diff --git a/packages/Webkul/API/Http/Controllers/Shop/CartController.php b/packages/Webkul/API/Http/Controllers/Shop/CartController.php index 1846c7a9e..b9cc0b78b 100644 --- a/packages/Webkul/API/Http/Controllers/Shop/CartController.php +++ b/packages/Webkul/API/Http/Controllers/Shop/CartController.php @@ -129,7 +129,7 @@ class CartController extends Controller Event::fire('checkout.cart.item.update.before', $itemId); - Cart::updateItem($item->product_id, ['quantity' => $qty], $itemId); + Cart::updateItem(['quantity' => $qty], $itemId); Event::fire('checkout.cart.item.update.after', $item); } diff --git a/packages/Webkul/Admin/src/Http/Controllers/ConfigurationController.php b/packages/Webkul/Admin/src/Http/Controllers/ConfigurationController.php index 67a867f45..aaaec0503 100755 --- a/packages/Webkul/Admin/src/Http/Controllers/ConfigurationController.php +++ b/packages/Webkul/Admin/src/Http/Controllers/ConfigurationController.php @@ -74,7 +74,7 @@ class ConfigurationController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { diff --git a/packages/Webkul/Admin/src/Http/Controllers/Customer/CustomerController.php b/packages/Webkul/Admin/src/Http/Controllers/Customer/CustomerController.php index e40fe6306..c8ac47077 100755 --- a/packages/Webkul/Admin/src/Http/Controllers/Customer/CustomerController.php +++ b/packages/Webkul/Admin/src/Http/Controllers/Customer/CustomerController.php @@ -71,7 +71,7 @@ class CustomerController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { @@ -81,7 +81,7 @@ class CustomerController extends Controller /** * Show the form for creating a new resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function create() { @@ -127,7 +127,7 @@ class CustomerController extends Controller * Show the form for editing the specified resource. * * @param int $id - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function edit($id) { @@ -190,7 +190,7 @@ class CustomerController extends Controller /** * To load the note taking screen for the customers * - * @return view + * @return \Illuminate\View\View */ public function createNote($id) { diff --git a/packages/Webkul/Admin/src/Http/Controllers/Customer/CustomerGroupController.php b/packages/Webkul/Admin/src/Http/Controllers/Customer/CustomerGroupController.php index 3effb922a..f4b4499bf 100755 --- a/packages/Webkul/Admin/src/Http/Controllers/Customer/CustomerGroupController.php +++ b/packages/Webkul/Admin/src/Http/Controllers/Customer/CustomerGroupController.php @@ -45,7 +45,7 @@ class CustomerGroupController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { @@ -55,7 +55,7 @@ class CustomerGroupController extends Controller /** * Show the form for creating a new resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function create() { @@ -89,7 +89,7 @@ class CustomerGroupController extends Controller * Show the form for editing the specified resource. * * @param int $id - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function edit($id) { diff --git a/packages/Webkul/Admin/src/Http/Controllers/DashboardController.php b/packages/Webkul/Admin/src/Http/Controllers/DashboardController.php index bbdccaf2a..13f2c19b2 100755 --- a/packages/Webkul/Admin/src/Http/Controllers/DashboardController.php +++ b/packages/Webkul/Admin/src/Http/Controllers/DashboardController.php @@ -125,7 +125,7 @@ class DashboardController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { diff --git a/packages/Webkul/Admin/src/Http/Controllers/Sales/InvoiceController.php b/packages/Webkul/Admin/src/Http/Controllers/Sales/InvoiceController.php index 9d44d9319..40ba5609e 100755 --- a/packages/Webkul/Admin/src/Http/Controllers/Sales/InvoiceController.php +++ b/packages/Webkul/Admin/src/Http/Controllers/Sales/InvoiceController.php @@ -61,7 +61,7 @@ class InvoiceController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { @@ -72,7 +72,7 @@ class InvoiceController extends Controller * Show the form for creating a new resource. * * @param int $orderId - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function create($orderId) { @@ -128,7 +128,7 @@ class InvoiceController extends Controller * Show the view for the specified resource. * * @param int $id - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function view($id) { diff --git a/packages/Webkul/Admin/src/Http/Controllers/Sales/OrderController.php b/packages/Webkul/Admin/src/Http/Controllers/Sales/OrderController.php index 1349214a1..19906800e 100755 --- a/packages/Webkul/Admin/src/Http/Controllers/Sales/OrderController.php +++ b/packages/Webkul/Admin/src/Http/Controllers/Sales/OrderController.php @@ -46,7 +46,7 @@ class OrderController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { @@ -57,7 +57,7 @@ class OrderController extends Controller * Show the view for the specified resource. * * @param int $id - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function view($id) { diff --git a/packages/Webkul/Admin/src/Http/Controllers/Sales/ShipmentController.php b/packages/Webkul/Admin/src/Http/Controllers/Sales/ShipmentController.php index ff446c10d..07460fbba 100755 --- a/packages/Webkul/Admin/src/Http/Controllers/Sales/ShipmentController.php +++ b/packages/Webkul/Admin/src/Http/Controllers/Sales/ShipmentController.php @@ -71,7 +71,7 @@ class ShipmentController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { @@ -82,7 +82,7 @@ class ShipmentController extends Controller * Show the form for creating a new resource. * * @param int $orderId - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function create($orderId) { @@ -177,7 +177,7 @@ class ShipmentController extends Controller * Show the view for the specified resource. * * @param int $id - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function view($id) { diff --git a/packages/Webkul/Admin/src/Http/routes.php b/packages/Webkul/Admin/src/Http/routes.php index 1c485c411..cd8a6e173 100755 --- a/packages/Webkul/Admin/src/Http/routes.php +++ b/packages/Webkul/Admin/src/Http/routes.php @@ -248,6 +248,9 @@ Route::group(['middleware' => ['web']], function () { 'view' => 'admin::catalog.products.edit' ])->name('admin.catalog.products.productlinksearch'); + //product search for linked products + Route::get('products/search/{id}', 'Webkul\Product\Http\Controllers\ProductController@searchProductForGroupedAssociation')->name('admin.catalog.products.search_product_for_grouped_association'); + Route::get('/products/{id}/{attribute_id}', 'Webkul\Product\Http\Controllers\ProductController@download')->defaults('_config', [ 'view' => 'admin.catalog.products.edit' ])->name('admin.catalog.products.file.download'); diff --git a/packages/Webkul/Admin/src/Resources/lang/ar/app.php b/packages/Webkul/Admin/src/Resources/lang/ar/app.php index e1339a81f..81d205bd1 100644 --- a/packages/Webkul/Admin/src/Resources/lang/ar/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/ar/app.php @@ -360,7 +360,33 @@ return [ 'add-image-btn-title' => 'إضافة صورة', 'mass-delete-success' => 'تم حذف كل الفهرس المنتقى من المنتجات بنجاح', 'mass-update-success' => 'كل الفهرس المختار من المنتجات تم تحديثه بنجاح', - 'configurable-error' => 'رجاء تحديد واحد مهيء الصفة.' + 'configurable-error' => 'رجاء تحديد واحد مهيء الصفة.', + 'categories' => 'Categories', + 'images' => 'Images', + 'inventories' => 'Inventories', + 'variations' => 'Variations', + 'downloadable' => 'Downloadable Information', + 'links' => 'Links', + 'add-link-btn-title' => 'Add Link', + 'samples' => 'Samples', + 'add-sample-btn-title' => 'Add Sample', + 'downloads' => 'Download Allowed', + 'file' => 'File', + 'sample' => 'Sample', + 'upload-file' => 'Upload File', + 'url' => 'Url', + 'sort-order' => 'Sort Order', + 'browse-file' => 'Browse File', + 'product-link' => 'Linked Products', + 'cross-selling' => 'Cross Selling', + 'up-selling' => 'Up Selling', + 'related-products' => 'Related Products', + 'product-search-hint' => 'Start typing product name', + 'no-result-found' => 'Products not found with same name.', + 'searching' => 'Searching ...', + 'grouped-products' => 'Grouped Products', + 'search-products' => 'Search Products', + 'no-result-found' => 'Products not found with same name.' ], 'attributes' => [ 'title' => 'الصفات', diff --git a/packages/Webkul/Admin/src/Resources/lang/en/app.php b/packages/Webkul/Admin/src/Resources/lang/en/app.php index da77f2f4c..a71856e46 100755 --- a/packages/Webkul/Admin/src/Resources/lang/en/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/en/app.php @@ -408,7 +408,10 @@ return [ 'related-products' => 'Related Products', 'product-search-hint' => 'Start typing product name', 'no-result-found' => 'Products not found with same name.', - 'searching' => 'Searching ...' + 'searching' => 'Searching ...', + 'grouped-products' => 'Grouped Products', + 'search-products' => 'Search Products', + 'no-result-found' => 'Products not found with same name.' ], 'attributes' => [ diff --git a/packages/Webkul/Admin/src/Resources/lang/pt_BR/app.php b/packages/Webkul/Admin/src/Resources/lang/pt_BR/app.php index d26d66dcb..d37a42fee 100755 --- a/packages/Webkul/Admin/src/Resources/lang/pt_BR/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/pt_BR/app.php @@ -362,7 +362,34 @@ return [ 'variant-already-exist-message' => 'Variante com as mesmas opções de atributo já existe.', 'add-image-btn-title' => 'Add Imagem', 'mass-delete-success' => 'Todos os índices de produtos selecionados foram excluídos com sucesso', - 'mass-update-success' => 'Todo o índice selecionado de produtos foi atualizado com sucesso' + 'mass-update-success' => 'Todo o índice selecionado de produtos foi atualizado com sucesso', + 'configurable-error' => 'Please select atleast one configurable attribute.', + 'categories' => 'Categories', + 'images' => 'Images', + 'inventories' => 'Inventories', + 'variations' => 'Variations', + 'downloadable' => 'Downloadable Information', + 'links' => 'Links', + 'add-link-btn-title' => 'Add Link', + 'samples' => 'Samples', + 'add-sample-btn-title' => 'Add Sample', + 'downloads' => 'Download Allowed', + 'file' => 'File', + 'sample' => 'Sample', + 'upload-file' => 'Upload File', + 'url' => 'Url', + 'sort-order' => 'Sort Order', + 'browse-file' => 'Browse File', + 'product-link' => 'Linked Products', + 'cross-selling' => 'Cross Selling', + 'up-selling' => 'Up Selling', + 'related-products' => 'Related Products', + 'product-search-hint' => 'Start typing product name', + 'no-result-found' => 'Products not found with same name.', + 'searching' => 'Searching ...', + 'grouped-products' => 'Grouped Products', + 'search-products' => 'Search Products', + 'no-result-found' => 'Products not found with same name.' ], 'attributes' => [ diff --git a/packages/Webkul/Admin/src/Resources/views/catalog/products/accordians/grouped-products.blade.php b/packages/Webkul/Admin/src/Resources/views/catalog/products/accordians/grouped-products.blade.php new file mode 100644 index 000000000..5cfd16743 --- /dev/null +++ b/packages/Webkul/Admin/src/Resources/views/catalog/products/accordians/grouped-products.blade.php @@ -0,0 +1,209 @@ +@section('css') + @parent + +@stop + +{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.grouped_products.before', ['product' => $product]) !!} + + +
+ + {!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.grouped_products.controls.before', ['product' => $product]) !!} + + + + {!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.grouped_products.controls.after', ['product' => $product]) !!} + +
+
+ +{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.grouped_products.after', ['product' => $product]) !!} + +@push('scripts') + @parent + + + + + + +@endpush \ No newline at end of file diff --git a/packages/Webkul/Admin/src/Resources/views/catalog/products/accordians/product-links.blade.php b/packages/Webkul/Admin/src/Resources/views/catalog/products/accordians/product-links.blade.php index 203b5d9ac..a3999ca9c 100755 --- a/packages/Webkul/Admin/src/Resources/views/catalog/products/accordians/product-links.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/catalog/products/accordians/product-links.blade.php @@ -34,7 +34,7 @@ @{{ product.name }} -
  • +
  • {{ __('admin::app.catalog.products.no-result-found') }}
  • diff --git a/packages/Webkul/Admin/src/Resources/views/sales/invoices/create.blade.php b/packages/Webkul/Admin/src/Resources/views/sales/invoices/create.blade.php index 33991e50f..7beb2aa7c 100755 --- a/packages/Webkul/Admin/src/Resources/views/sales/invoices/create.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/sales/invoices/create.blade.php @@ -224,14 +224,18 @@ @foreach ($order->items as $item) @if ($item->qty_to_invoice > 0) - {{ $item->type == 'configurable' ? $item->child->sku : $item->sku }} + {{ $item->getTypeInstance()->getOrderedItem($item)->sku }} {{ $item->name }} - @if ($html = $item->getOptionDetailHtml()) -

    {{ $html }}

    - @elseif ($item->type == 'downloadable') -

    Downloads : {{ $item->getDownloadableDetailHtml() }}

    + @if (isset($item->additional['attributes'])) +
    + + @foreach ($item->additional['attributes'] as $attribute) + {{ $attribute['attribute_name'] }} : {{ $attribute['option_label'] }} + @endforeach + +
    @endif {{ $item->qty_ordered }} diff --git a/packages/Webkul/Admin/src/Resources/views/sales/invoices/pdf.blade.php b/packages/Webkul/Admin/src/Resources/views/sales/invoices/pdf.blade.php index 3aaa31053..e6de4ae6b 100755 --- a/packages/Webkul/Admin/src/Resources/views/sales/invoices/pdf.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/sales/invoices/pdf.blade.php @@ -174,14 +174,18 @@ @foreach ($invoice->items as $item) - {{ $item->child ? $item->child->sku : $item->sku }} + {{ $item->getTypeInstance()->getOrderedItem($item)->sku }} {{ $item->name }} - @if ($html = $item->getOptionDetailHtml()) -

    {{ $html }}

    - @elseif ($item->type == 'downloadable') -

    Downloads : {{ $item->getDownloadableDetailHtml() }}

    + @if (isset($item->additional['attributes'])) +
    + + @foreach ($item->additional['attributes'] as $attribute) + {{ $attribute['attribute_name'] }} : {{ $attribute['option_label'] }} + @endforeach + +
    @endif {{ core()->formatBasePrice($item->base_price) }} diff --git a/packages/Webkul/Admin/src/Resources/views/sales/invoices/view.blade.php b/packages/Webkul/Admin/src/Resources/views/sales/invoices/view.blade.php index 28f404380..5986d3f8b 100755 --- a/packages/Webkul/Admin/src/Resources/views/sales/invoices/view.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/sales/invoices/view.blade.php @@ -229,15 +229,19 @@ @foreach ($invoice->items as $item) - {{ $item->child ? $item->child->sku : $item->sku }} + {{ $item->getTypeInstance()->getOrderedItem($item)->sku }} {{ $item->name }} - - @if ($html = $item->getOptionDetailHtml()) -

    {{ $html }}

    - @elseif ($item->type == 'downloadable') -

    Downloads : {{ $item->getDownloadableDetailHtml() }}

    + + @if (isset($item->additional['attributes'])) +
    + + @foreach ($item->additional['attributes'] as $attribute) + {{ $attribute['attribute_name'] }} : {{ $attribute['option_label'] }} + @endforeach + +
    @endif diff --git a/packages/Webkul/Admin/src/Resources/views/sales/orders/view.blade.php b/packages/Webkul/Admin/src/Resources/views/sales/orders/view.blade.php index 3a4474217..c0a11734e 100755 --- a/packages/Webkul/Admin/src/Resources/views/sales/orders/view.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/sales/orders/view.blade.php @@ -250,16 +250,20 @@ @foreach ($order->items as $item) - {{ $item->type == 'configurable' ? $item->child->sku : $item->sku }} + {{ $item->getTypeInstance()->getOrderedItem($item)->sku }} {{ $item->name }} - @if ($html = $item->getOptionDetailHtml()) -

    {{ $html }}

    - @elseif ($item->type == 'downloadable') -

    Downloads : {{ $item->getDownloadableDetailHtml() }}

    + @if (isset($item->additional['attributes'])) +
    + + @foreach ($item->additional['attributes'] as $attribute) + {{ $attribute['attribute_name'] }} : {{ $attribute['option_label'] }} + @endforeach + +
    @endif diff --git a/packages/Webkul/Admin/src/Resources/views/sales/shipments/create.blade.php b/packages/Webkul/Admin/src/Resources/views/sales/shipments/create.blade.php index 3810c99d1..f53ff4751 100755 --- a/packages/Webkul/Admin/src/Resources/views/sales/shipments/create.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/sales/shipments/create.blade.php @@ -273,14 +273,18 @@ @foreach ($order->items as $item) @if ($item->qty_to_ship > 0 && $item->product) - {{ $item->type == 'configurable' ? $item->child->sku : $item->sku }} + {{ $item->getTypeInstance()->getOrderedItem($item)->sku }} {{ $item->name }} - - @if ($html = $item->getOptionDetailHtml()) -

    {{ $html }}

    - @elseif ($item->type == 'downloadable') -

    Downloads : {{ $item->getDownloadableDetailHtml() }}

    + + @if (isset($item->additional['attributes'])) +
    + + @foreach ($item->additional['attributes'] as $attribute) + {{ $attribute['attribute_name'] }} : {{ $attribute['option_label'] }} + @endforeach + +
    @endif {{ $item->qty_ordered }} @@ -304,18 +308,11 @@ - type == 'configurable') { - $sourceQty = $item->child->product->inventory_source_qty($inventorySource); - } else { - $sourceQty = $item->product->inventory_source_qty($inventorySource); - } - ?> getTypeInstance()->getOrderedItem($item)->product; - $product = $item->type == 'configurable' ? $item->child->product : $item->product; + $sourceQty = $product->inventory_source_qty($inventorySource); foreach ($product->inventories as $inventory) { if ($inventory->inventory_source_id == $inventorySource->id) { diff --git a/packages/Webkul/Admin/src/Resources/views/sales/shipments/view.blade.php b/packages/Webkul/Admin/src/Resources/views/sales/shipments/view.blade.php index 92e974077..97c330575 100755 --- a/packages/Webkul/Admin/src/Resources/views/sales/shipments/view.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/sales/shipments/view.blade.php @@ -251,11 +251,15 @@ {{ $item->sku }} {{ $item->name }} - - @if ($html = $item->getOptionDetailHtml()) -

    {{ $html }}

    - @elseif ($item->type == 'downloadable') -

    Downloads : {{ $item->getDownloadableDetailHtml() }}

    + + @if (isset($item->additional['attributes'])) +
    + + @foreach ($item->additional['attributes'] as $attribute) + {{ $attribute['attribute_name'] }} : {{ $attribute['option_label'] }} + @endforeach + +
    @endif {{ $item->qty }} diff --git a/packages/Webkul/Attribute/src/Http/Controllers/AttributeController.php b/packages/Webkul/Attribute/src/Http/Controllers/AttributeController.php index a678aa026..d9958c78c 100755 --- a/packages/Webkul/Attribute/src/Http/Controllers/AttributeController.php +++ b/packages/Webkul/Attribute/src/Http/Controllers/AttributeController.php @@ -43,7 +43,7 @@ class AttributeController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { @@ -53,7 +53,7 @@ class AttributeController extends Controller /** * Show the form for creating a new resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function create() { @@ -88,7 +88,7 @@ class AttributeController extends Controller * Show the form for editing the specified resource. * * @param int $id - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function edit($id) { diff --git a/packages/Webkul/Attribute/src/Http/Controllers/AttributeFamilyController.php b/packages/Webkul/Attribute/src/Http/Controllers/AttributeFamilyController.php index 41de6b490..272f0848c 100755 --- a/packages/Webkul/Attribute/src/Http/Controllers/AttributeFamilyController.php +++ b/packages/Webkul/Attribute/src/Http/Controllers/AttributeFamilyController.php @@ -56,7 +56,7 @@ class AttributeFamilyController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { @@ -66,7 +66,7 @@ class AttributeFamilyController extends Controller /** * Show the form for creating a new resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function create() { @@ -100,7 +100,7 @@ class AttributeFamilyController extends Controller * Show the form for editing the specified resource. * * @param int $id - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function edit($id) { diff --git a/packages/Webkul/Category/src/Http/Controllers/CategoryController.php b/packages/Webkul/Category/src/Http/Controllers/CategoryController.php index 3402a6d7d..b1cac74b5 100755 --- a/packages/Webkul/Category/src/Http/Controllers/CategoryController.php +++ b/packages/Webkul/Category/src/Http/Controllers/CategoryController.php @@ -44,7 +44,7 @@ class CategoryController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { @@ -54,7 +54,7 @@ class CategoryController extends Controller /** * Show the form for creating a new resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function create() { @@ -100,7 +100,7 @@ class CategoryController extends Controller * Show the form for editing the specified resource. * * @param int $id - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function edit($id) { diff --git a/packages/Webkul/Checkout/src/Cart.php b/packages/Webkul/Checkout/src/Cart.php index 305c4a91f..0179e2504 100755 --- a/packages/Webkul/Checkout/src/Cart.php +++ b/packages/Webkul/Checkout/src/Cart.php @@ -12,6 +12,7 @@ use Webkul\Checkout\Models\CartPayment; use Webkul\Customer\Repositories\WishlistRepository; use Webkul\Customer\Repositories\CustomerAddressRepository; use Webkul\Product\Helpers\Price; +use Illuminate\Support\Facades\Event; /** * Facades handler for all the methods to be implemented in Cart. @@ -121,7 +122,7 @@ class Cart { /** * Return current logged in customer * - * @return Customer | Boolean + * @return Customer|boolean */ public function getCurrentCustomer() { @@ -130,15 +131,62 @@ class Cart { return auth()->guard($guard); } + /** + * Add Items in a cart with some cart and item details. + * + * @param integer $productId + * @param array $data + * @return Cart + */ + public function addProduct($productId, $data) + { + Event::fire('checkout.cart.add.before', $productId); + + $cart = $this->getCart(); + + if (! $cart && ! $cart = $this->create($data)) + return; + + $product = $this->productRepository->findOneByField('id', $productId); + + $cartProducts = $product->getTypeInstance()->prepareForCart($data); + + if (is_string($cartProducts)) { + throw new \Exception($cartProducts); + } else { + $parentCartItem = null; + + foreach ($cartProducts as $cartProduct) { + $cartItem = $this->getItemByProduct($cartProduct); + + if (isset($cartProduct['parent_id'])) + $cartProduct['parent_id'] = $parentCartItem->id; + + if (! $cartItem) { + $cartItem = $this->cartItemRepository->create(array_merge($cartProduct, ['cart_id' => $cart->id])); + } else { + $cartItem = $this->cartItemRepository->update($cartProduct, $cartItem->id); + } + + if (! $parentCartItem) + $parentCartItem = $cartItem; + } + } + + Event::fire('checkout.cart.add.after', $cart); + + $this->collectTotals(); + + return $cart; + } + /** * Create new cart instance. * - * @param integer $id - * @param array $data - * - * @return Boolean + * @param array $data + * @return Cart|null */ - public function create($id, $data, $qty = 1) + public function create($data) { $cartData = [ 'channel_id' => core()->getCurrentChannel()->id, @@ -160,392 +208,192 @@ class Cart { $cartData['is_guest'] = 1; } - $result = $this->cartRepository->create($cartData); + $cart = $this->cartRepository->create($cartData); - $this->putCart($result); - - if ($result) { - if ($item = $this->createItem($id, $data)) - return $item; - else - return false; - } else { + if (! $cart) { session()->flash('error', trans('shop::app.checkout.cart.create-error')); + + return; } + + $this->putCart($cart); + + return $cart; } /** - * Add Items in a cart with some cart and item details. + * Update cart items information * - * @param integer $id - * @param array $data + * @param array $data * - * @return void + * @return string|boolean */ - public function add($id, $data) + public function updateItems($data) { - $cart = $this->getCart(); + foreach ($data['qty'] as $itemId => $quantity) { + $item = $this->cartItemRepository->findOneByField('id', $itemId); + + if (! $item) + continue; - if ($cart != null) { - $ifExists = $this->checkIfItemExists($id, $data); + if ($quantity <= 0) { + $this->removeItem($itemId); - if ($ifExists) { - $item = $this->cartItemRepository->findOneByField('id', $ifExists); - - $data['quantity'] = $data['quantity'] + $item->quantity; - - $result = $this->updateItem($id, $data, $ifExists); - } else { - $result = $this->createItem($id, $data); + throw new \Exception(trans('shop::app.checkout.cart.quantity.illegal')); } - return $result; - } else { - return $this->create($id, $data); + if ($item->product->isStockable() && ! $item->product->haveSufficientQuantity($quantity)) + throw new \Exception(trans('shop::app.checkout.cart.quantity.inventory_warning')); + + Event::fire('checkout.cart.update.before', $item); + + $this->cartItemRepository->update([ + 'quantity' => $quantity, + 'total' => core()->convertPrice($item->price * $quantity), + 'base_total' => $item->price * $quantity, + 'total_weight' => $item->weight * $quantity, + 'base_total_weight' => $item->weight * $quantity + ], $itemId); + + Event::fire('checkout.cart.update.after', $item); } - } - - /** - * To check if the items exists in the cart or not - * - * @return boolean - */ - public function checkIfItemExists($id, $data) - { - $items = $this->getCart()->items; - - foreach ($items as $item) { - if ($id == $item->product_id) { - $product = $this->productRepository->findOnebyField('id', $id); - - if ($product->type == 'configurable') { - $variant = $this->productRepository->findOneByField('id', $data['selected_configurable_option']); - - if ($item->child->product_id == $data['selected_configurable_option']) - return $item->id; - } else if ($product->type == 'downloadable') { - // if ($data['links'] == $item->additional['links']) - return $item->id; - } else { - return $item->id; - } - } - } - - return 0; - } - - /** - * Create the item based on the type of product whether simple or configurable - * - * @return Mixed Array $item || Error - */ - public function createItem($id, $data) - { - $childProduct = $configurable = false; - - $product = $this->productRepository->findOneByField('id', $id); - - if ($product->type == 'configurable') { - if (! isset($data['selected_configurable_option']) || ! $data['selected_configurable_option']) { - return false; - } - - $childProduct = $this->productRepository->findOneByField('id', $data['selected_configurable_option']); - - if (! $childProduct->haveSufficientQuantity($data['quantity'])) { - session()->flash('warning', trans('shop::app.checkout.cart.quantity.inventory_warning')); - - return false; - } - } else { - if ($product->isStockable() && ! $product->haveSufficientQuantity($data['quantity'])) { - session()->flash('warning', trans('shop::app.checkout.cart.quantity.inventory_warning')); - - return false; - } - } - - //Check if the product's information is proper or not - if (! isset($data['product']) || ! isset($data['quantity'])) { - session()->flash('error', trans('shop::app.checkout.cart.integrity.missing_fields')); - - return false; - } else { - if ($product->type == 'configurable' && ! isset($data['super_attribute'])) { - session()->flash('error', trans('shop::app.checkout.cart.integrity.missing_options')); - - return false; - } else if ($product->type == 'downloadable' && (! isset($data['links']) || ! count($data['links']))) { - throw new \Exception('shop::app.checkout.cart.integrity.missing_links'); - } - } - - $child = $childData = null; - $additional = []; - - $price = $this->price->getMinimalPrice($product->type == 'configurable' ? $childProduct : $product); - - if ($product->type == 'configurable') { - $weight = $childProduct->weight; - } else { - $weight = $product->isStockable() ? $product->weight : 0; - } - - $parentData = [ - 'sku' => $product->sku, - 'quantity' => $data['quantity'], - 'cart_id' => $this->getCart()->id, - 'name' => $product->name, - 'price' => core()->convertPrice($price), - 'base_price' => $price, - 'total' => core()->convertPrice($price * $data['quantity']), - 'base_total' => $price * $data['quantity'], - 'weight' => $weight, - 'total_weight' => $weight * $data['quantity'], - 'base_total_weight' => $weight * $data['quantity'], - 'additional' => $additional, - 'type' => $product->type, - 'product_id' => $product->id, - 'additional' => $data, - ]; - - if ($product->type == 'configurable') { - $attributeDetails = $this->getProductAttributeOptionDetails($childProduct); - unset($attributeDetails['html']); - - $parentData['additional'] = array_merge($parentData['additional'], $attributeDetails); - - $childData = [ - 'product_id' => (int) $data['selected_configurable_option'], - 'sku' => $childProduct->sku, - 'name' => $childProduct->name, - 'type' => 'simple', - 'cart_id' => $this->getCart()->id - ]; - } else if ($product->type == 'downloadable') { - $parentData['additional'] = array_merge($parentData['additional'], ['link_lables' => $this->getDownloadableDetails($product)]); - } - - $item = $this->cartItemRepository->create($parentData); - - if (is_array($childData)) { - $childData['parent_id'] = $item->id; - - $this->cartItemRepository->create($childData); - } - - return $item; - } - - /** - * Update the cartItem on cart checkout page and if already added item is added again - * - * @param $id product_id of cartItem instance - * @param $data new requested quantities by customer - * @param $itemId is id from cartItem instance - * @return boolean - */ - public function updateItem($id, $data, $itemId) - { - $item = $this->cartItemRepository->findOneByField('id', $itemId); - - $additional = isset($data['product']) ? $data : $item->additional; - - if ($item->type == 'configurable') { - $product = $this->productRepository->findOneByField('id', $item->child->product_id); - - if (! $product->haveSufficientQuantity($data['quantity'])) { - session()->flash('warning', trans('shop::app.checkout.cart.quantity.inventory_warning')); - - return false; - } - - $attributeDetails = $this->getProductAttributeOptionDetails($product); - unset($attributeDetails['html']); - - $additional = array_merge($additional, $attributeDetails); - } else if ($item->type == 'downloadable') { - $additional = array_merge($additional, ['link_lables' => $this->getDownloadableDetails($item)]); - } else { - $product = $this->productRepository->findOneByField('id', $item->product_id); - - if ($product->isStockable() && ! $product->haveSufficientQuantity($data['quantity'])) { - session()->flash('warning', trans('shop::app.checkout.cart.quantity.inventory_warning')); - - return false; - } - } - - $quantity = $data['quantity']; - - $result = $item->update([ - 'quantity' => $quantity, - 'total' => core()->convertPrice($item->price * ($quantity)), - 'base_total' => $item->price * ($quantity), - 'total_weight' => $item->weight * ($quantity), - 'base_total_weight' => $item->weight * ($quantity), - 'additional' => $additional - ]); $this->collectTotals(); - if ($result) { - session()->flash('success', trans('shop::app.checkout.cart.quantity.success')); + return true; + } - return $item; - } else { - session()->flash('warning', trans('shop::app.checkout.cart.quantity.error')); + /** + * Get cart item by product + * + * @param array $data + * @return CartItem|void + */ + public function getItemByProduct($data) + { + $items = $this->getCart()->all_items; - return false; + foreach ($items as $item) { + if ($item->product->getTypeInstance()->compareOptions($item->additional, $data['additional'])) + return $item; } } /** * Remove the item from the cart * - * @return response + * @param integer $itemId + * @return boolean */ public function removeItem($itemId) { - if ($cart = $this->getCart()) { - $this->cartItemRepository->delete($itemId); + Event::fire('checkout.cart.delete.before', $itemId); - //delete the cart instance if no items are there - if ($cart->items()->get()->count() == 0) { - $this->cartRepository->delete($cart->id); + if (! $cart = $this->getCart()) + return false; - // $this->deActivateCart(); - if (session()->has('cart')) { - session()->forget('cart'); - } + $this->cartItemRepository->delete($itemId); + + //delete the cart instance if no items are there + if ($cart->items()->get()->count() == 0) { + $this->cartRepository->delete($cart->id); + + if (session()->has('cart')) { + session()->forget('cart'); } - - session()->flash('success', trans('shop::app.checkout.cart.item.success-remove')); - - return true; } - return false; + Event::fire('checkout.cart.delete.after', $itemId); + + $this->collectTotals(); + + return true; } /** * This function handles when guest has some of cart products and then logs in. * - * @return Response + * @return boolean */ public function mergeCart() { if (session()->has('cart')) { - $cart = $this->cartRepository->findWhere(['customer_id' => $this->getCurrentCustomer()->user()->id, 'is_active' => 1]); - - $cart = $cart->count() ? $cart->first() : false; + $cart = $this->cartRepository->findOneWhere(['customer_id' => $this->getCurrentCustomer()->user()->id, 'is_active' => 1]); $guestCart = session()->get('cart'); //when the logged in customer is not having any of the cart instance previously and are active. if (! $cart) { - $guestCart->update([ + $this->cartRepository->update([ 'customer_id' => $this->getCurrentCustomer()->user()->id, 'is_guest' => 0, 'customer_first_name' => $this->getCurrentCustomer()->user()->first_name, 'customer_last_name' => $this->getCurrentCustomer()->user()->last_name, 'customer_email' => $this->getCurrentCustomer()->user()->email - ]); + ], $guestCart->id); session()->forget('cart'); return true; } - $cartItems = $cart->items; + foreach ($guestCart->items as $key => $guestCartItem) { + $found = false; + foreach ($cart->items as $cartItem) { + if (! $cartItem->product->getTypeInstance()->compareOptions($cartItem->additional, $guestCartItem->additional)) + continue; - $guestCartId = $guestCart->id; - - $guestCartItems = $this->cartRepository->findOneByField('id', $guestCartId)->items; - - foreach ($guestCartItems as $key => $guestCartItem) { - foreach ($cartItems as $cartItem) { - - if ($guestCartItem->type == "configurable" && $cartItem->type == "configurable") { - $guestCartItemChild = $guestCartItem->child; - - $cartItemChild = $cartItem->child; - - if ($guestCartItemChild->product_id != $cartItemChild->product_id) - continue; - - $prevQty = $guestCartItem->quantity; - $newQty = $cartItem->quantity; - - $product = $this->productRepository->findOneByField('id', $cartItem->child->product_id); - - if ($product->isStockable() && ! $product->haveSufficientQuantity($prevQty + $newQty)) { - $this->cartItemRepository->delete($guestCartItem->id); - continue; - } - - $data['quantity'] = $newQty + $prevQty; - - $this->updateItem($cartItem->product_id, $data, $cartItem->id); - - $guestCartItems->forget($key); + $newQuantity = $cartItem->quantity + $guestCartItem->quantity; + if ($cartItem->product->isStockable() && ! $cartItem->product->haveSufficientQuantity($newQuantity)) { $this->cartItemRepository->delete($guestCartItem->id); - } else { - if ($cartItem->product_id == $guestCartItem->product_id) - continue; - $prevQty = $cartItem->quantity; - $newQty = $guestCartItem->quantity; + continue; + } - $product = $this->productRepository->findOneByField('id', $cartItem->product_id); + $this->cartItemRepository->update([ + 'quantity' => $newQuantity, + 'total' => core()->convertPrice($cartItem->price * $newQuantity), + 'base_total' => $cartItem->price * $newQuantity, + 'total_weight' => $cartItem->weight * $newQuantity, + 'base_total_weight' => $cartItem->weight * $newQuantity + ], $cartItem->id); - if ($product->isStockable() && ! $product->haveSufficientQuantity($prevQty + $newQty)) { - $this->cartItemRepository->delete($guestCartItem->id); + $guestCart->items->forget($key); - continue; - } + $this->cartItemRepository->delete($guestCartItem->id); - $data['quantity'] = $newQty + $prevQty; + $found = true; + } - $this->updateItem($cartItem->product_id, $data, $cartItem->id); + if (! $found) { + $this->cartItemRepository->update([ + 'cart_id' => $cart->id + ], $guestCartItem->id); - $guestCartItems->forget($key); - $this->cartItemRepository->delete($guestCartItem->id); + foreach ($guestCartItem->children as $child) { + $this->cartItemRepository->update([ + 'cart_id' => $cart->id + ], $child->id); } } } - //now handle the products that are not removed from the list of items in the guest cart. - foreach ($guestCartItems as $guestCartItem) { - if ($guestCartItem->type == "configurable") { - $guestCartItem->update(['cart_id' => $cart->id]); - - $guestCartItem->child->update(['cart_id' => $cart->id]); - } else{ - $guestCartItem->update(['cart_id' => $cart->id]); - } - } - - //delete the guest cart instance. - $this->cartRepository->delete($guestCartId); - - //forget the guest cart instance - session()->forget('cart'); - $this->collectTotals(); - return true; - } else { - return true; + $this->cartRepository->delete($guestCart->id); + + session()->forget('cart'); } + + return true; } /** * Save cart * - * @return mixed + * @param Cart $cart + * @return void */ public function putCart($cart) { @@ -557,7 +405,7 @@ class Cart { /** * Returns cart * - * @return mixed + * @return Cart|null */ public function getCart() { @@ -602,63 +450,11 @@ class Cart { return $data; } - /** - * Returns the items details of the configurable and simple products - * - * @return Mixed - */ - public function getProductAttributeOptionDetails($product) - { - $data = []; - - $labels = []; - - foreach ($product->parent->super_attributes as $attribute) { - $option = $attribute->options()->where('id', $product->{$attribute->code})->first(); - - $data['attributes'][$attribute->code] = [ - 'attribute_name' => $attribute->name ? $attribute->name : $attribute->admin_name, - 'option_id' => $option->id, - 'option_label' => $option->label, - ]; - - $labels[] = ($attribute->name ? $attribute->name : $attribute->admin_name) . ' : ' . $option->label; - } - - $data['html'] = implode(', ', $labels); - - return $data; - } - - /** - * Returns the items details of the downloadable names - * - * @return Mixed - */ - public function getDownloadableDetails($item) - { - $labels = []; - - if ($item instanceOf CartItem) { - $links = $item->additional['links']; - - $item = $item->product; - } else { - $links = request('links'); - } - - foreach ($item->downloadable_links as $link) { - if (in_array($link->id, $links)) - $labels[] = $link->title; - } - - return implode(', ', $labels); - } - /** * Save customer address * - * @return Mixed + * @param array $data + * @return boolean */ public function saveCustomerAddress($data) { @@ -761,7 +557,7 @@ class Cart { * Save shipping method for cart * * @param string $shippingMethodCode - * @return Mixed + * @return boolean */ public function saveShippingMethod($shippingMethodCode) { @@ -778,7 +574,7 @@ class Cart { * Save payment method for cart * * @param string $payment - * @return Mixed + * @return CartPayment */ public function savePaymentMethod($payment) { @@ -806,9 +602,8 @@ class Cart { { $validated = $this->validateItems(); - if (! $validated) { + if (! $validated) return false; - } if (! $cart = $this->getCart()) return false; @@ -859,70 +654,27 @@ class Cart { */ public function validateItems() { - $cart = $this->getCart(); - - if (! $cart) - return false; + if (! $cart = $this->getCart()) + return; //rare case of accident-->used when there are no items. if (count($cart->items) == 0) { $this->cartRepository->delete($cart->id); - + return false; } else { - $items = $cart->items; + foreach ($cart->items as $item) { + if ($item->product_flat->getTypeInstance()->getMinimalPrice($item) == $item->price) + continue; - foreach ($items as $item) { - $productFlat = $item->product_flat; + $price = ! is_null($item->custom_price) ? $item->custom_price : $this->price->getMinimalPrice($productFlat); - if ($productFlat->type == 'configurable') { - if ($productFlat->sku != $item->sku) { - $item->update(['sku' => $productFlat->sku]); - - } else if ($productFlat->name != $item->name) { - $item->update(['name' => $productFlat->name]); - - } else if ($this->price->getMinimalPrice($item->child->product_flat) != $item->price) { - // $price = (float) $item->custom_price ? $item->custom_price : $item->child->product->price; - - if (! is_null($item->custom_price)) { - $price = $item->custom_price; - } else { - $price = $this->price->getMinimalPrice($item->child->product_flat); - } - - $item->update([ - 'price' => core()->convertPrice($price), - 'base_price' => $price, - 'total' => core()->convertPrice($price * ($item->quantity)), - 'base_total' => $price * ($item->quantity), - ]); - } - - } else { - if ($productFlat->sku != $item->sku) { - $item->update(['sku' => $productFlat->sku]); - - } else if ($productFlat->name != $item->name) { - $item->update(['name' => $productFlat->name]); - - } else if ($this->price->getMinimalPrice($productFlat) != $item->price) { - // $price = (float) $item->custom_price ? $item->custom_price : $item->product->price; - - if (! is_null($item->custom_price)) { - $price = $item->custom_price; - } else { - $price = $this->price->getMinimalPrice($productFlat); - } - - $item->update([ - 'price' => core()->convertPrice($price), - 'base_price' => $price, - 'total' => core()->convertPrice($price * ($item->quantity)), - 'base_total' => $price * ($item->quantity), - ]); - } - } + $this->cartItemRepository->update([ + 'price' => core()->convertPrice($price), + 'base_price' => $price, + 'total' => core()->convertPrice($price * ($item->quantity)), + 'base_total' => $price * ($item->quantity), + ], $item->id); } return true; @@ -1012,16 +764,12 @@ class Cart { /** * Checks if all cart items have sufficient quantity. * + * @param CartItem $item * @return boolean */ public function isItemHaveQuantity($item) { - $product = $item->type == 'configurable' ? $item->child->product : $item->product; - - if ($product->isStockable() && ! $product->haveSufficientQuantity($item->quantity)) - return false; - - return true; + return $item->product->getTypeInstance()->isItemHaveQuantity($item); } /** @@ -1096,6 +844,7 @@ class Cart { /** * Prepares data for order item * + * @param array $data * @return array */ public function prepareDataForOrderItem($data) @@ -1129,117 +878,70 @@ class Cart { } /** - * Move to Cart - * * Move a wishlist item to cart + * + * @param WishlistItem $wishlistItem + * @return boolean */ public function moveToCart($wishlistItem) { - $product = $wishlistItem->product; - - if ($product->getTypeInstance()->canBeMovedFromWishlistToCart()) { - \Event::fire('checkout.cart.add.before', $product->id); - - $result = $this->add($product->id, ['quantity' => 1, 'product' => $product->id]); - - if ($result) { - \Event::fire('checkout.cart.add.after', $result); - - return true; - } else { - return false; - } - } else { + if (! $wishlistItem->product->getTypeInstance()->canBeMovedFromWishlistToCart($wishlistItem)) return false; + + $result = $this->addProduct($wishlistItem->product_id, $wishlistItem->additional); + + if ($result) { + $this->wishlistRepository->delete($wishlistItem->id); + + return true; } + + return false; } /** * Function to move a already added product to wishlist will run only on customer authentication. * - * @param instance cartItem $id + * @param integer $itemId + * @return boolean|void */ public function moveToWishlist($itemId) { $cart = $this->getCart(); - $wishlist = [ - 'channel_id' => $cart->channel_id, - 'customer_id' => $this->getCurrentCustomer()->user()->id, - ]; - - foreach ($cart->items as $item) { - if ($item->id == $itemId) { - if ($item->type == 'configurable') { - $wishlist['product_id'] = $item->child->product_id; - $wishtlist['options'] = $item->additional; - } else { - $wishlist['product_id'] = $item->product_id; - } - - $shouldBe = $this->wishlistRepository->findWhere([ - 'customer_id' => $this->getCurrentCustomer()->user()->id, - 'product_id' => $wishlist['product_id'] - ]); - - if ($shouldBe->isEmpty()) { - $wishlist = $this->wishlistRepository->create($wishlist); - } - - $result = $this->cartItemRepository->delete($itemId); - - if ($result) { - if ($cart->items()->count() == 0) - $this->cartRepository->delete($cart->id); - - session()->flash('success', trans('shop::app.checkout.cart.move-to-wishlist-success')); - - return $result; - } else { - session()->flash('success', trans('shop::app.checkout.cart.move-to-wishlist-error')); - - return $result; - } - } - } - } - - /** - * Handle the buy now process for simple as well as configurable products - * - * @return response mixed - */ - public function proceedToBuyNow($id, $quantity) - { - $product = $this->productRepository->findOneByField('id', $id); - - if ($product->type == 'configurable') { - session()->flash('warning', trans('shop::app.buynow.no-options')); + $cartItem = $cart->items()->find($itemId); + if (! $cartItem) return false; - } else { - $simpleOrVariant = $this->productRepository->find($id); - if ($simpleOrVariant->parent_id != null) { - $parent = $simpleOrVariant->parent; + $wishlistItems = $this->wishlistRepository->findWhere([ + 'customer_id' => $this->getCurrentCustomer()->user()->id, + 'product_id' => $cartItem->product_id + ]); - $data['product'] = $parent->id; - $data['selected_configurable_option'] = $simpleOrVariant->id; - $data['quantity'] = $quantity; - $data['super_attribute'] = 'From Buy Now'; + $found = false; - $result = $this->add($parent->id, $data); - - return $result; - } else { - $data['product'] = $id; - $data['is_configurable'] = false; - $data['quantity'] = $quantity; - - $result = $this->add($id, $data); - - return $result; - } + foreach ($wishlistItems as $wishlistItem) { + if ($cartItem->product->getTypeInstance()->compareOptions($cartItem->additional, $wishlistItem->item_options)) + $found = true; } + + if (! $found) { + $this->wishlistRepository->create([ + 'channel_id' => $cart->channel_id, + 'customer_id' => $this->getCurrentCustomer()->user()->id, + 'product_id' => $cartItem->product_id, + 'additional' => $cartItem->additional + ]); + } + + $result = $this->cartItemRepository->delete($itemId); + + if (! $cart->items()->count()) + $this->cartRepository->delete($cart->id); + + $this->collectTotals(); + + return true; } } \ No newline at end of file diff --git a/packages/Webkul/Checkout/src/Models/CartItem.php b/packages/Webkul/Checkout/src/Models/CartItem.php index 3a53425cb..8e7cb1913 100755 --- a/packages/Webkul/Checkout/src/Models/CartItem.php +++ b/packages/Webkul/Checkout/src/Models/CartItem.php @@ -55,4 +55,12 @@ class CartItem extends Model implements CartItemContract { return $this->belongsTo(self::class, 'id', 'parent_id'); } + + /** + * Get the children items. + */ + public function children() + { + return $this->hasMany(self::class, 'parent_id'); + } } diff --git a/packages/Webkul/Checkout/src/Repositories/CartItemRepository.php b/packages/Webkul/Checkout/src/Repositories/CartItemRepository.php index 223f69776..2c33af0b9 100755 --- a/packages/Webkul/Checkout/src/Repositories/CartItemRepository.php +++ b/packages/Webkul/Checkout/src/Repositories/CartItemRepository.php @@ -33,14 +33,15 @@ class CartItemRepository extends Repository public function update(array $data, $id, $attribute = "id") { - $cartitems = $this->find($id); + $item = $this->find($id); - $cartitems->update($data); + $item->update($data); - return $cartitems; + return $item; } - public function getProduct($cartItemId) { + public function getProduct($cartItemId) + { return $this->model->find($cartItemId)->product->id; } } \ No newline at end of file diff --git a/packages/Webkul/Core/src/Http/Controllers/ChannelController.php b/packages/Webkul/Core/src/Http/Controllers/ChannelController.php index 12c639c08..45d318ea2 100755 --- a/packages/Webkul/Core/src/Http/Controllers/ChannelController.php +++ b/packages/Webkul/Core/src/Http/Controllers/ChannelController.php @@ -43,7 +43,7 @@ class ChannelController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { @@ -53,7 +53,7 @@ class ChannelController extends Controller /** * Show the form for creating a new resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function create() { @@ -94,7 +94,7 @@ class ChannelController extends Controller * Show the form for editing the specified resource. * * @param int $id - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function edit($id) { diff --git a/packages/Webkul/Core/src/Http/Controllers/CountryStateController.php b/packages/Webkul/Core/src/Http/Controllers/CountryStateController.php index 9df091d63..e0abb4e0f 100755 --- a/packages/Webkul/Core/src/Http/Controllers/CountryStateController.php +++ b/packages/Webkul/Core/src/Http/Controllers/CountryStateController.php @@ -56,7 +56,7 @@ class CountryStateController extends Controller /** * Function to retrieve states with respect to countries with codes and names for both of the countries and states. * - * @return array + * @return \Illuminate\View\View */ public function getCountries() { diff --git a/packages/Webkul/Core/src/Http/Controllers/CurrencyController.php b/packages/Webkul/Core/src/Http/Controllers/CurrencyController.php index 8df8c2962..4416eda0b 100755 --- a/packages/Webkul/Core/src/Http/Controllers/CurrencyController.php +++ b/packages/Webkul/Core/src/Http/Controllers/CurrencyController.php @@ -43,7 +43,7 @@ class CurrencyController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { @@ -53,7 +53,7 @@ class CurrencyController extends Controller /** * Show the form for creating a new resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function create() { @@ -87,7 +87,7 @@ class CurrencyController extends Controller * Show the form for editing the specified resource. * * @param int $id - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function edit($id) { diff --git a/packages/Webkul/Core/src/Http/Controllers/ExchangeRateController.php b/packages/Webkul/Core/src/Http/Controllers/ExchangeRateController.php index 98b3968ec..cb76fd96e 100755 --- a/packages/Webkul/Core/src/Http/Controllers/ExchangeRateController.php +++ b/packages/Webkul/Core/src/Http/Controllers/ExchangeRateController.php @@ -57,7 +57,7 @@ class ExchangeRateController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { @@ -67,7 +67,7 @@ class ExchangeRateController extends Controller /** * Show the form for creating a new resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function create() { @@ -103,7 +103,7 @@ class ExchangeRateController extends Controller * Show the form for editing the specified resource. * * @param int $id - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function edit($id) { diff --git a/packages/Webkul/Core/src/Http/Controllers/LocaleController.php b/packages/Webkul/Core/src/Http/Controllers/LocaleController.php index 19bfeffc5..019e8d854 100755 --- a/packages/Webkul/Core/src/Http/Controllers/LocaleController.php +++ b/packages/Webkul/Core/src/Http/Controllers/LocaleController.php @@ -43,7 +43,7 @@ class LocaleController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { @@ -53,7 +53,7 @@ class LocaleController extends Controller /** * Show the form for creating a new resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function create() { @@ -87,7 +87,7 @@ class LocaleController extends Controller * Show the form for editing the specified resource. * * @param int $id - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function edit($id) { diff --git a/packages/Webkul/Core/src/Http/Controllers/SliderController.php b/packages/Webkul/Core/src/Http/Controllers/SliderController.php index e9c3a7f33..04deeb442 100755 --- a/packages/Webkul/Core/src/Http/Controllers/SliderController.php +++ b/packages/Webkul/Core/src/Http/Controllers/SliderController.php @@ -47,7 +47,7 @@ class SliderController extends Controller /** * Loads the index for the sliders settings. * - * @return mixed + * @return \Illuminate\View\View */ public function index() { @@ -57,7 +57,7 @@ class SliderController extends Controller /** * Loads the form for creating slider. * - * @return mixed + * @return \Illuminate\View\View */ public function create() { @@ -92,7 +92,7 @@ class SliderController extends Controller /** * Edit the previously created slider item. * - * @return mixed + * @return \Illuminate\View\View */ public function edit($id) { diff --git a/packages/Webkul/Core/src/Http/Controllers/SubscriptionController.php b/packages/Webkul/Core/src/Http/Controllers/SubscriptionController.php index c44f3ece8..affc806d7 100755 --- a/packages/Webkul/Core/src/Http/Controllers/SubscriptionController.php +++ b/packages/Webkul/Core/src/Http/Controllers/SubscriptionController.php @@ -44,7 +44,7 @@ class SubscriptionController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { @@ -55,8 +55,7 @@ class SubscriptionController extends Controller * To unsubscribe the user without deleting the resource of the subscribed user * * @param integer $id - * - * @return mixed + * @return \Illuminate\View\View */ public function edit($id) { @@ -69,7 +68,6 @@ class SubscriptionController extends Controller * To unsubscribe the user without deleting the resource of the subscribed user * * @param integer $id - * * @return mixed */ public function update($id) diff --git a/packages/Webkul/Customer/src/Database/Migrations/2019_03_28_103658_add_notes_column_in_customers_table.php b/packages/Webkul/Customer/src/Database/Migrations/2019_03_28_103658_add_notes_column_in_customers_table.php index ec4f45089..12793a5f3 100644 --- a/packages/Webkul/Customer/src/Database/Migrations/2019_03_28_103658_add_notes_column_in_customers_table.php +++ b/packages/Webkul/Customer/src/Database/Migrations/2019_03_28_103658_add_notes_column_in_customers_table.php @@ -26,7 +26,6 @@ class AddNotesColumnInCustomersTable extends Migration public function down() { Schema::table('customers', function (Blueprint $table) { - $table->dropColumn('notes'); }); } } diff --git a/packages/Webkul/Customer/src/Database/Migrations/2019_08_12_184925_add_additional_cloumn_in_wishlist_table.php b/packages/Webkul/Customer/src/Database/Migrations/2019_08_12_184925_add_additional_cloumn_in_wishlist_table.php new file mode 100644 index 000000000..b3f3ce787 --- /dev/null +++ b/packages/Webkul/Customer/src/Database/Migrations/2019_08_12_184925_add_additional_cloumn_in_wishlist_table.php @@ -0,0 +1,32 @@ +json('additional')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('wishlist', function (Blueprint $table) { + // + }); + } +} diff --git a/packages/Webkul/Customer/src/Http/Controllers/AccountController.php b/packages/Webkul/Customer/src/Http/Controllers/AccountController.php index 22bc576fc..1c34f365d 100755 --- a/packages/Webkul/Customer/src/Http/Controllers/AccountController.php +++ b/packages/Webkul/Customer/src/Http/Controllers/AccountController.php @@ -35,7 +35,7 @@ class AccountController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { diff --git a/packages/Webkul/Customer/src/Http/Controllers/AddressController.php b/packages/Webkul/Customer/src/Http/Controllers/AddressController.php index e1119f31a..b7fefec45 100755 --- a/packages/Webkul/Customer/src/Http/Controllers/AddressController.php +++ b/packages/Webkul/Customer/src/Http/Controllers/AddressController.php @@ -45,7 +45,7 @@ class AddressController extends Controller /** * Address Route index page * - * @return view + * @return \Illuminate\View\View */ public function index() { @@ -55,7 +55,7 @@ class AddressController extends Controller /** * Show the address create form * - * @return view + * @return \Illuminate\View\View */ public function create() { @@ -103,7 +103,7 @@ class AddressController extends Controller /** * For editing the existing addresses of current logged in customer * - * @return view + * @return \Illuminate\View\View */ public function edit($id) { diff --git a/packages/Webkul/Customer/src/Http/Controllers/CustomerController.php b/packages/Webkul/Customer/src/Http/Controllers/CustomerController.php index 743d82c6c..e05616ad3 100755 --- a/packages/Webkul/Customer/src/Http/Controllers/CustomerController.php +++ b/packages/Webkul/Customer/src/Http/Controllers/CustomerController.php @@ -45,7 +45,7 @@ class CustomerController extends Controller /** * Taking the customer to profile details page * - * @return View + * @return \Illuminate\View\View */ public function index() { @@ -57,7 +57,7 @@ class CustomerController extends Controller /** * For loading the edit form page. * - * @return View + * @return \Illuminate\View\View */ public function edit() { @@ -116,7 +116,7 @@ class CustomerController extends Controller /** * Load the view for the customer account panel, showing approved reviews. * - * @return Mixed + * @return \Illuminate\View\View */ public function reviews() { diff --git a/packages/Webkul/Customer/src/Http/Controllers/ForgotPasswordController.php b/packages/Webkul/Customer/src/Http/Controllers/ForgotPasswordController.php index efec364d8..a98503c06 100755 --- a/packages/Webkul/Customer/src/Http/Controllers/ForgotPasswordController.php +++ b/packages/Webkul/Customer/src/Http/Controllers/ForgotPasswordController.php @@ -36,7 +36,7 @@ class ForgotPasswordController extends Controller /** * Show the form for creating a new resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function create() { diff --git a/packages/Webkul/Customer/src/Http/Controllers/RegistrationController.php b/packages/Webkul/Customer/src/Http/Controllers/RegistrationController.php index d9f4bde2a..cb3c6dc35 100755 --- a/packages/Webkul/Customer/src/Http/Controllers/RegistrationController.php +++ b/packages/Webkul/Customer/src/Http/Controllers/RegistrationController.php @@ -60,7 +60,7 @@ class RegistrationController extends Controller /** * Opens up the user's sign up form. * - * @return view + * @return \Illuminate\View\View */ public function show() { diff --git a/packages/Webkul/Customer/src/Http/Controllers/ResetPasswordController.php b/packages/Webkul/Customer/src/Http/Controllers/ResetPasswordController.php index 780833dfc..73e47ef7f 100755 --- a/packages/Webkul/Customer/src/Http/Controllers/ResetPasswordController.php +++ b/packages/Webkul/Customer/src/Http/Controllers/ResetPasswordController.php @@ -41,7 +41,7 @@ class ResetPasswordController extends Controller * If no token is present, display the link request form. * * @param string|null $token - * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + * @return \Illuminate\View\View */ public function create($token = null) { diff --git a/packages/Webkul/Customer/src/Http/Controllers/SessionController.php b/packages/Webkul/Customer/src/Http/Controllers/SessionController.php index e1a85cb85..da3dc2015 100755 --- a/packages/Webkul/Customer/src/Http/Controllers/SessionController.php +++ b/packages/Webkul/Customer/src/Http/Controllers/SessionController.php @@ -40,7 +40,7 @@ class SessionController extends Controller /** * Display the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function show() { diff --git a/packages/Webkul/Customer/src/Http/Controllers/WishlistController.php b/packages/Webkul/Customer/src/Http/Controllers/WishlistController.php index 5d3a073fe..4ecac9ebd 100755 --- a/packages/Webkul/Customer/src/Http/Controllers/WishlistController.php +++ b/packages/Webkul/Customer/src/Http/Controllers/WishlistController.php @@ -59,6 +59,8 @@ class WishlistController extends Controller /** * Displays the listing resources if the customer having items in wishlist. + * + * @return \Illuminate\View\View */ public function index() { @@ -79,9 +81,8 @@ class WishlistController extends Controller { $product = $this->productRepository->findOneByField('id', $itemId); - if (! $product->status) { + if (! $product->status) return redirect()->back(); - } $data = [ 'channel_id' => core()->getCurrentChannel()->id, @@ -149,39 +150,31 @@ class WishlistController extends Controller */ public function move($itemId) { - $wishlistItem = $this->wishlistRepository->findOneByField('id', $itemId); + $wishlistItem = $this->wishlistRepository->findOneWhere([ + 'id' => $itemId, + 'customer_id' => auth()->guard('customer')->user()->id + ]); - if (! isset($wishlistItem) || $wishlistItem->customer_id != auth()->guard('customer')->user()->id) { - session()->flash('warning', trans('shop::app.security-warning')); - - return redirect()->route('customer.wishlist.index'); - } + if (! $wishlistItem) + abort(404); try { $result = Cart::moveToCart($wishlistItem); + + if ($result) { + session()->flash('success', trans('shop::app.wishlist.moved')); + } else { + session()->flash('info', trans('shop::app.wishlist.option-missing')); + + return redirect()->route('shop.products.index', $wishlistItem->product->url_key); + } + + return redirect()->back(); } catch (\Exception $e) { session()->flash('warning', $e->getMessage()); return redirect()->back(); } - - if ($result) { - if ($wishlistItem->delete()) { - session()->flash('success', trans('shop::app.wishlist.moved')); - - Cart::collectTotals(); - - return redirect()->back(); - } else { - session()->flash('error', trans('shop::app.wishlist.move-error')); - - return redirect()->back(); - } - } else { - session()->flash('info', trans('shop::app.wishlist.option-missing')); - - return redirect()->route('shop.products.index', $wishlistItem->product->url_key); - } } /** diff --git a/packages/Webkul/Customer/src/Mail/VerificationEmail.php b/packages/Webkul/Customer/src/Mail/VerificationEmail.php index ef874a335..55653dba4 100755 --- a/packages/Webkul/Customer/src/Mail/VerificationEmail.php +++ b/packages/Webkul/Customer/src/Mail/VerificationEmail.php @@ -26,7 +26,7 @@ class VerificationEmail extends Mailable /** * Build the message. * - * @return $this + * @return \Illuminate\View\View */ public function build() { diff --git a/packages/Webkul/Customer/src/Models/Wishlist.php b/packages/Webkul/Customer/src/Models/Wishlist.php index bf875dd04..dd762464e 100755 --- a/packages/Webkul/Customer/src/Models/Wishlist.php +++ b/packages/Webkul/Customer/src/Models/Wishlist.php @@ -10,9 +10,17 @@ class Wishlist extends Model implements WishlistContract { protected $table = 'wishlist'; - protected $fillable = ['channel_id', 'product_id', 'customer_id', 'item_options','moved_to_cart','shared','time_of_moving']; + protected $casts = [ + 'additional' => 'array', + ]; - public function product() { + protected $fillable = ['channel_id', 'product_id', 'customer_id', 'additional', 'moved_to_cart', 'shared', 'time_of_moving']; + + /** + * The Product that belong to the wishlist. + */ + public function product() + { return $this->hasOne(ProductProxy::modelClass(), 'id', 'product_id'); } } diff --git a/packages/Webkul/Discount/src/Http/Controllers/CartRuleController.php b/packages/Webkul/Discount/src/Http/Controllers/CartRuleController.php index c122886ba..0529d4517 100644 --- a/packages/Webkul/Discount/src/Http/Controllers/CartRuleController.php +++ b/packages/Webkul/Discount/src/Http/Controllers/CartRuleController.php @@ -63,7 +63,7 @@ class CartRuleController extends Controller } /** - * @return view + * @return \Illuminate\View\View */ public function index() { @@ -71,7 +71,7 @@ class CartRuleController extends Controller } /** - * @return view + * @return \Illuminate\View\View */ public function create() { @@ -277,7 +277,7 @@ class CartRuleController extends Controller } /** - * @return view + * @return \Illuminate\View\View */ public function edit($id) { diff --git a/packages/Webkul/Inventory/src/Http/Controllers/InventorySourceController.php b/packages/Webkul/Inventory/src/Http/Controllers/InventorySourceController.php index b78570a3e..c8e8cbb05 100755 --- a/packages/Webkul/Inventory/src/Http/Controllers/InventorySourceController.php +++ b/packages/Webkul/Inventory/src/Http/Controllers/InventorySourceController.php @@ -43,7 +43,7 @@ class InventorySourceController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { @@ -53,7 +53,7 @@ class InventorySourceController extends Controller /** * Show the form for creating a new resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function create() { @@ -99,7 +99,7 @@ class InventorySourceController extends Controller * Show the form for editing the specified resource. * * @param int $id - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function edit($id) { diff --git a/packages/Webkul/Paypal/src/Http/Controllers/StandardController.php b/packages/Webkul/Paypal/src/Http/Controllers/StandardController.php index 8390dc44a..4edbc32bf 100755 --- a/packages/Webkul/Paypal/src/Http/Controllers/StandardController.php +++ b/packages/Webkul/Paypal/src/Http/Controllers/StandardController.php @@ -47,7 +47,7 @@ class StandardController extends Controller /** * Redirects to the paypal. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function redirect() { diff --git a/packages/Webkul/Product/src/Config/product_types.php b/packages/Webkul/Product/src/Config/product_types.php index 84b33d5aa..80508fe03 100644 --- a/packages/Webkul/Product/src/Config/product_types.php +++ b/packages/Webkul/Product/src/Config/product_types.php @@ -6,7 +6,6 @@ return [ 'name' => 'Simple', 'class' => 'Webkul\Product\Type\Simple', 'sort' => 1 - ], 'configurable' => [ 'key' => 'configurable', @@ -20,10 +19,16 @@ return [ 'class' => 'Webkul\Product\Type\Virtual', 'sort' => 3 ], + 'grouped' => [ + 'key' => 'grouped', + 'name' => 'Grouped', + 'class' => 'Webkul\Product\Type\Grouped', + 'sort' => 4 + ], 'downloadable' => [ 'key' => 'downloadable', 'name' => 'Downloadable', 'class' => 'Webkul\Product\Type\Downloadable', - 'sort' => 4 + 'sort' => 5 ] ]; \ No newline at end of file diff --git a/packages/Webkul/Product/src/Contracts/ProductGroupedProduct.php b/packages/Webkul/Product/src/Contracts/ProductGroupedProduct.php new file mode 100644 index 000000000..ca9d6ed64 --- /dev/null +++ b/packages/Webkul/Product/src/Contracts/ProductGroupedProduct.php @@ -0,0 +1,7 @@ +increments('id'); + $table->integer('qty')->default(0); + $table->integer('sort_order')->default(0); + + $table->integer('product_id')->unsigned(); + $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade'); + + $table->integer('associated_product_id')->unsigned(); + $table->foreign('associated_product_id')->references('id')->on('products')->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('product_grouped_products'); + } +} \ No newline at end of file diff --git a/packages/Webkul/Product/src/Helpers/AbstractProduct.php b/packages/Webkul/Product/src/Helpers/AbstractProduct.php index 50650ad4c..f7efa7ae4 100755 --- a/packages/Webkul/Product/src/Helpers/AbstractProduct.php +++ b/packages/Webkul/Product/src/Helpers/AbstractProduct.php @@ -6,6 +6,12 @@ use Webkul\Product\Models\ProductAttributeValue; use Webkul\Product\Models\ProductFlatProxy; use Webkul\Product\Models\ProductFlat; +/** + * Abstract Product Helper + * + * @author Jitendra Singh + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ abstract class AbstractProduct { /** diff --git a/packages/Webkul/Product/src/Helpers/ConfigurableOption.php b/packages/Webkul/Product/src/Helpers/ConfigurableOption.php index 3ec316b67..dc7d65ca4 100755 --- a/packages/Webkul/Product/src/Helpers/ConfigurableOption.php +++ b/packages/Webkul/Product/src/Helpers/ConfigurableOption.php @@ -8,6 +8,12 @@ use Webkul\Product\Helpers\Price; use Webkul\Product\Models\Product; use Webkul\Product\Models\ProductAttributeValue; +/** + * Configurable Option Helper + * + * @author Jitendra Singh + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ class ConfigurableOption extends AbstractProduct { /** diff --git a/packages/Webkul/Product/src/Helpers/GroupedProduct.php b/packages/Webkul/Product/src/Helpers/GroupedProduct.php new file mode 100644 index 000000000..6b8a90c79 --- /dev/null +++ b/packages/Webkul/Product/src/Helpers/GroupedProduct.php @@ -0,0 +1,32 @@ + + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ +class GroupedProduct extends AbstractProduct +{ + /** + * ProductGroupedProductRepository object + * + * @var object + */ + protected $productGroupedProductRepository; + + /** + * Create a new helper instance. + * + * @param Webkul\Product\Repositories\ProductGroupedProductRepository $productGroupedProductRepository + * @return void + */ + public function __construct(ProductGroupedProductRepository $productGroupedProductRepository) + { + $this->productGroupedProductRepository = $productGroupedProductRepository; + } +} \ No newline at end of file diff --git a/packages/Webkul/Product/src/Helpers/Price.php b/packages/Webkul/Product/src/Helpers/Price.php index da28d0193..8e3464864 100755 --- a/packages/Webkul/Product/src/Helpers/Price.php +++ b/packages/Webkul/Product/src/Helpers/Price.php @@ -7,6 +7,12 @@ use Webkul\Product\Models\ProductAttributeValue; use Webkul\Product\Models\Product; use Webkul\Product\Models\ProductFlat; +/** + * Price Helper + * + * @author Jitendra Singh + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ class Price extends AbstractProduct { /** @@ -60,6 +66,7 @@ class Price extends AbstractProduct public function getVariantMinPrice($product) { static $price = []; + $finalPrice = []; if (array_key_exists($product->id, $price)) @@ -122,9 +129,8 @@ class Price extends AbstractProduct if (is_null($product->special_price) || ! (float) $product->special_price) return false; - if (core()->isChannelDateInInterval($product->special_price_from, $product->special_price_to)) { + if (core()->isChannelDateInInterval($product->special_price_from, $product->special_price_to)) return true; - } return false; } diff --git a/packages/Webkul/Product/src/Helpers/ProductImage.php b/packages/Webkul/Product/src/Helpers/ProductImage.php index bd0fe1b7e..98b6e49c3 100755 --- a/packages/Webkul/Product/src/Helpers/ProductImage.php +++ b/packages/Webkul/Product/src/Helpers/ProductImage.php @@ -5,6 +5,12 @@ namespace Webkul\Product\Helpers; use Webkul\Attribute\Repositories\AttributeOptionRepository as AttributeOption; use Illuminate\Support\Facades\Storage; +/** + * Product Image Helper + * + * @author Jitendra Singh + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ class ProductImage extends AbstractProduct { /** diff --git a/packages/Webkul/Product/src/Helpers/Review.php b/packages/Webkul/Product/src/Helpers/Review.php index 72a1059fe..fadd70bf8 100755 --- a/packages/Webkul/Product/src/Helpers/Review.php +++ b/packages/Webkul/Product/src/Helpers/Review.php @@ -3,6 +3,12 @@ namespace Webkul\Product\Helpers; use DB; +/** + * Product Review Helper + * + * @author Jitendra Singh + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ class Review extends AbstractProduct { /** diff --git a/packages/Webkul/Product/src/Helpers/Toolbar.php b/packages/Webkul/Product/src/Helpers/Toolbar.php index b89c3ec34..cee7e5fdc 100755 --- a/packages/Webkul/Product/src/Helpers/Toolbar.php +++ b/packages/Webkul/Product/src/Helpers/Toolbar.php @@ -2,6 +2,12 @@ namespace Webkul\Product\Helpers; +/** + * Toolbar Helper + * + * @author Jitendra Singh + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ class Toolbar extends AbstractProduct { /** diff --git a/packages/Webkul/Product/src/Helpers/View.php b/packages/Webkul/Product/src/Helpers/View.php index 16bca34d5..eebd5effb 100755 --- a/packages/Webkul/Product/src/Helpers/View.php +++ b/packages/Webkul/Product/src/Helpers/View.php @@ -2,6 +2,12 @@ namespace Webkul\Product\Helpers; +/** + * Product View Helper + * + * @author Jitendra Singh + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ class View extends AbstractProduct { /** diff --git a/packages/Webkul/Product/src/Http/Controllers/ProductController.php b/packages/Webkul/Product/src/Http/Controllers/ProductController.php index 3a949238e..574d81b75 100755 --- a/packages/Webkul/Product/src/Http/Controllers/ProductController.php +++ b/packages/Webkul/Product/src/Http/Controllers/ProductController.php @@ -8,6 +8,7 @@ use Webkul\Category\Repositories\CategoryRepository; use Webkul\Product\Repositories\ProductRepository; use Webkul\Product\Repositories\ProductDownloadableLinkRepository; use Webkul\Product\Repositories\ProductDownloadableSampleRepository; +use Webkul\Product\Repositories\ProductGroupedProductRepository; use Webkul\Attribute\Repositories\AttributeFamilyRepository; use Webkul\Inventory\Repositories\InventorySourceRepository; use Illuminate\Support\Facades\Storage; @@ -69,6 +70,13 @@ class ProductController extends Controller */ protected $inventorySourceRepository; + /** + * ProductGroupedProductRepository object + * + * @var Object + */ + protected $productGroupedProductRepository; + /** * Create a new controller instance. * @@ -78,6 +86,7 @@ class ProductController extends Controller * @param \Webkul\Product\Repositories\ProductDownloadableSampleRepository $productDownloadableSampleRepository * @param \Webkul\Attribute\Repositories\AttributeFamilyRepository $attributeFamilyRepository * @param \Webkul\Inventory\Repositories\InventorySourceRepository $inventorySource + * @param \Webkul\Inventory\Repositories\ProductGroupedProductRepository $productGroupedProductRepository * @return void */ public function __construct( @@ -86,7 +95,8 @@ class ProductController extends Controller ProductDownloadableLinkRepository $productDownloadableLinkRepository, ProductDownloadableSampleRepository $productDownloadableSampleRepository, AttributeFamilyRepository $attributeFamilyRepository, - InventorySourceRepository $inventorySourceRepository + InventorySourceRepository $inventorySourceRepository, + ProductGroupedProductRepository $productGroupedProductRepository ) { $this->_config = request('_config'); @@ -102,12 +112,14 @@ class ProductController extends Controller $this->attributeFamilyRepository = $attributeFamilyRepository; $this->inventorySourceRepository = $inventorySourceRepository; + + $this->productGroupedProductRepository = $productGroupedProductRepository; } /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { @@ -117,7 +129,7 @@ class ProductController extends Controller /** * Show the form for creating a new resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function create() { @@ -172,7 +184,7 @@ class ProductController extends Controller * Show the form for editing the specified resource. * * @param int $id - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function edit($id) { @@ -317,7 +329,7 @@ class ProductController extends Controller /** * Result of search product. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View | \Illuminate\Http\JsonResponse */ public function productLinkSearch() { @@ -353,4 +365,16 @@ class ProductController extends Controller return Storage::download($productAttribute['text_value']); } + + /** + * Search simple products for grouped product association + * + * @return \Illuminate\Http\JsonResponse + */ + public function searchProductForGroupedAssociation() + { + return response()->json( + $this->productGroupedProductRepository->searchSimpleProducts(request('id'), request()->input('query')) + ); + } } \ No newline at end of file diff --git a/packages/Webkul/Product/src/Http/Controllers/ReviewController.php b/packages/Webkul/Product/src/Http/Controllers/ReviewController.php index 7db3e0eaa..105e6f7b5 100755 --- a/packages/Webkul/Product/src/Http/Controllers/ReviewController.php +++ b/packages/Webkul/Product/src/Http/Controllers/ReviewController.php @@ -45,7 +45,7 @@ class ReviewController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { @@ -56,7 +56,7 @@ class ReviewController extends Controller * Show the form for editing the specified resource. * * @param int $id - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function edit($id) { diff --git a/packages/Webkul/Product/src/Models/Product.php b/packages/Webkul/Product/src/Models/Product.php index 5494e5b73..d98084ae9 100755 --- a/packages/Webkul/Product/src/Models/Product.php +++ b/packages/Webkul/Product/src/Models/Product.php @@ -157,6 +157,14 @@ class Product extends Model implements ProductContract return $this->hasMany(ProductDownloadableLinkProxy::modelClass()); } + /** + * Get the grouped products that owns the product. + */ + public function grouped_products() + { + return $this->hasMany(ProductGroupedProductProxy::modelClass()); + } + /** * @param integer $qty * diff --git a/packages/Webkul/Product/src/Models/ProductFlat.php b/packages/Webkul/Product/src/Models/ProductFlat.php index 770828b16..e5b47f256 100644 --- a/packages/Webkul/Product/src/Models/ProductFlat.php +++ b/packages/Webkul/Product/src/Models/ProductFlat.php @@ -13,6 +13,16 @@ class ProductFlat extends Model implements ProductFlatContract public $timestamps = false; + /** + * Retrieve type instance + * + * @return AbstractType + */ + public function getTypeInstance() + { + return $this->product->getTypeInstance(); + } + /** * Get the product that owns the attribute value. */ @@ -149,6 +159,14 @@ class ProductFlat extends Model implements ProductFlatContract return $this->product->downloadable_links(); } + /** + * Get the grouped products that owns the product. + */ + public function grouped_products() + { + return $this->product->grouped_products(); + } + /** * Retrieve product attributes * diff --git a/packages/Webkul/Product/src/Models/ProductGroupedProduct.php b/packages/Webkul/Product/src/Models/ProductGroupedProduct.php new file mode 100644 index 000000000..c66eb1657 --- /dev/null +++ b/packages/Webkul/Product/src/Models/ProductGroupedProduct.php @@ -0,0 +1,29 @@ +belongsTo(ProductProxy::modelClass()); + } + + /** + * Get the product that owns the image. + */ + public function associated_product() + { + return $this->belongsTo(ProductProxy::modelClass()); + } +} \ No newline at end of file diff --git a/packages/Webkul/Product/src/Models/ProductGroupedProductProxy.php b/packages/Webkul/Product/src/Models/ProductGroupedProductProxy.php new file mode 100644 index 000000000..ad7553503 --- /dev/null +++ b/packages/Webkul/Product/src/Models/ProductGroupedProductProxy.php @@ -0,0 +1,10 @@ +type != 'downloadable') - return; - $previousLinkIds = $product->downloadable_links()->pluck('id'); if (isset($data['downloadable_links'])) { diff --git a/packages/Webkul/Product/src/Repositories/ProductDownloadableSampleRepository.php b/packages/Webkul/Product/src/Repositories/ProductDownloadableSampleRepository.php index 105ea6d2f..532ebe84f 100755 --- a/packages/Webkul/Product/src/Repositories/ProductDownloadableSampleRepository.php +++ b/packages/Webkul/Product/src/Repositories/ProductDownloadableSampleRepository.php @@ -48,9 +48,6 @@ class ProductDownloadableSampleRepository extends Repository */ public function saveSamples(array $data, $product) { - if ($product->type != 'downloadable') - return; - $previousSampleIds = $product->downloadable_samples()->pluck('id'); if (isset($data['downloadable_samples'])) { diff --git a/packages/Webkul/Product/src/Repositories/ProductGroupedProductRepository.php b/packages/Webkul/Product/src/Repositories/ProductGroupedProductRepository.php new file mode 100644 index 000000000..8920c3ead --- /dev/null +++ b/packages/Webkul/Product/src/Repositories/ProductGroupedProductRepository.php @@ -0,0 +1,83 @@ + + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ +class ProductGroupedProductRepository extends Repository +{ + public function model() + { + return 'Webkul\Product\Contracts\ProductGroupedProduct'; + } + + /** + * Search simple products for grouped product association + * + * @param integer $productId + * @param string $term + * @return \Illuminate\Support\Collection + */ + public function searchSimpleProducts($productId, $term) + { + $product = app(ProductRepository::class)->find($productId); + + $groupedProductIds = $product->grouped_products()->pluck('product_id'); + + $groupedProductIds = $groupedProductIds->concat([$productId]); + + return app(ProductFlatRepository::class)->scopeQuery(function($query) use($groupedProductIds, $term) { + $channel = request()->get('channel') ?: (core()->getCurrentChannelCode() ?: core()->getDefaultChannelCode()); + + $locale = request()->get('locale') ?: app()->getLocale(); + + return $query->distinct() + ->addSelect('product_flat.*') + ->addSelect('product_flat.product_id as id') + ->leftJoin('products', 'product_flat.product_id', '=', 'products.id') + ->where('products.type', 'simple') + ->where('product_flat.channel', $channel) + ->where('product_flat.locale', $locale) + ->whereNotIn('product_flat.product_id', $groupedProductIds) + ->where('product_flat.name', 'like', '%' . urldecode($term) . '%') + ->orderBy('product_id', 'desc'); + })->get(); + } + + /** + * @param array $data + * @param Product $product + * @return void + */ + public function saveGroupedProducts($data, $product) + { + $previousGroupedProductIds = $product->grouped_products()->pluck('id'); + + if (isset($data['links'])) { + foreach ($data['links'] as $linkId => $linkInputs) { + if (str_contains($linkId, 'link_')) { + $this->create(array_merge([ + 'product_id' => $product->id, + ], $linkInputs)); + } else { + if (is_numeric($index = $previousGroupedProductIds->search($linkId))) + $previousGroupedProductIds->forget($index); + + $this->update($linkInputs, $linkId); + } + } + } + + foreach ($previousGroupedProductIds as $previousGroupedProductId) { + $this->delete($previousGroupedProductId); + } + } +} \ No newline at end of file diff --git a/packages/Webkul/Product/src/Repositories/ProductInventoryRepository.php b/packages/Webkul/Product/src/Repositories/ProductInventoryRepository.php index 470f4add0..822d0291a 100755 --- a/packages/Webkul/Product/src/Repositories/ProductInventoryRepository.php +++ b/packages/Webkul/Product/src/Repositories/ProductInventoryRepository.php @@ -30,14 +30,12 @@ class ProductInventoryRepository extends Repository */ public function saveInventories(array $data, $product) { - if ($product->type != 'simple') + if (! $product->isStockable()) return; if (isset($data['inventories'])) { foreach ($data['inventories'] as $inventorySourceId => $qty) { - if (is_null($qty)) { - $qty = 0; - } + $qty = is_null($qty) ? 0 : $qty; $productInventory = $this->findOneWhere([ 'product_id' => $product->id, @@ -45,7 +43,6 @@ class ProductInventoryRepository extends Repository 'vendor_id' => isset($data['vendor_id']) ? $data['vendor_id'] : 0 ]); - if ($productInventory) { $productInventory->qty = $qty; diff --git a/packages/Webkul/Product/src/Repositories/ProductRepository.php b/packages/Webkul/Product/src/Repositories/ProductRepository.php index ed4924f04..d474e9626 100755 --- a/packages/Webkul/Product/src/Repositories/ProductRepository.php +++ b/packages/Webkul/Product/src/Repositories/ProductRepository.php @@ -2,14 +2,12 @@ namespace Webkul\Product\Repositories; -use Illuminate\Container\Container as App; use DB; +use Illuminate\Container\Container as App; use Illuminate\Support\Facades\Event; -use Webkul\Core\Eloquent\Repository; -use Webkul\Attribute\Repositories\AttributeRepository; -use Webkul\Product\Models\ProductAttributeValue; use Illuminate\Database\Eloquent\ModelNotFoundException; -use Storage; +use Webkul\Attribute\Repositories\AttributeRepository; +use Webkul\Core\Eloquent\Repository; /** * Product Repository @@ -26,78 +24,23 @@ class ProductRepository extends Repository */ protected $attributeRepository; - /** - * ProductAttributeValueRepository object - * - * @var array - */ - protected $attributeValueRepository; - - /** - * ProductFlatRepository object - * - * @var array - */ - protected $productInventoryRepository; - - /** - * ProductImageRepository object - * - * @var array - */ - protected $productImageRepository; - - /** - * ProductDownloadableLinkRepository object - * - * @var array - */ - protected $productDownloadableLinkRepository; - - /** - * ProductDownloadableLinkRepository object - * - * @var array - */ - protected $productDownloadableSampleRepository; - /** * Create a new controller instance. * - * @param Webkul\Attribute\Repositories\AttributeRepository $attributeRepository - * @param Webkul\Attribute\Repositories\ProductAttributeValueRepository $attributeValueRepository - * @param Webkul\Product\Repositories\ProductInventoryRepository $productInventoryRepository - * @param Webkul\Product\Repositories\ProductImageRepository $productImageRepository - * @param Webkul\Product\Repositories\ProductDownloadableLinkRepository $productDownloadableLinkRepository - * @param Webkul\Product\Repositories\ProductDownloadableSampleRepository $productDownloadableSampleRepository + * @param Webkul\Attribute\Repositories\AttributeRepository $attributeRepository * @return void */ public function __construct( AttributeRepository $attributeRepository, - ProductAttributeValueRepository $attributeValueRepository, - ProductInventoryRepository $productInventoryRepository, - ProductImageRepository $productImageRepository, - ProductDownloadableLinkRepository $productDownloadableLinkRepository, - ProductDownloadableSampleRepository $productDownloadableSampleRepository, App $app ) { $this->attributeRepository = $attributeRepository; - $this->attributeValueRepository = $attributeValueRepository; - - $this->productInventoryRepository = $productInventoryRepository; - - $this->productImageRepository = $productImageRepository; - - $this->productDownloadableLinkRepository = $productDownloadableLinkRepository; - - $this->productDownloadableSampleRepository = $productDownloadableSampleRepository; - parent::__construct($app); } - /**->where('product_flat.visible_individually', 1) + /** * Specify Model class name * * @return mixed @@ -113,36 +56,12 @@ class ProductRepository extends Repository */ public function create(array $data) { - //before store of the product Event::fire('catalog.product.create.before'); - $product = $this->model->create($data); + $typeInstance = app(config('product_types.' . $data['type'] . '.class')); - $nameAttribute = $this->attributeRepository->findOneByField('code', 'status'); - $this->attributeValueRepository->create([ - 'product_id' => $product->id, - 'attribute_id' => $nameAttribute->id, - 'value' => 1 - ]); + $product = $typeInstance->create($data); - if (isset($data['super_attributes'])) { - - $super_attributes = []; - - foreach ($data['super_attributes'] as $attributeCode => $attributeOptions) { - $attribute = $this->attributeRepository->findOneByField('code', $attributeCode); - - $super_attributes[$attribute->id] = $attributeOptions; - - $product->super_attributes()->attach($attribute->id); - } - - foreach (array_permutation($super_attributes) as $permutation) { - $this->createVariant($product, $permutation); - } - } - - //after store of the product Event::fire('catalog.product.create.after', $product); return $product; @@ -160,121 +79,7 @@ class ProductRepository extends Repository $product = $this->find($id); - if ($product->parent_id && $this->checkVariantOptionAvailabiliy($data, $product)) { - $data['parent_id'] = NULL; - } - - $product->update($data); - - $attributes = $product->attribute_family->custom_attributes; - - foreach ($attributes as $attribute) { - if (! isset($data[$attribute->code]) || (in_array($attribute->type, ['date', 'datetime']) && ! $data[$attribute->code])) - continue; - - if ($attribute->type == 'multiselect') { - $data[$attribute->code] = implode(",", $data[$attribute->code]); - } - - if ($attribute->type == 'image' || $attribute->type == 'file') { - $dir = 'product/' . $product->id; - - if (gettype($data[$attribute->code]) == 'object') { - $data[$attribute->code] = request()->file($attribute->code)->store($dir); - } else { - $data[$attribute->code] = NULL; - } - } - - $attributeValue = $this->attributeValueRepository->findOneWhere([ - 'product_id' => $product->id, - 'attribute_id' => $attribute->id, - 'channel' => $attribute->value_per_channel ? $data['channel'] : null, - 'locale' => $attribute->value_per_locale ? $data['locale'] : null - ]); - - if (! $attributeValue) { - $this->attributeValueRepository->create([ - 'product_id' => $product->id, - 'attribute_id' => $attribute->id, - 'value' => $data[$attribute->code], - 'channel' => $attribute->value_per_channel ? $data['channel'] : null, - 'locale' => $attribute->value_per_locale ? $data['locale'] : null - ]); - } else { - $this->attributeValueRepository->update([ - ProductAttributeValue::$attributeTypeFields[$attribute->type] => $data[$attribute->code] - ], $attributeValue->id - ); - - if ($attribute->type == 'image' || $attribute->type == 'file') { - Storage::delete($attributeValue->text_value); - } - } - } - - if (request()->route()->getName() != 'admin.catalog.products.massupdate') { - if (isset($data['categories'])) { - $product->categories()->sync($data['categories']); - } - - if (isset($data['up_sell'])) { - $product->up_sells()->sync($data['up_sell']); - } else { - $data['up_sell'] = []; - $product->up_sells()->sync($data['up_sell']); - } - - if (isset($data['cross_sell'])) { - $product->cross_sells()->sync($data['cross_sell']); - } else { - $data['cross_sell'] = []; - $product->cross_sells()->sync($data['cross_sell']); - } - - if (isset($data['related_products'])) { - $product->related_products()->sync($data['related_products']); - } else { - $data['related_products'] = []; - $product->related_products()->sync($data['related_products']); - } - - $previousVariantIds = $product->variants->pluck('id'); - - if (isset($data['variants'])) { - foreach ($data['variants'] as $variantId => $variantData) { - if (str_contains($variantId, 'variant_')) { - $permutation = []; - foreach ($product->super_attributes as $superAttribute) { - $permutation[$superAttribute->id] = $variantData[$superAttribute->code]; - } - - $this->createVariant($product, $permutation, $variantData); - } else { - if (is_numeric($index = $previousVariantIds->search($variantId))) { - $previousVariantIds->forget($index); - } - - $variantData['channel'] = $data['channel']; - $variantData['locale'] = $data['locale']; - - $this->updateVariant($variantData, $variantId); - } - } - } - - foreach ($previousVariantIds as $variantId) { - $this->delete($variantId); - } - - $this->productInventoryRepository->saveInventories($data, $product); - - $this->productImageRepository->uploadImages($data, $product); - - $this->productDownloadableLinkRepository->saveLinks($data, $product); - - $this->productDownloadableSampleRepository->saveSamples($data, $product); - } + $product = $product->getTypeInstance()->update($data, $id, $attribute); Event::fire('catalog.product.update.after', $product); @@ -294,167 +99,6 @@ class ProductRepository extends Repository Event::fire('catalog.product.delete.after', $id); } - /** - * @param mixed $product - * @param array $permutation - * @param array $data - * @return mixed - */ - public function createVariant($product, $permutation, $data = []) - { - if (! count($data)) { - $data = [ - "sku" => $product->sku . '-variant-' . implode('-', $permutation), - "name" => "", - "inventories" => [], - "price" => 0, - "weight" => 0, - "status" => 1 - ]; - } - - $variant = $this->model->create([ - 'parent_id' => $product->id, - 'type' => 'simple', - 'attribute_family_id' => $product->attribute_family_id, - 'sku' => $data['sku'], - ]); - - foreach (['sku', 'name', 'price', 'weight', 'status'] as $attributeCode) { - $attribute = $this->attributeRepository->findOneByField('code', $attributeCode); - - if ($attribute->value_per_channel) { - if ($attribute->value_per_locale) { - foreach (core()->getAllChannels() as $channel) { - foreach (core()->getAllLocales() as $locale) { - $this->attributeValueRepository->create([ - 'product_id' => $variant->id, - 'attribute_id' => $attribute->id, - 'channel' => $channel->code, - 'locale' => $locale->code, - 'value' => $data[$attributeCode] - ]); - } - } - } else { - foreach (core()->getAllChannels() as $channel) { - $this->attributeValueRepository->create([ - 'product_id' => $variant->id, - 'attribute_id' => $attribute->id, - 'channel' => $channel->code, - 'value' => $data[$attributeCode] - ]); - } - } - } else { - if ($attribute->value_per_locale) { - foreach (core()->getAllLocales() as $locale) { - $this->attributeValueRepository->create([ - 'product_id' => $variant->id, - 'attribute_id' => $attribute->id, - 'locale' => $locale->code, - 'value' => $data[$attributeCode] - ]); - } - } else { - $this->attributeValueRepository->create([ - 'product_id' => $variant->id, - 'attribute_id' => $attribute->id, - 'value' => $data[$attributeCode] - ]); - } - } - } - - foreach ($permutation as $attributeId => $optionId) { - $this->attributeValueRepository->create([ - 'product_id' => $variant->id, - 'attribute_id' => $attributeId, - 'value' => $optionId - ]); - } - - $this->productInventoryRepository->saveInventories($data, $variant); - - return $variant; - } - - /** - * @param array $data - * @param $id - * @return mixed - */ - public function updateVariant(array $data, $id) - { - $variant = $this->find($id); - - $variant->update(['sku' => $data['sku']]); - - foreach (['sku', 'name', 'price', 'weight', 'status'] as $attributeCode) { - $attribute = $this->attributeRepository->findOneByField('code', $attributeCode); - - $attributeValue = $this->attributeValueRepository->findOneWhere([ - 'product_id' => $id, - 'attribute_id' => $attribute->id, - 'channel' => $attribute->value_per_channel ? $data['channel'] : null, - 'locale' => $attribute->value_per_locale ? $data['locale'] : null - ]); - - if (! $attributeValue) { - $this->attributeValueRepository->create([ - 'product_id' => $id, - 'attribute_id' => $attribute->id, - 'value' => $data[$attribute->code], - 'channel' => $attribute->value_per_channel ? $data['channel'] : null, - 'locale' => $attribute->value_per_locale ? $data['locale'] : null - ]); - } else { - $this->attributeValueRepository->update([ - ProductAttributeValue::$attributeTypeFields[$attribute->type] => $data[$attribute->code] - ], $attributeValue->id); - } - } - - $this->productInventoryRepository->saveInventories($data, $variant); - - return $variant; - } - - /** - * @param array $data - * @param mixed $product - * @return mixed - */ - public function checkVariantOptionAvailabiliy($data, $product) - { - $parent = $product->parent; - - $superAttributeCodes = $parent->super_attributes->pluck('code'); - - $isAlreadyExist = false; - - foreach ($parent->variants as $variant) { - if ($variant->id == $product->id) - continue; - - $matchCount = 0; - - foreach ($superAttributeCodes as $attributeCode) { - if (! isset($data[$attributeCode])) - return false; - - if ($data[$attributeCode] == $variant->{$attributeCode}) - $matchCount++; - } - - if ($matchCount == $superAttributeCodes->count()) { - return true; - } - } - - return false; - } - /** * @param integer $categoryId * @return Collection @@ -473,24 +117,20 @@ class ProductRepository extends Repository ->addSelect(DB::raw('IF( product_flat.special_price_from IS NOT NULL AND product_flat.special_price_to IS NOT NULL , IF( NOW( ) >= product_flat.special_price_from AND NOW( ) <= product_flat.special_price_to, IF( product_flat.special_price IS NULL OR product_flat.special_price = 0 , product_flat.price, LEAST( product_flat.special_price, product_flat.price ) ) , product_flat.price ) , IF( product_flat.special_price_from IS NULL , IF( product_flat.special_price_to IS NULL , IF( product_flat.special_price IS NULL OR product_flat.special_price = 0 , product_flat.price, LEAST( product_flat.special_price, product_flat.price ) ) , IF( NOW( ) <= product_flat.special_price_to, IF( product_flat.special_price IS NULL OR product_flat.special_price = 0 , product_flat.price, LEAST( product_flat.special_price, product_flat.price ) ) , product_flat.price ) ) , IF( product_flat.special_price_to IS NULL , IF( NOW( ) >= product_flat.special_price_from, IF( product_flat.special_price IS NULL OR product_flat.special_price = 0 , product_flat.price, LEAST( product_flat.special_price, product_flat.price ) ) , product_flat.price ) , product_flat.price ) ) ) AS final_price')) - ->leftJoin('products', 'product_flat.product_id', '=', 'products.id') ->leftJoin('product_categories', 'products.id', '=', 'product_categories.product_id') ->where('product_flat.channel', $channel) ->where('product_flat.locale', $locale) ->whereNotNull('product_flat.url_key'); - if ($categoryId) { + if ($categoryId) $qb->where('product_categories.category_id', $categoryId); - } - if (is_null(request()->input('status'))) { + if (is_null(request()->input('status'))) $qb->where('product_flat.status', 1); - } - if (is_null(request()->input('visible_individually'))) { + if (is_null(request()->input('visible_individually'))) $qb->where('product_flat.visible_individually', 1); - } $queryBuilder = $qb->leftJoin('product_flat as flat_variants', function($qb) use($channel, $locale) { $qb->on('product_flat.id', '=', 'flat_variants.parent_id') @@ -498,9 +138,8 @@ class ProductRepository extends Repository ->where('flat_variants.locale', $locale); }); - if (isset($params['search'])) { + if (isset($params['search'])) $qb->where('product_flat.name', 'like', '%' . urldecode($params['search']) . '%'); - } if (isset($params['sort'])) { $attribute = $this->attributeRepository->findOneByField('code', $params['sort']); diff --git a/packages/Webkul/Product/src/Type/AbstractType.php b/packages/Webkul/Product/src/Type/AbstractType.php index 8363eac03..e913972ff 100644 --- a/packages/Webkul/Product/src/Type/AbstractType.php +++ b/packages/Webkul/Product/src/Type/AbstractType.php @@ -2,6 +2,17 @@ namespace Webkul\Product\Type; +use Webkul\Attribute\Repositories\AttributeRepository; +use Webkul\Product\Repositories\ProductRepository; +use Webkul\Product\Repositories\ProductAttributeValueRepository; +use Webkul\Product\Repositories\ProductInventoryRepository; +use Webkul\Product\Repositories\ProductImageRepository; +use Webkul\Product\Models\ProductAttributeValue; +use Webkul\Product\Helpers\Price; +use Webkul\Product\Helpers\ProductImage; +use Illuminate\Support\Facades\Storage; +use Cart; + /** * Abstract class Type * @@ -10,6 +21,55 @@ namespace Webkul\Product\Type; */ abstract class AbstractType { + /** + * AttributeRepository instance + * + * @var AttributeRepository + */ + protected $attributeRepository; + + /** + * ProductRepository instance + * + * @var ProductRepository + */ + protected $productRepository; + + /** + * ProductAttributeValueRepository instance + * + * @var ProductAttributeValueRepository + */ + protected $attributeValueRepository; + + /** + * ProductInventoryRepository instance + * + * @var ProductInventoryRepository + */ + protected $productInventoryRepository; + + /** + * ProductImageRepository instance + * + * @var ProductImageRepository + */ + protected $productImageRepository; + + /** + * Product price helper instance + * + * @var Price + */ + protected $priceHelper; + + /** + * Product Image helper instance + * + * @var ProductImage + */ + protected $productImageHelper; + /** * Product model instance * @@ -17,11 +77,126 @@ abstract class AbstractType */ protected $product; + /** + * Create a new product type instance. + * + * @param Webkul\Attribute\Repositories\AttributeRepository $attributeRepository + * @param Webkul\Product\Repositories\ProductRepository $productRepository + * @param Webkul\Product\Repositories\ProductAttributeValueRepository $attributeValueRepository + * @param Webkul\Product\Repositories\ProductInventoryRepository $productInventoryRepository + * @param Webkul\Product\Repositories\ProductImageRepository $productImageRepository + * @param Webkul\Product\Helpers\Price $priceHelper + * @param Webkul\Product\Helpers\ProductImage $productImageHelper + * @return void + */ + public function __construct( + AttributeRepository $attributeRepository, + ProductRepository $productRepository, + ProductAttributeValueRepository $attributeValueRepository, + ProductInventoryRepository $productInventoryRepository, + ProductImageRepository $productImageRepository, + Price $priceHelper, + ProductImage $productImageHelper + ) + { + $this->attributeRepository = $attributeRepository; + + $this->productRepository = $productRepository; + + $this->attributeValueRepository = $attributeValueRepository; + + $this->productInventoryRepository = $productInventoryRepository; + + $this->productImageRepository = $productImageRepository; + + $this->priceHelper = $priceHelper; + + $this->productImageHelper = $productImageHelper; + } + + /** + * @param array $data + * @return Product + */ + public function create(array $data) + { + return $this->productRepository->getModel()->create($data); + } + + /** + * @param array $data + * @param $id + * @param string $attribute + * @return Product + */ + public function update(array $data, $id, $attribute = "id") + { + $product = $this->productRepository->find($id); + + $product->update($data); + + foreach ($product->attribute_family->custom_attributes as $attribute) { + if (! isset($data[$attribute->code]) || (in_array($attribute->type, ['date', 'datetime']) && ! $data[$attribute->code])) + continue; + + if ($attribute->type == 'multiselect') + $data[$attribute->code] = implode(",", $data[$attribute->code]); + + if ($attribute->type == 'image' || $attribute->type == 'file') { + $data[$attribute->code] = gettype($data[$attribute->code]) == 'object' + ? request()->file($attribute->code)->store('product/' . $product->id) + : NULL; + } + + $attributeValue = $this->attributeValueRepository->findOneWhere([ + 'product_id' => $product->id, + 'attribute_id' => $attribute->id, + 'channel' => $attribute->value_per_channel ? $data['channel'] : null, + 'locale' => $attribute->value_per_locale ? $data['locale'] : null + ]); + + if (! $attributeValue) { + $this->attributeValueRepository->create([ + 'product_id' => $product->id, + 'attribute_id' => $attribute->id, + 'value' => $data[$attribute->code], + 'channel' => $attribute->value_per_channel ? $data['channel'] : null, + 'locale' => $attribute->value_per_locale ? $data['locale'] : null + ]); + } else { + $this->attributeValueRepository->update([ + ProductAttributeValue::$attributeTypeFields[$attribute->type] => $data[$attribute->code] + ], $attributeValue->id + ); + + if ($attribute->type == 'image' || $attribute->type == 'file') + Storage::delete($attributeValue->text_value); + } + } + + if (request()->route()->getName() != 'admin.catalog.products.massupdate') { + if (isset($data['categories'])) + $product->categories()->sync($data['categories']); + + $product->up_sells()->sync($data['up_sell'] ?? []); + + $product->cross_sells()->sync($data['cross_sell'] ?? []); + + $product->related_products()->sync($data['related_products'] ?? []); + + $this->productInventoryRepository->saveInventories($data, $product); + + $this->productImageRepository->uploadImages($data, $product); + } + + return $product; + } + /** * Specify type instance product * - * @param Product $product - * @return AbstractType + * @param Product $product + * @return AbstractType */ public function setProduct($product) { @@ -33,25 +208,52 @@ abstract class AbstractType /** * Return true if this product type is saleable * - * @return array + * @return boolean */ - abstract public function isSaleable(); + public function isSaleable() + { + if (! $this->product->status) + return false; + + return true; + } /** * Return true if this product can have inventory * - * @return array + * @return boolean */ - abstract public function isStockable(); + public function isStockable() + { + return false; + } + + /** + * @param integer $qty + * @return bool + */ + public function haveSufficientQuantity($qty) + { + return true; + } + + /** + * @param CartItem $cartItem + * @return bool + */ + public function isItemHaveQuantity($cartItem) + { + return $cartItem->product->getTypeInstance()->haveSufficientQuantity($cartItem->quantity); + } /** * Return true if item can be moved to cart from wishlist * * @return boolean */ - public function canBeMovedFromWishlistToCart() + public function canBeMovedFromWishlistToCart($item) { - return false; + return true; } /** @@ -91,5 +293,120 @@ abstract class AbstractType { return []; } -} -?> \ No newline at end of file + + /** + * Add product. Returns error message if can't prepare product. + * + * @param array $data + * @return array + */ + public function prepareForCart($data) + { + $data = $this->getQtyRequest($data); + + if ($this->isStockable() && ! $this->haveSufficientQuantity($data['quantity'])) + return trans('shop::app.checkout.cart.quantity.inventory_warning'); + + $price = $this->priceHelper->getMinimalPrice($this->product); + + $products = [ + [ + 'product_id' => $this->product->id, + 'sku' => $this->product->sku, + 'quantity' => $data['quantity'], + 'name' => $this->product->name, + 'price' => $convertedPrice = core()->convertPrice($price), + 'base_price' => $price, + 'total' => $convertedPrice * $data['quantity'], + 'base_total' => $price * $data['quantity'], + 'weight' => $this->product->weight ?? 0, + 'total_weight' => ($this->product->weight ?? 0) * $data['quantity'], + 'base_total_weight' => ($this->product->weight ?? 0) * $data['quantity'], + 'type' => $this->product->type, + 'additional' => $this->getAdditionalOptions($data) + ] + ]; + + return $products; + } + + /** + * Get request quantity + * + * @param Product $product + * @param array $data + * @return CartItem|void + */ + public function getQtyRequest($data) + { + if ($item = Cart::getItemByProduct(['additional' => $data])) + $data['quantity'] += $item->quantity; + + return $data; + } + + /** + * Check if product can be configured + * + * @return boolean + */ + public function canConfigure() + { + return false; + } + + /** + * + * @param array $options1 + * @param array $options2 + * @return boolean + */ + public function compareOptions($options1, $options2) + { + return $this->product->id == $options2['product_id']; + } + + /** + * Returns additional information for items + * + * @param array $data + * @return array + */ + public function getAdditionalOptions($data) + { + return $data; + } + + /** + * Get actual ordered item + * + * @param CartItem $item + * @return CartItem|OrderItem|InvoiceItem|ShipmentItem|Wishlist + */ + public function getOrderedItem($item) + { + return $item; + } + + /** + * Get product base image + * + * @param Wishlist|CartItem $item + * @return array + */ + public function getBaseImage($item) + { + return $this->productImageHelper->getProductBaseImage($item->product); + } + + /** + * Get product base image + * + * @param CartItem $item + * @return float + */ + public function getMinimalPrice($item) + { + return $this->priceHelper->getMinimalPrice($item->product); + } +} \ No newline at end of file diff --git a/packages/Webkul/Product/src/Type/Configurable.php b/packages/Webkul/Product/src/Type/Configurable.php new file mode 100644 index 000000000..2bb6235ba --- /dev/null +++ b/packages/Webkul/Product/src/Type/Configurable.php @@ -0,0 +1,433 @@ + + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ +class Configurable extends AbstractType +{ + /** + * Skip attribute for downloadable product type + * + * @var array + */ + protected $skipAttributes = ['price', 'cost', 'special_price', 'special_price_from', 'special_price_to', 'width', 'height', 'depth', 'weight']; + + /** + * These blade files will be included in product edit page + * + * @var array + */ + protected $additionalViews = [ + 'admin::catalog.products.accordians.images', + 'admin::catalog.products.accordians.categories', + 'admin::catalog.products.accordians.variations', + 'admin::catalog.products.accordians.product-links' + ]; + + /** + * @param array $data + * @return Product + */ + public function create(array $data) + { + $product = $this->productRepository->getModel()->create($data); + + if (isset($data['super_attributes'])) { + $super_attributes = []; + + foreach ($data['super_attributes'] as $attributeCode => $attributeOptions) { + $attribute = $this->attributeRepository->findOneByField('code', $attributeCode); + + $super_attributes[$attribute->id] = $attributeOptions; + + $product->super_attributes()->attach($attribute->id); + } + + foreach (array_permutation($super_attributes) as $permutation) { + $this->createVariant($product, $permutation); + } + } + } + + /** + * @param array $data + * @param $id + * @param string $attribute + * @return Product + */ + public function update(array $data, $id, $attribute = "id") + { + $product = parent::update($data, $id, $attribute); + + if (request()->route()->getName() != 'admin.catalog.products.massupdate') { + $previousVariantIds = $product->variants->pluck('id'); + + if (isset($data['variants'])) { + foreach ($data['variants'] as $variantId => $variantData) { + if (str_contains($variantId, 'variant_')) { + $permutation = []; + + foreach ($product->super_attributes as $superAttribute) { + $permutation[$superAttribute->id] = $variantData[$superAttribute->code]; + } + + $this->createVariant($product, $permutation, $variantData); + } else { + if (is_numeric($index = $previousVariantIds->search($variantId))) + $previousVariantIds->forget($index); + + $variantData['channel'] = $data['channel']; + $variantData['locale'] = $data['locale']; + + $this->updateVariant($variantData, $variantId); + } + } + } + + foreach ($previousVariantIds as $variantId) { + $this->productRepository->delete($variantId); + } + } + + return $product; + } + + /** + * @param mixed $product + * @param array $permutation + * @param array $data + * @return mixed + */ + public function createVariant($product, $permutation, $data = []) + { + if (! count($data)) { + $data = [ + "sku" => $product->sku . '-variant-' . implode('-', $permutation), + "name" => "", + "inventories" => [], + "price" => 0, + "weight" => 0, + "status" => 1 + ]; + } + + $variant = $this->productRepository->getModel()->create([ + 'parent_id' => $product->id, + 'type' => 'simple', + 'attribute_family_id' => $product->attribute_family_id, + 'sku' => $data['sku'], + ]); + + foreach (['sku', 'name', 'price', 'weight', 'status'] as $attributeCode) { + $attribute = $this->attributeRepository->findOneByField('code', $attributeCode); + + if ($attribute->value_per_channel) { + if ($attribute->value_per_locale) { + foreach (core()->getAllChannels() as $channel) { + foreach (core()->getAllLocales() as $locale) { + $this->attributeValueRepository->create([ + 'product_id' => $variant->id, + 'attribute_id' => $attribute->id, + 'channel' => $channel->code, + 'locale' => $locale->code, + 'value' => $data[$attributeCode] + ]); + } + } + } else { + foreach (core()->getAllChannels() as $channel) { + $this->attributeValueRepository->create([ + 'product_id' => $variant->id, + 'attribute_id' => $attribute->id, + 'channel' => $channel->code, + 'value' => $data[$attributeCode] + ]); + } + } + } else { + if ($attribute->value_per_locale) { + foreach (core()->getAllLocales() as $locale) { + $this->attributeValueRepository->create([ + 'product_id' => $variant->id, + 'attribute_id' => $attribute->id, + 'locale' => $locale->code, + 'value' => $data[$attributeCode] + ]); + } + } else { + $this->attributeValueRepository->create([ + 'product_id' => $variant->id, + 'attribute_id' => $attribute->id, + 'value' => $data[$attributeCode] + ]); + } + } + } + + foreach ($permutation as $attributeId => $optionId) { + $this->attributeValueRepository->create([ + 'product_id' => $variant->id, + 'attribute_id' => $attributeId, + 'value' => $optionId + ]); + } + + $this->productInventoryRepository->saveInventories($data, $variant); + + return $variant; + } + + /** + * @param array $data + * @param $id + * @return mixed + */ + public function updateVariant(array $data, $id) + { + $variant = $this->productRepository->find($id); + + $variant->update(['sku' => $data['sku']]); + + foreach (['sku', 'name', 'price', 'weight', 'status'] as $attributeCode) { + $attribute = $this->attributeRepository->findOneByField('code', $attributeCode); + + $attributeValue = $this->attributeValueRepository->findOneWhere([ + 'product_id' => $id, + 'attribute_id' => $attribute->id, + 'channel' => $attribute->value_per_channel ? $data['channel'] : null, + 'locale' => $attribute->value_per_locale ? $data['locale'] : null + ]); + + if (! $attributeValue) { + $this->attributeValueRepository->create([ + 'product_id' => $id, + 'attribute_id' => $attribute->id, + 'value' => $data[$attribute->code], + 'channel' => $attribute->value_per_channel ? $data['channel'] : null, + 'locale' => $attribute->value_per_locale ? $data['locale'] : null + ]); + } else { + $this->attributeValueRepository->update([ + ProductAttributeValue::$attributeTypeFields[$attribute->type] => $data[$attribute->code] + ], $attributeValue->id); + } + } + + $this->productInventoryRepository->saveInventories($data, $variant); + + return $variant; + } + + /** + * @param array $data + * @param mixed $product + * @return mixed + */ + public function checkVariantOptionAvailabiliy($data, $product) + { + $superAttributeCodes = $product->parent->super_attributes->pluck('code'); + + foreach ($product->parent->variants as $variant) { + if ($variant->id == $product->id) + continue; + + $matchCount = 0; + + foreach ($superAttributeCodes as $attributeCode) { + if (! isset($data[$attributeCode])) + return false; + + if ($data[$attributeCode] == $variant->{$attributeCode}) + $matchCount++; + } + + if ($matchCount == $superAttributeCodes->count()) + return true; + } + + return false; + } + + /** + * @param CartItem $cartItem + * @return bool + */ + public function isItemHaveQuantity($cartItem) + { + return $cartItem->child->product->getTypeInstance()->haveSufficientQuantity($cartItem->quantity); + } + + /** + * Returns validation rules + * + * @return array + */ + public function getTypeValidationRules() + { + return [ + 'variants.*.name' => 'required', + 'variants.*.sku' => 'required', + 'variants.*.price' => 'required', + 'variants.*.weight' => 'required', + ]; + } + + /** + * Return true if item can be moved to cart from wishlist + * + * @param Wishlist $item + * @return boolean + */ + public function canBeMovedFromWishlistToCart($item) + { + if (isset($item->additional['selected_configurable_option'])) + return true; + + return false; + } + + /** + * Add product. Returns error message if can't prepare product. + * + * @param array $data + * @return array + */ + public function prepareForCart($data) + { + if (! isset($data['selected_configurable_option']) || ! $data['selected_configurable_option']) + return trans('shop::app.checkout.cart.item.error-add'); + + $data = $this->getQtyRequest($data); + + $childProduct = $this->productRepository->find($data['selected_configurable_option']); + + if (! $childProduct->haveSufficientQuantity($data['quantity'])) + return trans('shop::app.checkout.cart.quantity.inventory_warning'); + + $price = $this->priceHelper->getMinimalPrice($childProduct); + + $products = [ + [ + 'product_id' => $this->product->id, + 'sku' => $this->product->sku, + 'quantity' => $data['quantity'], + 'name' => $this->product->name, + 'price' => $convertedPrice = core()->convertPrice($price), + 'base_price' => $price, + 'total' => $convertedPrice * $data['quantity'], + 'base_total' => $price * $data['quantity'], + 'weight' => $childProduct->weight, + 'total_weight' => $childProduct->weight * $data['quantity'], + 'base_total_weight' => $childProduct->weight * $data['quantity'], + 'type' => $this->product->type, + 'additional' => $this->getAdditionalOptions($data) + ], [ + 'parent_id' => $this->product->id, + 'product_id' => (int) $data['selected_configurable_option'], + 'sku' => $childProduct->sku, + 'name' => $childProduct->name, + 'type' => 'simple', + 'additional' => ['product_id' => (int) $data['selected_configurable_option']] + ] + ]; + + return $products; + } + + /** + * Check if product can be configured + * + * @return boolean + */ + public function canConfigure() + { + return true; + } + + /** + * + * @param array $options1 + * @param array $options2 + * @return boolean + */ + public function compareOptions($options1, $options2) + { + if ($this->product->id != $options2['product_id']) + return false; + + return $options1['selected_configurable_option'] === $options2['selected_configurable_option']; + } + + /** + * Returns additional information for items + * + * @param array $data + * @return array + */ + public function getAdditionalOptions($data) + { + $childProduct = app('Webkul\Product\Repositories\ProductRepository')->findOneByField('id', $data['selected_configurable_option']); + + foreach ($this->product->super_attributes as $attribute) { + $option = $attribute->options()->where('id', $childProduct->{$attribute->code})->first(); + + $data['attributes'][$attribute->code] = [ + 'attribute_name' => $attribute->name ? $attribute->name : $attribute->admin_name, + 'option_id' => $option->id, + 'option_label' => $option->label, + ]; + } + + return $data; + } + + /** + * Get actual ordered item + * + * @param CartItem $item + * @return CartItem|OrderItem|InvoiceItem|ShipmentItem + */ + public function getOrderedItem($item) + { + return $item->child; + } + + /** + * Get product base image + * + * @param Wishlist|CartItem $item + * @return array + */ + public function getBaseImage($item) + { + if ($item instanceof \Webkul\Customer\Contracts\Wishlist) { + if (isset($item->additional['selected_configurable_option'])) { + $product = $this->productRepository->find($item->additional['selected_configurable_option']); + } else { + $product = $item->product; + } + } else { + $product = $item->child->product; + } + + return $this->productImageHelper->getProductBaseImage($product); + } + + /** + * Get product base image + * + * @param CartItem $item + * @return array + */ + public function getMinimalPrice($item) + { + return $this->priceHelper->getMinimalPrice($item->child->product); + } +} \ No newline at end of file diff --git a/packages/Webkul/Product/src/Type/Confirgurable.php b/packages/Webkul/Product/src/Type/Confirgurable.php deleted file mode 100644 index a6f64cbd1..000000000 --- a/packages/Webkul/Product/src/Type/Confirgurable.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) - */ -class Configurable extends AbstractType -{ - /** - * Skip attribute for downloadable product type - * - * @var array - */ - protected $skipAttributes = ['price', 'cost', 'special_price', 'special_price_from', 'special_price_to', 'width', 'height', 'depth', 'weight']; - - /** - * @var array - */ - protected $additionalViews = [ - 'admin::catalog.products.accordians.images', - 'admin::catalog.products.accordians.categories', - 'admin::catalog.products.accordians.variations', - 'admin::catalog.products.accordians.product-links' - ]; - - /** - * Return true if this product type is saleable - * - * @return array - */ - public function isSaleable() - { - if (! $this->product->status) - return false; - - return true; - } - - /** - * Return true if this product can have inventory - * - * @return array - */ - public function isStockable() - { - return false; - } - - /** - * Returns validation rules - * - * @return array - */ - public function getTypeValidationRules() - { - return [ - 'variants.*.name' => 'required', - 'variants.*.sku' => 'required', - 'variants.*.price' => 'required', - 'variants.*.weight' => 'required', - ]; - } -} \ No newline at end of file diff --git a/packages/Webkul/Product/src/Type/Downloadable.php b/packages/Webkul/Product/src/Type/Downloadable.php index 045eab095..74a552aee 100644 --- a/packages/Webkul/Product/src/Type/Downloadable.php +++ b/packages/Webkul/Product/src/Type/Downloadable.php @@ -2,6 +2,18 @@ namespace Webkul\Product\Type; +use Webkul\Attribute\Repositories\AttributeRepository; +use Webkul\Product\Repositories\ProductRepository; +use Webkul\Product\Repositories\ProductAttributeValueRepository; +use Webkul\Product\Repositories\ProductInventoryRepository; +use Webkul\Product\Repositories\ProductImageRepository; +use Webkul\Product\Repositories\ProductDownloadableLinkRepository; +use Webkul\Product\Repositories\ProductDownloadableSampleRepository; +use Webkul\Product\Models\ProductAttributeValue; +use Webkul\Product\Helpers\Price; +use Webkul\Product\Helpers\ProductImage; +use Webkul\Checkout\Models\CartItem; + /** * Class Downloadable. * @@ -10,6 +22,69 @@ namespace Webkul\Product\Type; */ class Downloadable extends AbstractType { + /** + * AttributeRepository instance + * + * @var AttributeRepository + */ + protected $attributeRepository; + + /** + * ProductRepository instance + * + * @var ProductRepository + */ + protected $productRepository; + + /** + * ProductAttributeValueRepository instance + * + * @var ProductAttributeValueRepository + */ + protected $attributeValueRepository; + + /** + * ProductInventoryRepository instance + * + * @var ProductInventoryRepository + */ + protected $productInventoryRepository; + + /** + * ProductImageRepository instance + * + * @var ProductImageRepository + */ + protected $productImageRepository; + + /** + * ProductDownloadableLinkRepository instance + * + * @var ProductDownloadableLinkRepository + */ + protected $productDownloadableLinkRepository; + + /** + * ProductDownloadableSampleRepository instance + * + * @var ProductDownloadableSampleRepository + */ + protected $productDownloadableSampleRepository; + + /** + * Product price helper instance + * + * @var Price + */ + protected $priceHelper; + + /** + * Product Image helper instance + * + * @var ProductImage + */ + protected $productImageHelper; + /** * Skip attribute for downloadable product type * @@ -18,6 +93,8 @@ class Downloadable extends AbstractType protected $skipAttributes = ['width', 'height', 'depth', 'weight']; /** + * These blade files will be included in product edit page + * * @var array */ protected $additionalViews = [ @@ -27,10 +104,70 @@ class Downloadable extends AbstractType 'admin::catalog.products.accordians.product-links' ]; + /** + * Create a new product type instance. + * + * @param Webkul\Attribute\Repositories\AttributeRepository $attributeRepository + * @param Webkul\Product\Repositories\ProductRepository $productRepository + * @param Webkul\Product\Repositories\ProductAttributeValueRepository $attributeValueRepository + * @param Webkul\Product\Repositories\ProductInventoryRepository $productInventoryRepository + * @param Webkul\Product\Repositories\ProductImageRepository $productImageRepository + * @param Webkul\Product\Repositories\ProductDownloadableLinkRepository $productDownloadableLinkRepository + * @param Webkul\Product\Repositories\ProductDownloadableSampleRepository $productDownloadableSampleRepository + * @param Webkul\Product\Helpers\Price $priceHelper + * @param Webkul\Product\Helpers\ProductImage $productImageHelper + * @return void + */ + public function __construct( + AttributeRepository $attributeRepository, + ProductRepository $productRepository, + ProductAttributeValueRepository $attributeValueRepository, + ProductInventoryRepository $productInventoryRepository, + productImageRepository $productImageRepository, + ProductDownloadableLinkRepository $productDownloadableLinkRepository, + ProductDownloadableSampleRepository $productDownloadableSampleRepository, + Price $priceHelper, + ProductImage $productImageHelper + ) + { + parent::__construct( + $attributeRepository, + $productRepository, + $attributeValueRepository, + $productInventoryRepository, + $productImageRepository, + $priceHelper, + $productImageHelper + ); + + $this->productDownloadableLinkRepository = $productDownloadableLinkRepository; + + $this->productDownloadableSampleRepository = $productDownloadableSampleRepository; + } + + /** + * @param array $data + * @param $id + * @param string $attribute + * @return Product + */ + public function update(array $data, $id, $attribute = "id") + { + $product = parent::update($data, $id, $attribute); + + if (request()->route()->getName() != 'admin.catalog.products.massupdate') { + $this->productDownloadableLinkRepository->saveLinks($data, $product); + + $this->productDownloadableSampleRepository->saveSamples($data, $product); + } + + return $product; + } + /** * Return true if this product type is saleable * - * @return array + * @return boolean */ public function isSaleable() { @@ -43,16 +180,6 @@ class Downloadable extends AbstractType return false; } - /** - * Return true if this product can have inventory - * - * @return array - */ - public function isStockable() - { - return false; - } - /** * Returns validation rules * @@ -70,4 +197,66 @@ class Downloadable extends AbstractType 'downloadable_links.*.sort_order' => 'required', ]; } + + /** + * Add product. Returns error message if can't prepare product. + * + * @param array $data + * @return array + */ + public function prepareForCart($data) + { + if(! isset($data['links']) || ! count($data['links'])) + return trans('shop::app.checkout.cart.integrity.missing_links'); + + return parent::prepareForCart($data); + } + + /** + * Check if product can be configured + * + * @return boolean + */ + public function canConfigure() + { + return true; + } + + /** + * + * @param array $options1 + * @param array $options2 + * @return boolean + */ + public function compareOptions($options1, $options2) + { + if ($this->product->id != $options2['product_id']) + return false; + + return $options1['links'] == $options2['links']; + } + + /** + * Returns additional information for items + * + * @param array $data + * @return array + */ + public function getAdditionalOptions($data) + { + $labels = []; + + foreach ($this->product->downloadable_links as $link) { + if (in_array($link->id, $data['links'])) + $labels[] = $link->title; + } + + $data['attributes'][0] = [ + 'attribute_name' => 'Downloads', + 'option_id' => 0, + 'option_label' => implode(', ', $labels), + ]; + + return $data; + } } \ No newline at end of file diff --git a/packages/Webkul/Product/src/Type/Grouped.php b/packages/Webkul/Product/src/Type/Grouped.php new file mode 100644 index 000000000..dfce93def --- /dev/null +++ b/packages/Webkul/Product/src/Type/Grouped.php @@ -0,0 +1,188 @@ + + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ +class Grouped extends AbstractType +{ + /** + * AttributeRepository instance + * + * @var AttributeRepository + */ + protected $attributeRepository; + + /** + * ProductRepository instance + * + * @var ProductRepository + */ + protected $productRepository; + + /** + * ProductAttributeValueRepository instance + * + * @var ProductAttributeValueRepository + */ + protected $attributeValueRepository; + + /** + * ProductInventoryRepository instance + * + * @var ProductInventoryRepository + */ + protected $productInventoryRepository; + + /** + * ProductImageRepository instance + * + * @var ProductImageRepository + */ + protected $productImageRepository; + + /** + * ProductGroupedProductRepository instance + * + * @var ProductGroupedProductRepository + */ + protected $productGroupedProductRepository; + + /** + * Product price helper instance + * + * @var Price + */ + protected $priceHelper; + + /** + * Product Image helper instance + * + * @var ProductImage + */ + protected $productImageHelper; + + /** + * Skip attribute for downloadable product type + * + * @var array + */ + protected $skipAttributes = ['price', 'cost', 'special_price', 'special_price_from', 'special_price_to', 'width', 'height', 'depth', 'weight']; + + /** + * These blade files will be included in product edit page + * + * @var array + */ + protected $additionalViews = [ + 'admin::catalog.products.accordians.images', + 'admin::catalog.products.accordians.categories', + 'admin::catalog.products.accordians.grouped-products', + 'admin::catalog.products.accordians.product-links' + ]; + + /** + * Create a new product type instance. + * + * @param Webkul\Attribute\Repositories\AttributeRepository $attributeRepository + * @param Webkul\Product\Repositories\ProductRepository $productRepository + * @param Webkul\Product\Repositories\ProductAttributeValueRepository $attributeValueRepository + * @param Webkul\Product\Repositories\ProductInventoryRepository $productInventoryRepository + * @param Webkul\Product\Repositories\ProductImageRepository $productImageRepository + * @param Webkul\Product\Repositories\ProductGroupedProductRepository $productGroupedProductRepository + * @param Webkul\Product\Helpers\Price $priceHelper + * @param Webkul\Product\Helpers\ProductImage $productImageHelper + * @return void + */ + public function __construct( + AttributeRepository $attributeRepository, + ProductRepository $productRepository, + ProductAttributeValueRepository $attributeValueRepository, + ProductInventoryRepository $productInventoryRepository, + ProductImageRepository $productImageRepository, + ProductGroupedProductRepository $productGroupedProductRepository, + Price $priceHelper, + ProductImage $productImageHelper + ) + { + parent::__construct( + $attributeRepository, + $productRepository, + $attributeValueRepository, + $productInventoryRepository, + $productImageRepository, + $priceHelper, + $productImageHelper + ); + + $this->productGroupedProductRepository = $productGroupedProductRepository; + } + + /** + * @param array $data + * @param $id + * @param string $attribute + * @return Product + */ + public function update(array $data, $id, $attribute = "id") + { + $product = parent::update($data, $id, $attribute); + + if (request()->route()->getName() != 'admin.catalog.products.massupdate') + $this->productGroupedProductRepository->saveGroupedProducts($data, $product); + + return $product; + } + + /** + * Returns validation rules + * + * @return array + */ + public function getTypeValidationRules() + { + return [ + ]; + } + + /** + * Add product. Returns error message if can't prepare product. + * + * @param array $data + * @return array + */ + public function prepareForCart($data) + { + $products = []; + + foreach ($data['qty'] as $productId => $qty) { + $product = $this->productRepository->find($productId); + + $cartProducts = $product->getTypeInstance()->prepareForCart([ + 'product_id' => $productId, + 'quantity' => $qty, + ]); + + if (is_string($cartProducts)) + return $cartProducts; + + $products = array_merge($products, $cartProducts); + } + + return $products; + } +} \ No newline at end of file diff --git a/packages/Webkul/Product/src/Type/Simple.php b/packages/Webkul/Product/src/Type/Simple.php index fdb3219d6..f23000d60 100644 --- a/packages/Webkul/Product/src/Type/Simple.php +++ b/packages/Webkul/Product/src/Type/Simple.php @@ -18,6 +18,8 @@ class Simple extends AbstractType protected $skipAttributes = []; /** + * These blade files will be included in product edit page + * * @var array */ protected $additionalViews = [ @@ -30,7 +32,7 @@ class Simple extends AbstractType /** * Return true if this product type is saleable * - * @return array + * @return boolean */ public function isSaleable() { @@ -46,7 +48,7 @@ class Simple extends AbstractType /** * Return true if this product can have inventory * - * @return array + * @return boolean */ public function isStockable() { @@ -54,13 +56,13 @@ class Simple extends AbstractType } /** - * Return true if item can be moved to cart from wishlist + * @param integer $qty * * @return boolean */ - public function canBeMovedFromWishlistToCart() + public function haveSufficientQuantity($qty) { - return true; + return $qty <= $this->totalQuantity() ? true : (core()->getConfigData('catalog.inventory.stock_options.backorders') ? true : false); } /** @@ -91,14 +93,4 @@ class Simple extends AbstractType return $total; } - - /** - * @param integer $qty - * - * @return bool - */ - public function haveSufficientQuantity($qty) - { - return $qty <= $this->totalQuantity() ? true : (core()->getConfigData('catalog.inventory.stock_options.backorders') ? true : false); - } } \ No newline at end of file diff --git a/packages/Webkul/Product/src/Type/Virtual.php b/packages/Webkul/Product/src/Type/Virtual.php index 7e84de265..c4dc816c1 100644 --- a/packages/Webkul/Product/src/Type/Virtual.php +++ b/packages/Webkul/Product/src/Type/Virtual.php @@ -18,6 +18,8 @@ class Virtual extends AbstractType protected $skipAttributes = ['width', 'height', 'depth', 'weight']; /** + * These blade files will be included in product edit page + * * @var array */ protected $additionalViews = [ @@ -25,37 +27,4 @@ class Virtual extends AbstractType 'admin::catalog.products.accordians.categories', 'admin::catalog.products.accordians.product-links' ]; - - /** - * Return true if this product type is saleable - * - * @return array - */ - public function isSaleable() - { - if (! $this->product->status) - return false; - - return true; - } - - /** - * Return true if this product can have inventory - * - * @return array - */ - public function isStockable() - { - return false; - } - - /** - * Return true if item can be moved to cart from wishlist - * - * @return boolean - */ - public function canBeMovedFromWishlistToCart() - { - return true; - } } \ No newline at end of file diff --git a/packages/Webkul/Sales/src/Models/InvoiceItem.php b/packages/Webkul/Sales/src/Models/InvoiceItem.php index aa5a81a85..99f36e6ac 100755 --- a/packages/Webkul/Sales/src/Models/InvoiceItem.php +++ b/packages/Webkul/Sales/src/Models/InvoiceItem.php @@ -12,6 +12,16 @@ class InvoiceItem extends Model implements InvoiceItemContract protected $casts = [ 'additional' => 'array', ]; + + /** + * Retrieve type instance + * + * @return AbstractType + */ + public function getTypeInstance() + { + return $this->order_item->getTypeInstance(); + } /** * Get the invoice record associated with the invoice item. diff --git a/packages/Webkul/Sales/src/Models/ShipmentItem.php b/packages/Webkul/Sales/src/Models/ShipmentItem.php index c14a9d587..78970032b 100755 --- a/packages/Webkul/Sales/src/Models/ShipmentItem.php +++ b/packages/Webkul/Sales/src/Models/ShipmentItem.php @@ -12,6 +12,16 @@ class ShipmentItem extends Model implements ShipmentItemContract protected $casts = [ 'additional' => 'array', ]; + + /** + * Retrieve type instance + * + * @return AbstractType + */ + public function getTypeInstance() + { + return $this->order_item->getTypeInstance(); + } /** * Get the shipment record associated with the shipment item. diff --git a/packages/Webkul/Shop/src/Http/Controllers/CartController.php b/packages/Webkul/Shop/src/Http/Controllers/CartController.php index 7480e24a2..64bd6d5e4 100755 --- a/packages/Webkul/Shop/src/Http/Controllers/CartController.php +++ b/packages/Webkul/Shop/src/Http/Controllers/CartController.php @@ -2,10 +2,7 @@ namespace Webkul\Shop\Http\Controllers; -use Webkul\Checkout\Repositories\CartItemRepository; -use Webkul\Product\Repositories\ProductRepository; use Webkul\Customer\Repositories\WishlistRepository; -use Illuminate\Support\Facades\Event; use Cart; /** @@ -13,6 +10,7 @@ use Cart; * removing the products in the cart. * * @author Prashant Singh @prashant-webkul + * @author Jitendra Singh * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) */ class CartController extends Controller @@ -24,20 +22,6 @@ class CartController extends Controller */ protected $_config; - /** - * CartItemRepository object - * - * @var Object - */ - protected $cartItemRepository; - - /** - * ProductRepository object - * - * @var Object - */ - protected $productRepository; - /** * WishlistRepository Repository object * @@ -45,31 +29,16 @@ class CartController extends Controller */ protected $wishlistRepository; - /** - * @var boolean - */ - protected $suppressFlash = false; - /** * Create a new controller instance. * - * @param \Webkul\Checkout\Repositories\CartItemRepository $cartItemRepository - * @param \Webkul\Product\Repositories\ProductRepository $productRepository * @param \Webkul\Customer\Repositories\CartItemRepository $wishlistRepository * @return void */ - public function __construct( - CartItemRepository $cartItemRepository, - ProductRepository $productRepository, - WishlistRepository $wishlistRepository - ) + public function __construct(WishlistRepository $wishlistRepository) { $this->middleware('customer')->only(['moveToWishlist']); - $this->cartItemRepository = $cartItemRepository; - - $this->productRepository = $productRepository; - $this->wishlistRepository = $wishlistRepository; $this->_config = request('_config'); @@ -78,7 +47,7 @@ class CartController extends Controller /** * Method to populate the cart page which will be populated before the checkout process. * - * @return Mixed + * @return \Illuminate\View\View */ public function index() { @@ -93,74 +62,38 @@ class CartController extends Controller public function add($id) { try { - $product = $this->productRepository->find($id); - - $data = request()->all(); - - if ($product->type == 'downloadable' && ! isset($data['links'])) { - session()->flash('warning', trans('shop::app.checkout.cart.integrity.missing_links')); - - return redirect()->route('shop.products.index', $product->url_key); - } else if ($product->type == 'configurable' - && (! isset($data['selected_configurable_option']) || ! $data['selected_configurable_option'])) { - session()->flash('warning', trans('shop::app.checkout.cart.add-config-warning')); - - return redirect()->route('shop.products.index', $product->url_key); - } - - Event::fire('checkout.cart.add.before', $id); - - $result = Cart::add($id, request()->except('_token')); - - Event::fire('checkout.cart.add.after', $result); - - Cart::collectTotals(); + $result = Cart::addProduct($id, request()->all()); if ($result) { session()->flash('success', trans('shop::app.checkout.cart.item.success')); - if (auth()->guard('customer')->user()) { - $customer = auth()->guard('customer')->user(); + if ($customer = auth()->guard('customer')->user()) + $this->wishlistRepository->deleteWhere(['product_id' => $id]); - if (count($customer->wishlist_items)) { - foreach ($customer->wishlist_items as $wishlist) { - if ($wishlist->product_id == $id) { - $this->wishlistRepository->delete($wishlist->id); - } - } - } - } - - return redirect()->back(); + if (request()->get('is_buy_now')) + return redirect()->route('shop.checkout.onepage.index'); } else { session()->flash('warning', trans('shop::app.checkout.cart.item.error-add')); - - return redirect()->back(); } - - return redirect()->route($this->_config['redirect']); - } catch(\Exception $e) { session()->flash('error', trans($e->getMessage())); - - return redirect()->back(); } + + return redirect()->back(); } /** * Removes the item from the cart if it exists * * @param integer $itemId + * @return Response */ public function remove($itemId) { - Event::fire('checkout.cart.delete.before', $itemId); + $result = Cart::removeItem($itemId); - Cart::removeItem($itemId); - - Event::fire('checkout.cart.delete.after', $itemId); - - Cart::collectTotals(); + if ($result) + session()->flash('success', trans('shop::app.checkout.cart.item.success-remove')); return redirect()->back(); } @@ -168,47 +101,15 @@ class CartController extends Controller /** * Updates the quantity of the items present in the cart. * - * @return response + * @return Response */ public function updateBeforeCheckout() { try { - $request = request()->except('_token'); + $result = Cart::updateItems(request()->all()); - foreach ($request['qty'] as $id => $quantity) { - if ($quantity <= 0) { - session()->flash('warning', trans('shop::app.checkout.cart.quantity.illegal')); - - return redirect()->back(); - } - } - - foreach ($request['qty'] as $key => $value) { - $item = $this->cartItemRepository->findOneByField('id', $key); - - $data['quantity'] = $value; - - Event::fire('checkout.cart.update.before', $item); - - $result = Cart::updateItem($item->product_id, $data, $key); - - if ($result == false) { - $this->suppressFlash = true; - } - - Event::fire('checkout.cart.update.after', $item); - - unset($item); - unset($data); - } - - Cart::collectTotals(); - - if ($this->suppressFlash) { - session()->forget('success'); - session()->forget('warning'); - session()->flash('info', trans('shop::app.checkout.cart.partial-cart-update')); - } + if ($result) + session()->flash('success', trans('shop::app.checkout.cart.quantity.success')); } catch(\Exception $e) { session()->flash('error', trans($e->getMessage())); } @@ -216,49 +117,22 @@ class CartController extends Controller return redirect()->back(); } - public function buyNow($id, $quantity = 1) - { - try { - Event::fire('checkout.cart.add.before', $id); - - $result = Cart::proceedToBuyNow($id, $quantity); - - Event::fire('checkout.cart.add.after', $result); - - Cart::collectTotals(); - - if (! $result) { - return redirect()->back(); - } else { - return redirect()->route('shop.checkout.onepage.index'); - } - } catch(\Exception $e) { - session()->flash('error', trans($e->getMessage())); - - return redirect()->back(); - } - } - /** - * Function to move a already added product to wishlist - * will run only on customer authentication. + * Function to move a already added product to wishlist will run only on customer authentication. * - * @param instance cartItem $id + * @param integer $id + * @return Response */ public function moveToWishlist($id) { $result = Cart::moveToWishlist($id); - if (! $result) { - Cart::collectTotals(); - + if ($result) { session()->flash('success', trans('shop::app.wishlist.moved')); - - return redirect()->back(); } else { session()->flash('warning', trans('shop::app.wishlist.move-error')); - - return redirect()->back(); } + + return redirect()->back(); } } \ No newline at end of file diff --git a/packages/Webkul/Shop/src/Http/Controllers/CategoryController.php b/packages/Webkul/Shop/src/Http/Controllers/CategoryController.php index 4c49d3928..03d428067 100755 --- a/packages/Webkul/Shop/src/Http/Controllers/CategoryController.php +++ b/packages/Webkul/Shop/src/Http/Controllers/CategoryController.php @@ -43,7 +43,7 @@ class CategoryController extends Controller * Display a listing of the resource. * * @param string $slug - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index($slug) { diff --git a/packages/Webkul/Shop/src/Http/Controllers/DownloadableProductController.php b/packages/Webkul/Shop/src/Http/Controllers/DownloadableProductController.php index c269297b7..b0b14bd92 100644 --- a/packages/Webkul/Shop/src/Http/Controllers/DownloadableProductController.php +++ b/packages/Webkul/Shop/src/Http/Controllers/DownloadableProductController.php @@ -47,7 +47,7 @@ class DownloadableProductController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { return view($this->_config['view']); diff --git a/packages/Webkul/Shop/src/Http/Controllers/HomeController.php b/packages/Webkul/Shop/src/Http/Controllers/HomeController.php index ba8b35c1e..2c39ff53d 100755 --- a/packages/Webkul/Shop/src/Http/Controllers/HomeController.php +++ b/packages/Webkul/Shop/src/Http/Controllers/HomeController.php @@ -37,6 +37,8 @@ use Webkul\Core\Repositories\SliderRepository; /** * loads the home page for the storefront + * + * @return \Illuminate\View\View */ public function index() { diff --git a/packages/Webkul/Shop/src/Http/Controllers/OnepageController.php b/packages/Webkul/Shop/src/Http/Controllers/OnepageController.php index 61bb2effe..052703c07 100755 --- a/packages/Webkul/Shop/src/Http/Controllers/OnepageController.php +++ b/packages/Webkul/Shop/src/Http/Controllers/OnepageController.php @@ -82,7 +82,7 @@ class OnepageController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { @@ -104,7 +104,7 @@ class OnepageController extends Controller /** * Return order short summary * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function summary() { @@ -170,7 +170,7 @@ class OnepageController extends Controller /** * Saves payment method. * - * @return \Illuminate\Http\Response + * @return \Illuminate\Http\JsonResponse */ public function savePayment() { diff --git a/packages/Webkul/Shop/src/Http/Controllers/OrderController.php b/packages/Webkul/Shop/src/Http/Controllers/OrderController.php index 734f7c35d..a254c056e 100644 --- a/packages/Webkul/Shop/src/Http/Controllers/OrderController.php +++ b/packages/Webkul/Shop/src/Http/Controllers/OrderController.php @@ -60,7 +60,7 @@ class OrderController extends Controller /** * Display a listing of the resource. * - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index() { @@ -71,7 +71,7 @@ class OrderController extends Controller * Show the view for the specified resource. * * @param int $id - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function view($id) { diff --git a/packages/Webkul/Shop/src/Http/Controllers/ProductController.php b/packages/Webkul/Shop/src/Http/Controllers/ProductController.php index 0e3c65891..02c1e000f 100755 --- a/packages/Webkul/Shop/src/Http/Controllers/ProductController.php +++ b/packages/Webkul/Shop/src/Http/Controllers/ProductController.php @@ -83,7 +83,7 @@ class ProductController extends Controller * Display a listing of the resource. * * @param string $slug - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function index($slug) { diff --git a/packages/Webkul/Shop/src/Http/Controllers/ReviewController.php b/packages/Webkul/Shop/src/Http/Controllers/ReviewController.php index f8c6ae89b..b27b2a1b9 100755 --- a/packages/Webkul/Shop/src/Http/Controllers/ReviewController.php +++ b/packages/Webkul/Shop/src/Http/Controllers/ReviewController.php @@ -57,7 +57,7 @@ class ReviewController extends Controller * Show the form for creating a new resource. * * @param string $slug - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function create($slug) { @@ -103,7 +103,7 @@ class ReviewController extends Controller * Display reviews of particular product. * * @param string $slug - * @return \Illuminate\Http\Response + * @return \Illuminate\View\View */ public function show($slug) { diff --git a/packages/Webkul/Shop/src/Http/Controllers/SearchController.php b/packages/Webkul/Shop/src/Http/Controllers/SearchController.php index 82be77aec..bd8a5389c 100755 --- a/packages/Webkul/Shop/src/Http/Controllers/SearchController.php +++ b/packages/Webkul/Shop/src/Http/Controllers/SearchController.php @@ -41,6 +41,8 @@ use Webkul\Product\Repositories\SearchRepository; /** * Index to handle the view loaded with the search results + * + * @return \Illuminate\View\View */ public function index() { diff --git a/packages/Webkul/Shop/src/Http/routes.php b/packages/Webkul/Shop/src/Http/routes.php index e40669488..0898dbf02 100755 --- a/packages/Webkul/Shop/src/Http/routes.php +++ b/packages/Webkul/Shop/src/Http/routes.php @@ -86,9 +86,6 @@ Route::group(['middleware' => ['web', 'locale', 'theme', 'currency']], function 'view' => 'shop::checkout.success' ])->name('shop.checkout.success'); - //Shop buynow button action - Route::get('buynow/{id}', 'Webkul\Shop\Http\Controllers\CartController@buyNow')->name('shop.product.buynow'); - //Shop buynow button action Route::get('move/wishlist/{id}', 'Webkul\Shop\Http\Controllers\CartController@moveToWishlist')->name('shop.movetowishlist'); diff --git a/packages/Webkul/Shop/src/Resources/assets/sass/app.scss b/packages/Webkul/Shop/src/Resources/assets/sass/app.scss index a1a348ba7..b8b7d57fd 100755 --- a/packages/Webkul/Shop/src/Resources/assets/sass/app.scss +++ b/packages/Webkul/Shop/src/Resources/assets/sass/app.scss @@ -402,10 +402,10 @@ input { } .sticker { - border-radius: 100px; + border-bottom-right-radius: 15px; position: absolute; - top: 20px; - left: 20px; + top: 15px; + left: 15px; text-transform: uppercase; padding: 4px 13px; font-size: 14px; @@ -1828,8 +1828,76 @@ section.product-detail { margin-bottom: 0; } + .checkbox { + display: inline-block; + } + a { float: right; + margin-top: 3px; + } + } + } + } + } + + .grouped-product-container { + .grouped-product-list { + padding: 15px 0; + border-top: solid 1px rgba(162, 162, 162, 0.2); + + ul { + li { + margin-bottom: 15px; + width: 100%; + display: inline-block; + + &:last-child { + margin-bottom: 0; + } + + &:first-child { + span { + font-weight: 600; + + &:last-child { + float: right; + width: 50px; + text-align: left; + } + } + } + + .name { + vertical-align: middle; + display: inline-block; + + .product-price { + margin-top: 5px; + margin-bottom: 0; + font-size: 14px; + + .special-price { + font-size: 16px; + } + } + } + + .qty { + float: right; + + .control-group { + display: inline-block; + max-width: 50px; + text-align: center; + margin-bottom: 0; + + .control { + margin: 0; + width: 100%; + text-align: center; + } + } } } } diff --git a/packages/Webkul/Shop/src/Resources/lang/en/app.php b/packages/Webkul/Shop/src/Resources/lang/en/app.php index e2116b2d6..78fa694c5 100755 --- a/packages/Webkul/Shop/src/Resources/lang/en/app.php +++ b/packages/Webkul/Shop/src/Resources/lang/en/app.php @@ -351,7 +351,9 @@ return [ 'less-quantity' => 'Quantity can not be less than one.', 'samples' => 'Samples', 'links' => 'Links', - 'sample' => 'Sample' + 'sample' => 'Sample', + 'name' => 'Name', + 'qty' => 'Qty' ], 'wishlist' => [ diff --git a/packages/Webkul/Shop/src/Resources/views/checkout/cart/index.blade.php b/packages/Webkul/Shop/src/Resources/views/checkout/cart/index.blade.php index d71a66e28..51f1e8070 100755 --- a/packages/Webkul/Shop/src/Resources/views/checkout/cart/index.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/checkout/cart/index.blade.php @@ -19,12 +19,9 @@
    @csrf @foreach ($cart->items as $key => $item) - type == "configurable") - $productBaseImage = $productImageHelper->getProductBaseImage($item->child->product); - else - $productBaseImage = $productImageHelper->getProductBaseImage($item->product); - ?> + @php + $productBaseImage = $item->product->getTypeInstance()->getBaseImage($item); + @endphp
    @@ -55,17 +52,12 @@ {!! view_render_event('bagisto.shop.checkout.cart.item.options.before', ['item' => $item]) !!} - @if ($item->type == 'configurable') - -
    - - {{ Cart::getProductAttributeOptionDetails($item->child->product)['html'] }} - -
    - @elseif ($item->type == 'downloadable') -
    + @if (isset($item->additional['attributes'])) +
    - Downloads : {{ $item->additional['link_lables'] }} + @foreach ($item->additional['attributes'] as $attribute) + {{ $attribute['attribute_name'] }} : {{ $attribute['option_label'] }} + @endforeach
    @endif diff --git a/packages/Webkul/Shop/src/Resources/views/checkout/cart/mini-cart.blade.php b/packages/Webkul/Shop/src/Resources/views/checkout/cart/mini-cart.blade.php index 36fbd0db2..2e74b9487 100755 --- a/packages/Webkul/Shop/src/Resources/views/checkout/cart/mini-cart.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/checkout/cart/mini-cart.blade.php @@ -42,12 +42,9 @@
    - type == "configurable") - $images = $productImageHelper->getProductBaseImage($item->child->product); - else - $images = $productImageHelper->getProductBaseImage($item->product); - ?> + @php + $images = $item->product->getTypeInstance()->getBaseImage($item); + @endphp
    @@ -60,15 +57,13 @@ {!! view_render_event('bagisto.shop.checkout.cart-mini.item.options.before', ['item' => $item]) !!} - - @if ($item->type == "configurable") -
    - {{ trim(Cart::getProductAttributeOptionDetails($item->child->product)['html']) }} -
    - @elseif ($item->type == 'downloadable') + + @if (isset($item->additional['attributes']))
    - Downloads : {{ $item->additional['link_lables'] }} + @foreach ($item->additional['attributes'] as $attribute) + {{ $attribute['attribute_name'] }} : {{ $attribute['option_label'] }} + @endforeach
    @endif diff --git a/packages/Webkul/Shop/src/Resources/views/checkout/onepage/review.blade.php b/packages/Webkul/Shop/src/Resources/views/checkout/onepage/review.blade.php index cf51c29ec..60ad84bc7 100755 --- a/packages/Webkul/Shop/src/Resources/views/checkout/onepage/review.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/checkout/onepage/review.blade.php @@ -66,12 +66,9 @@
    @foreach ($cart->items as $item) - - product; - - $productBaseImage = $productImageHelper->getProductBaseImage($product); - ?> + @php + $productBaseImage = $item->product->getTypeInstance()->getBaseImage($item); + @endphp
    @@ -83,7 +80,7 @@ {!! view_render_event('bagisto.shop.checkout.name.before', ['item' => $item]) !!}
    - {{ $product->name }} + {{ $item->product->name }}
    {!! view_render_event('bagisto.shop.checkout.name.after', ['item' => $item]) !!} @@ -112,23 +109,19 @@ {!! view_render_event('bagisto.shop.checkout.quantity.after', ['item' => $item]) !!} - @if ($product->type == 'configurable') - {!! view_render_event('bagisto.shop.checkout.options.before', ['item' => $item]) !!} + {!! view_render_event('bagisto.shop.checkout.options.before', ['item' => $item]) !!} + + @if (isset($item->additional['attributes'])) +
    + + @foreach ($item->additional['attributes'] as $attribute) + {{ $attribute['attribute_name'] }} : {{ $attribute['option_label'] }} + @endforeach -
    - {{ Cart::getProductAttributeOptionDetails($item->child->product)['html'] }}
    - - {!! view_render_event('bagisto.shop.checkout.options.after', ['item' => $item]) !!} - @elseif ($product->type == 'downloadable') - {!! view_render_event('bagisto.shop.checkout.downlodable_links.before', ['item' => $item]) !!} - -
    - Downloads : {{ $item->additional['link_lables'] }} -
    - - {!! view_render_event('bagisto.shop.checkout.downlodable_links.after', ['item' => $item]) !!} @endif + + {!! view_render_event('bagisto.shop.checkout.options.after', ['item' => $item]) !!}
    @endforeach diff --git a/packages/Webkul/Shop/src/Resources/views/customers/account/orders/view.blade.php b/packages/Webkul/Shop/src/Resources/views/customers/account/orders/view.blade.php index 7d2a9827d..b1d5c84c6 100755 --- a/packages/Webkul/Shop/src/Resources/views/customers/account/orders/view.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/customers/account/orders/view.blade.php @@ -66,15 +66,19 @@ @foreach ($order->items as $item) - {{ $item->type == 'configurable' ? $item->child->sku : $item->sku }} + {{ $item->getTypeInstance()->getOrderedItem($item)->sku }} {{ $item->name }} + + @if (isset($item->additional['attributes'])) +
    + + @foreach ($item->additional['attributes'] as $attribute) + {{ $attribute['attribute_name'] }} : {{ $attribute['option_label'] }} + @endforeach - @if ($html = $item->getOptionDetailHtml()) -

    {{ $html }}

    - @elseif ($item->type == 'downloadable') -

    Downloads : {{ $item->getDownloadableDetailHtml() }}

    +
    @endif {{ core()->formatPrice($item->price, $order->order_currency_code) }} @@ -200,7 +204,7 @@ @foreach ($invoice->items as $item) - {{ $item->child ? $item->child->sku : $item->sku }} + {{ $item->getTypeInstance()->getOrderedItem($item)->sku }} {{ $item->name }} {{ core()->formatPrice($item->price, $order->order_currency_code) }} {{ $item->qty }} diff --git a/packages/Webkul/Shop/src/Resources/views/customers/account/wishlist/wishlist.blade.php b/packages/Webkul/Shop/src/Resources/views/customers/account/wishlist/wishlist.blade.php index dd14fa780..3df960b90 100755 --- a/packages/Webkul/Shop/src/Resources/views/customers/account/wishlist/wishlist.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/customers/account/wishlist/wishlist.blade.php @@ -1,72 +1,86 @@ @extends('shop::layouts.master') @section('content-wrapper') +