From 8c12e35621ac9533ba9c7a89a1bbbab6e7c19fa4 Mon Sep 17 00:00:00 2001 From: prashant-webkul Date: Fri, 16 Nov 2018 17:21:10 +0530 Subject: [PATCH] Cart Refactored, Email Subscription, UI Bug Fix, Wishlist Order & Invoices Datagrid --- config/app.php | 3 +- config/cache.php | 16 +- .../src/DataGrids/OrderInvoicesDataGrid.php | 127 +++ .../src/DataGrids/OrderShipmentsDataGrid.php | 127 +++ .../src/Providers/EventServiceProvider.php | 25 +- .../Admin/src/Resources/lang/en/app.php | 2 + .../views/sales/invoices/index.blade.php | 23 + .../views/sales/shipments/index.blade.php | 23 + packages/Webkul/Checkout/src/Cart.php | 770 ++++++------------ .../src/Repositories/CartItemRepository.php | 12 - .../Core/src/Models/SubscribersList.php | 22 + .../SubscribersListRepository.php | 35 + .../Http/Controllers/WishlistController.php | 96 +-- .../Webkul/Customer/src/Models/Customer.php | 32 +- .../Webkul/Customer/src/Models/Wishlist.php | 4 +- .../Customer/src/Resources/lang/en/app.php | 7 +- .../src/Http/Controllers/CartController.php | 32 +- .../Controllers/SubscriptionController.php | 100 ++- packages/Webkul/Shop/src/Http/routes.php | 13 +- .../Shop/src/Mail/SubscriptionEmail.php | 31 + .../src/Resources/assets/sass/_variables.scss | 1 + .../Shop/src/Resources/assets/sass/app.scss | 81 +- .../Webkul/Shop/src/Resources/lang/en/app.php | 81 +- .../views/checkout/cart/index.blade.php | 17 +- .../customers/account/address/index.blade.php | 4 +- .../customers/account/orders/index.blade.php | 12 +- .../account/reviews/reviews.blade.php | 2 +- .../account/wishlist/wishlist.blade.php | 28 +- .../customer/subscription-email.blade.php | 18 + .../views/layouts/footer/footer.blade.php | 13 +- .../Resources/views/layouts/master.blade.php | 3 + .../views/products/list/card.blade.php | 4 +- .../views/products/reviews/index.blade.php | 2 +- .../views/datagrid/filters.blade.php | 4 +- 34 files changed, 1072 insertions(+), 698 deletions(-) create mode 100644 packages/Webkul/Admin/src/DataGrids/OrderInvoicesDataGrid.php create mode 100644 packages/Webkul/Admin/src/DataGrids/OrderShipmentsDataGrid.php create mode 100644 packages/Webkul/Admin/src/Resources/views/sales/invoices/index.blade.php create mode 100644 packages/Webkul/Admin/src/Resources/views/sales/shipments/index.blade.php create mode 100644 packages/Webkul/Core/src/Models/SubscribersList.php create mode 100644 packages/Webkul/Core/src/Repositories/SubscribersListRepository.php create mode 100644 packages/Webkul/Shop/src/Mail/SubscriptionEmail.php create mode 100644 packages/Webkul/Shop/src/Resources/views/emails/customer/subscription-email.blade.php diff --git a/config/app.php b/config/app.php index fc2887b37..e76af059d 100644 --- a/config/app.php +++ b/config/app.php @@ -140,11 +140,10 @@ return [ | this array to grant expanded functionality to your applications. | */ + /* Code Editor - */ - 'editor' =>'vscode', diff --git a/config/cache.php b/config/cache.php index fa12e5e4f..49d1dad9e 100644 --- a/config/cache.php +++ b/config/cache.php @@ -69,8 +69,20 @@ return [ ], 'redis' => [ - 'driver' => 'redis', - 'connection' => 'default', + + 'client' => 'predis', + + 'clusters' => [ + 'default' => [ + [ + 'host' => env('REDIS_HOST', 'localhost'), + 'password' => env('REDIS_PASSWORD', null), + 'port' => env('REDIS_PORT', 6379), + 'database' => 0, + ], + ], + ], + ], ], diff --git a/packages/Webkul/Admin/src/DataGrids/OrderInvoicesDataGrid.php b/packages/Webkul/Admin/src/DataGrids/OrderInvoicesDataGrid.php new file mode 100644 index 000000000..92c735b4c --- /dev/null +++ b/packages/Webkul/Admin/src/DataGrids/OrderInvoicesDataGrid.php @@ -0,0 +1,127 @@ + @prashant-webkul + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ + +class OrderInvoicesDataGrid +{ + /** + * The Order invoices Data Grid implementation. + * + * @var OrderInvoicesDataGrid + * for invoices of orders + */ + public function createOrderInvoicesDataGrid() + { + + return DataGrid::make([ + 'name' => 'invoices', + 'table' => 'invoices as inv', + 'select' => 'inv.id', + 'perpage' => 10, + 'aliased' => false, + + 'massoperations' =>[ + [ + 'route' => route('admin.datagrid.delete'), + 'method' => 'DELETE', + 'label' => 'Delete', + 'type' => 'button', + ], + ], + + 'actions' => [ + // [ + // 'type' => 'View', + // 'route' => route('admin.datagrid.delete'), + // 'confirm_text' => 'Do you really want to do this?', + // 'icon' => 'icon pencil-lg-icon', + // ], [ + // 'type' => 'Delete', + // 'route' => route('admin.datagrid.delete'), + // 'confirm_text' => 'Do you really want to do this?', + // 'icon' => 'icon trash-icon', + // ] + ], + + 'join' => [], + + //use aliasing on secodary columns if join is performed + + 'columns' => [ + [ + 'name' => 'inv.id', + 'alias' => 'invid', + 'type' => 'number', + 'label' => 'ID', + 'sortable' => true + ], [ + 'name' => 'inv.state', + 'alias' => 'invstate', + 'type' => 'number', + 'label' => 'State', + 'sortable' => true + ], [ + 'name' => 'inv.total_qty', + 'alias' => 'invtotalqty', + 'type' => 'number', + 'label' => 'Quantity', + 'sortable' => true + ], [ + 'name' => 'inv.grand_total', + 'alias' => 'invgrandtotal', + 'type' => 'number', + 'label' => 'Grand Total', + 'sortable' => true + ] + ], + + 'filterable' => [ + [ + 'column' => 'inv.id', + 'alias' => 'invid', + 'type' => 'number', + 'label' => 'ID', + ] + ], + //don't use aliasing in case of searchables + + 'searchable' => [ + // [ + // 'column' => 'or.id', + // 'alias' => 'orderid', + // 'type' => 'number', + // 'label' => 'ID', + // ] + ], + + //list of viable operators that will be used + 'operators' => [ + 'eq' => "=", + 'lt' => "<", + 'gt' => ">", + 'lte' => "<=", + 'gte' => ">=", + 'neqs' => "<>", + 'neqn' => "!=", + 'like' => "like", + 'nlike' => "not like", + ], + // 'css' => [] + ]); + } + + public function render() + { + return $this->createOrderInvoicesDataGrid()->render(); + } +} \ No newline at end of file diff --git a/packages/Webkul/Admin/src/DataGrids/OrderShipmentsDataGrid.php b/packages/Webkul/Admin/src/DataGrids/OrderShipmentsDataGrid.php new file mode 100644 index 000000000..bbd835aaa --- /dev/null +++ b/packages/Webkul/Admin/src/DataGrids/OrderShipmentsDataGrid.php @@ -0,0 +1,127 @@ + @prashant-webkul + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ + +class OrderShipmentsDataGrid +{ + /** + * The Order Shipments Data Grid implementation. + * + * @var OrderShipmentsDataGrid + * for shipments of orders + */ + public function createOrderShipmentsDataGrid() + { + + return DataGrid::make([ + 'name' => 'shipments', + 'table' => 'shipments as ship', + 'select' => 'ship.id', + 'perpage' => 10, + 'aliased' => false, + + 'massoperations' =>[ + [ + 'route' => route('admin.datagrid.delete'), + 'method' => 'DELETE', + 'label' => 'Delete', + 'type' => 'button', + ], + ], + + 'actions' => [ + // [ + // 'type' => 'View', + // 'route' => route('admin.datagrid.delete'), + // 'confirm_text' => 'Do you really want to do this?', + // 'icon' => 'icon pencil-lg-icon', + // ], [ + // 'type' => 'Delete', + // 'route' => route('admin.datagrid.delete'), + // 'confirm_text' => 'Do you really want to do this?', + // 'icon' => 'icon trash-icon', + // ] + ], + + 'join' => [], + + //use aliasing on secodary columns if join is performed + + 'columns' => [ + [ + 'name' => 'ship.id', + 'alias' => 'shipID', + 'type' => 'number', + 'label' => 'ID', + 'sortable' => true + ], [ + 'name' => 'ship.status', + 'alias' => 'shipstatus', + 'type' => 'string', + 'label' => 'Status', + 'sortable' => true, + 'wrapper' => function ($value) { + if($value == 'processing') + return 'Processing'; + else if($value == 'completed') + return 'Completed'; + else if($value == "canceled") + return 'Canceled'; + else if($value == "closed") + return 'Closed'; + else if($value == "pending") + return 'Pending'; + }, + ], + ], + + 'filterable' => [ + [ + 'column' => 'ship.id', + 'alias' => 'shipID', + 'type' => 'number', + 'label' => 'ID', + ] + ], + //don't use aliasing in case of searchables + + 'searchable' => [ + // [ + // 'column' => 'or.id', + // 'alias' => 'orderid', + // 'type' => 'number', + // 'label' => 'ID', + // ] + ], + + //list of viable operators that will be used + 'operators' => [ + 'eq' => "=", + 'lt' => "<", + 'gt' => ">", + 'lte' => "<=", + 'gte' => ">=", + 'neqs' => "<>", + 'neqn' => "!=", + 'like' => "like", + 'nlike' => "not like", + ], + // 'css' => [] + ]); + } + + public function render() + { + return $this->createOrderShipmentsDataGrid()->render(); + } +} \ No newline at end of file diff --git a/packages/Webkul/Admin/src/Providers/EventServiceProvider.php b/packages/Webkul/Admin/src/Providers/EventServiceProvider.php index ee19a87b3..453539d2c 100644 --- a/packages/Webkul/Admin/src/Providers/EventServiceProvider.php +++ b/packages/Webkul/Admin/src/Providers/EventServiceProvider.php @@ -29,20 +29,19 @@ class EventServiceProvider extends ServiceProvider 'route' => 'admin.sales.orders.index', 'sort' => 1, 'icon-class' => '', + ], [ + 'key' => 'sales.shipments', + 'name' => 'Shipments', + 'route' => 'admin.sales.shipments.index', + 'sort' => 2, + 'icon-class' => '', + ], [ + 'key' => 'sales.invoices', + 'name' => 'Invoices', + 'route' => 'admin.sales.invoices.index', + 'sort' => 3, + 'icon-class' => '', ], - // [ - // 'key' => 'sales.shipments', - // 'name' => 'Shipments', - // 'route' => 'admin.sales.orders.index', - // 'sort' => 2, - // 'icon-class' => '', - // ], [ - // 'key' => 'sales.invoices', - // 'name' => 'Invoices', - // 'route' => 'admin.sales.orders.index', - // 'sort' => 3, - // 'icon-class' => '', - // ], [ 'key' => 'catalog', 'name' => 'Catalog', diff --git a/packages/Webkul/Admin/src/Resources/lang/en/app.php b/packages/Webkul/Admin/src/Resources/lang/en/app.php index f7b59bb11..6619618d3 100644 --- a/packages/Webkul/Admin/src/Resources/lang/en/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/en/app.php @@ -144,6 +144,7 @@ return [ 'cancel-confirm-msg' => 'Are you sure you want to cancel this order ?' ], 'invoices' => [ + 'title' => 'Invoices', 'id' => 'Id', 'invoice-id' => 'Invoice Id', 'date' => 'Invoice Date', @@ -164,6 +165,7 @@ return [ 'order-date' => 'Order Date' ], 'shipments' => [ + 'title' => 'Shipments', 'id' => 'Id', 'date' => 'Shipment Date', 'order-id' => 'Order Id', diff --git a/packages/Webkul/Admin/src/Resources/views/sales/invoices/index.blade.php b/packages/Webkul/Admin/src/Resources/views/sales/invoices/index.blade.php new file mode 100644 index 000000000..038e4812b --- /dev/null +++ b/packages/Webkul/Admin/src/Resources/views/sales/invoices/index.blade.php @@ -0,0 +1,23 @@ +@extends('admin::layouts.content') + +@section('page_title') + {{ __('admin::app.sales.invoices.title') }} +@stop + +@section('content') +
+ + +
+ @inject('orderInvoicesGrid', 'Webkul\Admin\DataGrids\OrderInvoicesDataGrid') + {!! $orderInvoicesGrid->render() !!} +
+
+@stop \ No newline at end of file diff --git a/packages/Webkul/Admin/src/Resources/views/sales/shipments/index.blade.php b/packages/Webkul/Admin/src/Resources/views/sales/shipments/index.blade.php new file mode 100644 index 000000000..64e99c112 --- /dev/null +++ b/packages/Webkul/Admin/src/Resources/views/sales/shipments/index.blade.php @@ -0,0 +1,23 @@ +@extends('admin::layouts.content') + +@section('page_title') + {{ __('admin::app.sales.shipments.title') }} +@stop + +@section('content') +
+ + +
+ @inject('orderShipmentsGrid', 'Webkul\Admin\DataGrids\OrderShipmentsDataGrid') + {!! $orderShipmentsGrid->render() !!} +
+
+@stop \ No newline at end of file diff --git a/packages/Webkul/Checkout/src/Cart.php b/packages/Webkul/Checkout/src/Cart.php index 48d68e0af..57ae232d6 100644 --- a/packages/Webkul/Checkout/src/Cart.php +++ b/packages/Webkul/Checkout/src/Cart.php @@ -70,6 +70,11 @@ class Cart { */ protected $wishlist; + /** + * Suppress the session flash messages + */ + protected $suppressFlash; + /** * Create a new controller instance. * @@ -104,21 +109,150 @@ class Cart { $this->taxCategory = $taxCategory; $this->wishlist = $wishlist; + + $this->suppressFlash = false; } /** - * Prepare the other data for the product to be success. + * Create new cart instance. * * @param integer $id - * @param array $data + * @param array $data * - * @return array + * @return Boolean */ - public function prepareItemData($productId, $data) + public function create($id, $data, $qty = 1) { - $product = $this->product->findOneByField('id', $productId); + $cartData = [ + 'channel_id' => core()->getCurrentChannel()->id, - //Check if the product's information is proper or not. + 'global_currency_code' => core()->getBaseCurrencyCode(), + + 'base_currency_code' => core()->getBaseCurrencyCode(), + + 'channel_currency_code' => core()->getChannelBaseCurrencyCode(), + + 'cart_currency_code' => core()->getCurrentCurrencyCode(), + 'items_count' => 1 + ]; + + //Authentication details + if(auth()->guard('customer')->check()) { + $cartData['customer_id'] = auth()->guard('customer')->user()->id; + $cartData['is_guest'] = 0; + $cartData['customer_first_name'] = auth()->guard('customer')->user()->first_name; + $cartData['customer_last_name'] = auth()->guard('customer')->user()->last_name; + $cartData['customer_email'] = auth()->guard('customer')->user()->email; + } else { + $cartData['is_guest'] = 1; + } + + $result = $this->cart->create($cartData); + + $this->putCart($result); + + if($result) { + if($this->createItem($id, $data)) + return true; + else + return false; + } else { + session()->flash('error', trans('shop::app.checkout.cart.create-error')); + } + } + + /** + * Add Items in a cart with some cart and item details. + * + * @param integer $id + * @param array $data + * + * @return void + */ + public function add($id, $data) { + $cart = $this->getCart(); + + if($cart != null) { + $ifExists = $this->checkIfItemExists($id, $data); + + if($ifExists) { + $item = $this->cartItem->findOneByField('id', $ifExists); + + $data['quantity'] = $data['quantity'] + $item->quantity; + + $result = $this->updateItem($id, $data, $ifExists); + } else { + $result = $this->createItem($id, $data); + } + + session()->flash('success', trans('shop::checkout.cart.success')); + + return true; + } else { + $this->create($id, $data); + } + } + + /** + * 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->product->findOnebyField('id', $id); + + if($product->type == 'configurable') { + $variant = $this->product->findOneByField('id', $data['selected_configurable_option']); + + if($item->child->product_id == $data['selected_configurable_option']) { + 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) + { + $product = $parentProduct = $configurable = false; + $product = $this->product->findOneByField('id', $id); + + if($product->type == 'configurable') { + $parentProduct = $this->product->findOneByField('id', $data['selected_configurable_option']); + + $canAdd = $parentProduct->haveSufficientQuantity($data['quantity']); + + if(!$canAdd) { + session()->flash('warning', 'insuff qty'); + + return false; + } + + $configurable = true; + } else { + $canAdd = $product->haveSufficientQuantity($data['quantity']); + + if(!$canAdd) { + session()->flash('warning', 'insuff qty'); + + 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')); @@ -133,285 +267,134 @@ class Cart { $child = $childData = null; $additional = []; - if($product->type == 'configurable') { - $child = $this->product->findOneByField('id', $data['selected_configurable_option']); + $price = ($product->type == 'configurable' ? $parentProduct->price : $product->price); + $weight = ($product->type == 'configurable' ? $parentProduct->weight : $product->weight); - $additional = $this->getProductAttributeOptionDetails($child); + $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 + ]; + + if($configurable){ + $parentData['type'] = $product['type']; + $parentData['product_id'] = $product['id']; + $parentData['additional'] = $data; + } else { + $parentData['type'] = $product['type']; + $parentData['product_id'] = $product['id']; + $parentData['additional'] = $data; + } + + if($configurable) { + $additional = $this->getProductAttributeOptionDetails($parentProduct); unset($additional['html']); $additional['request'] = $data; $additional['variant_id'] = $data['selected_configurable_option']; - $childData = [ - 'product_id' => $data['selected_configurable_option'], - 'sku' => $child->sku, - 'name' => $child->name, - 'type' => 'simple' - ]; + $childData['product_id'] = (int)$data['selected_configurable_option']; + $childData['sku'] = $parentProduct->sku; + $childData['name'] = $parentProduct->name; + $childData['type'] = 'simple'; + $childData['cart_id'] = $this->getCart()->id; } - $price = ($product->type == 'configurable' ? $child->price : $product->price); + $result = $this->cartItem->create($parentData); - $parentData = [ - 'sku' => $product->sku, - 'product_id' => $productId, - 'quantity' => $data['quantity'], - 'type' => $product->type, - 'name' => $product->name, - 'price' => core()->convertPrice($price), - 'base_price' => $price, - 'total' => core()->convertPrice($price * $data['quantity']), - 'base_total' => $price * $data['quantity'], - 'weight' => $weight = ($product->type == 'configurable' ? $child->weight : $product->weight), - 'total_weight' => $weight * $data['quantity'], - 'base_total_weight' => $weight * $data['quantity'], - 'additional' => $additional - ]; - - return ['parent' => $parentData, 'child' => $childData]; - } - - /** - * Add Items in a cart with some cart and item details. - * - * @param integer $id - * @param array $data - * - * @return void - */ - public function add($id, $data, $prepared = false, $preparedData = []) { - // dd($id, $data, $prepared, $preparedData); - if($prepared == false) { - $itemData = $this->prepareItemData($id, $data); - } else { - $itemData = $preparedData; + if ($childData != null) { + $childData['parent_id'] = $result->id; + $this->cartItem->create($childData); } - if(!$itemData) { + if($result) + return true; + else return false; - } - - if($cart = $this->getCart()) { - if($prepared == true) { - $product = $this->product->find($preparedData['parent']['product_id']); - } else { - $product = $this->product->find($id); - } - - $cartItems = $cart->items; - - //check the isset conditions as collection empty object will mislead the condition and error handling case. - if(isset($cartItems) && $cartItems->count()) { - //for previously added items - foreach($cartItems as $cartItem) { - if($product->type == "simple") { - if($cartItem->product_id == $id) { - $prevQty = $cartItem->quantity; - $newQty = $data['quantity']; - - $canBe = $this->canAddOrUpdate($cartItem->id, $prevQty + $newQty); - - if($canBe == false) { - session()->flash('warning', trans('shop::app.checkout.cart.quantity.inventory_warning')); - - return false; - } - - $cartItem->update([ - 'quantity' => $prevQty + $newQty, - 'total' => core()->convertPrice($cartItem->price * ($prevQty + $newQty)), - 'base_total' => $cartItem->price * ($prevQty + $newQty) - ]); - - session()->flash('success', trans('shop::app.checkout.cart.quantity.success')); - - return true; - } - } else if($product->type == "configurable") { - if ($cartItem->type == "configurable") { - $temp = $this->cartItem->findOneByField('parent_id', $cartItem->id); - - if($temp->product_id == $data['selected_configurable_option']) { - $child = $temp->child; - - $parent = $cartItem; - $parentPrice = $parent->price; - - $prevQty = $parent->quantity; - $newQty = $data['quantity']; - - $canBe = $this->canAddOrUpdate($cartItem->child->id, $prevQty + $newQty); - - if($canBe == false) { - session()->flash('warning', trans('shop::app.checkout.cart.quantity.inventory_warning')); - - return false; - } - - $parent->update([ - 'quantity' => $prevQty + $newQty, - 'total' => core()->convertPrice($parentPrice * ($prevQty + $newQty)), - 'base_total' => $parentPrice * ($prevQty + $newQty) - ]); - - session()->flash('success', trans('shop::app.checkout.cart.quantity.success')); - - return true; - } - } - } - } - - //for new items - if($product->type == "configurable") { - $canAdd = $this->canAdd($itemData['child']['product_id'], 1); - - if($canAdd == false) { - session()->flash('warning', trans('shop::app.checkout.cart.quantity.inventory_warning')); - - return false; - } - - $parent = $cart->items()->create($itemData['parent']); - - $itemData['child']['parent_id'] = $parent->id; - - $cart->items()->create($itemData['child']); - } else if($product->type != "configurable") { - $canAdd = $this->canAdd($itemData['parent']['product_id'], 1); - - if($canAdd == false) { - session()->flash('warning', trans('shop::app.checkout.cart.quantity.inventory_warning')); - - return false; - } - $parent = $cart->items()->create($itemData['parent']); - } - - session()->flash('success', trans('shop::app.checkout.cart.item.success')); - - return $cart; - } else { - //rare case of accidents - if(isset($cart)) { - $this->cart->delete($cart->id); - } else { - if($prepared == false) { - return $this->createNewCart($id, $data); - } - else { - return $this->createNewCart($id, $data, true, $preparedData); - } - - } - } - } else { - if($prepared == false) { - return $this->createNewCart($id, $data); - } - else { - return $this->createNewCart($id, $data, true, $preparedData); - } - } } /** - * Create new cart instance with the current item success. + * Update the cartItem on cart checkout page and if already added item is added again * - * @param integer $id - * @param array $data - * - * @return Booleans + * @return boolean */ - public function createNewCart($id, $data, $prepared = false, $preparedData = []) { - // dd($id, $data, $prepared,$preparedData); - if($prepared == false) { - if(isset($data['selected_configurable_option'])) { - $canAdd = $this->canAdd($data['selected_configurable_option'], $data['quantity']); - } else { - $canAdd = $this->canAdd($id, $data['quantity']); - } + public function updateItem($id, $data, $itemId) + { + $item = $this->cartItem->findOneByField('id', $itemId); - if(!$canAdd) { + if($item->type == 'configurable') { + $product = $this->product->findOneByField('id', $item->child->product_id); + + if(!$product->haveSufficientQuantity($data['quantity'])) { session()->flash('warning', trans('shop::app.checkout.cart.quantity.inventory_warning')); return false; } - - $itemData = $this->prepareItemData($id, $data); } else { - $itemData = $preparedData; - } + $product = $this->product->findOneByField('id', $item->product_id); - //if the item data is not valid to be processed it will be returning false - if($itemData == false) { - return false; - } + if(!$product->haveSufficientQuantity($data['quantity'])) { + session()->flash('warning', trans('shop::app.checkout.cart.quantity.inventory_warning')); - $cartData['channel_id'] = core()->getCurrentChannel()->id; - - //auth user details else they will be set when the customer is guest - if(auth()->guard('customer')->check()) { - $cartData['customer_id'] = auth()->guard('customer')->user()->id; - $cartData['is_guest'] = 0; - $cartData['customer_first_name'] = auth()->guard('customer')->user()->first_name; - $cartData['customer_last_name'] = auth()->guard('customer')->user()->last_name; - $cartData['customer_email'] = auth()->guard('customer')->user()->email; - } else { - $cartData['is_guest'] = 1; - } - - //set the currency column with the respective currency - $cartData['global_currency_code'] = core()->getBaseCurrencyCode(); - $cartData['base_currency_code'] = core()->getBaseCurrencyCode(); - $cartData['channel_currency_code'] = core()->getChannelBaseCurrencyCode(); - $cartData['cart_currency_code'] = core()->getCurrentCurrencyCode(); - //set the cart items and quantity - $cartData['items_count'] = 1; - - if($prepared == false) { - $cartData['items_qty'] = $data['quantity']; - } else { - $cartData['items_qty'] = 1; - } - - //create the cart instance in the database - if($cart = $this->cart->create($cartData)) { - $itemData['parent']['cart_id'] = $cart->id; - $product = $this->product->find($id); - - if ($product->type == "configurable") { - //parent item entry - if($prepared == false) { - $itemData['parent']['additional'] = json_encode($data); - } - - if($parent = $this->cartItem->create($itemData['parent'])) { - //child item entry - $itemData['child']['parent_id'] = $parent->id; - $itemData['child']['cart_id'] = $cart->id; - - if($child = $this->cartItem->create($itemData['child'])) { - $this->putCart($cart); - - session()->flash('success', trans('shop::app.checkout.cart.item.success')); - - return $cart; - } - } - } else if($product->type != "configurable") { - if($this->cartItem->create($itemData['parent'])) { - $this->putCart($cart); - - session()->flash('success', trans('shop::app.checkout.cart.item.success')); - - return $cart; - } + return false; } } - session()->flash('error', trans('shop::app.checkout.cart.item.error_add')); + $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) + ]); + + $this->collectTotals(); + + if($result) { + session()->flash('success', trans('shop::app.checkout.cart.quantity.success')); + + return true; + } else { + session()->flash('warning', trans('shop::app.checkout.cart.quantity.error')); + + return false; + } + + } + + /** + * Remove the item from the cart + * + * @return response + */ + public function removeItem($itemId) + { + if($cart = $this->getCart()) { + $this->cartItem->delete($itemId); + + //delete the cart instance if no items are there + if($cart->items()->get()->count() == 0) { + $this->cart->delete($cart->id); + + $this->deActivateCart(); + } + + session()->flash('success', trans('shop::app.checkout.cart.item.success-remove')); + + return true; + } return false; } @@ -455,23 +438,18 @@ class Cart { if($guestCartItem->type == "simple") { if($cartItem->product_id == $guestCartItem->product_id) { $prevQty = $cartItem->quantity; - $newQty = $guestCartItem->quantity; - $canBe = $this->canAddOrUpdate($cartItem->id, $prevQty + $newQty); + $product = $this->product->findOneByField('id', $cartItem->product_id); - if($canBe == false) { + if(!$product->haveSufficientQuantity($prevQty + $newQty)) { $this->cartItem->delete($guestCartItem->id); continue; } - $cartItem->update([ - 'quantity' => $prevQty + $newQty, - 'total' => core()->convertPrice($cartItem->price * ($prevQty + $newQty)), - 'base_total' => $cartItem->price * ($prevQty + $newQty), - 'total_weight' => $cartItem->weight * ($prevQty + $newQty), - 'base_total_weight' => $cartItem->weight * ($prevQty + $newQty) - ]); + $data['quantity'] = $newQty + $prevQty; + + $this->updateItem($cartItem->product_id, $data, $cartItem->id); $guestCartItems->forget($key); $this->cartItem->delete($guestCartItem->id); @@ -485,34 +463,26 @@ class Cart { $prevQty = $guestCartItem->quantity; $newQty = $cartItem->quantity; - $canBe = $this->canAddOrUpdate($cartItem->child->id, $prevQty + $newQty); + $product = $this->product->findOneByField('id', $cartItem->child->product_id); - if($canBe == false) { + if(!$product->haveSufficientQuantity($prevQty + $newQty)) { $this->cartItem->delete($guestCartItem->id); continue; } - $cartItem->update([ - 'quantity' => $prevQty + $newQty, - 'total' => core()->convertPrice($cartItem->price * ($prevQty + $newQty)), - 'base_total' => $cartItem->price * ($prevQty + $newQty), - 'total_weight' => $cartItem->weight * ($prevQty + $newQty), - 'base_total_weight' => $cartItem->weight * ($prevQty + $newQty) - ]); + $data['quantity'] = $newQty + $prevQty; + + $this->updateItem($cartItem->product_id, $data, $cartItem->id); $guestCartItems->forget($key); - //child will be deleted first - // $this->cartItem->delete($guestCartItemChild->id); - - //then parent will also delete the child if any $this->cartItem->delete($guestCartItem->id); } } } } - //now handle the products that are not deleted. + //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") { @@ -538,129 +508,6 @@ class Cart { } } - /** - * Update the cart on - * cart checkout page - */ - public function update($itemIds) - { - if($cart = $this->getCart()) { - $items = $cart->items; - - foreach($items as $item) { - foreach($itemIds['qty'] as $id => $quantity) { - if($id == $item->id) { - if($item->type == "configurable") { - $canBe = $this->canAddOrUpdate($item->child->id, $quantity); - - if($canBe == false) { - session()->flash('warning', trans('shop::app.checkout.cart.quantity.inventory_warning')); - - return $cart; - } - - $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) - ]); - } else { - $canBe = $this->canAddOrUpdate($id, $quantity); - - if($canBe == false) { - session()->flash('warning', trans('shop::app.checkout.cart.quantity.inventory_warning')); - - return $cart; - } - $prevQty = $item->quantity; - - $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) - ]); - } - } - } - } - $this->collectTotals(); - - session()->flash('success', trans('shop::app.checkout.cart.quantity.success')); - - return $cart; - } else { - session()->flash('warning', trans('shop::app.checkout.cart.integrity.missing_fields')); - - return false; - } - } - - /** - * Remove the item from the cart - * - * @return response - */ - public function removeItem($itemId) - { - if($cart = $this->getCart()) { - $this->cartItem->delete($itemId); - - //delete the cart instance if no items are there - if($cart->items()->get()->count() == 0) { - $this->cart->delete($cart->id); - - session()->forget('cart'); - - session()->flash('success', trans('shop::app.checkout.cart.item.success-remove')); - } - } - } - - /** - * Method to check if the product is available and its required quantity - * is available or not in the inventory sources. - * - * @param integer $id - * - * @return Array - */ - public function canAddOrUpdate($itemId, $quantity) - { - if ($quantity < 1) { - session()->flash('warning', trans('shop::app.checkout.cart.quantity.warning')); - - return false; - } - - $item = $this->cartItem->findOneByField('id', $itemId); - - if($item->product->haveSufficientQuantity($quantity)) { - return true; - } - - return false; - } - - /** - * Can Add the product or not will check the quantity for that particular product - * before creation of the cart. - * - * @return boolean - */ - public function canAdd($id, $qty) { - $product = $this->product->find($id); - - if($product->haveSufficientQuantity($qty)) { - return true; - } - - return false; - } - /** * Save cart * @@ -929,8 +776,8 @@ class Cart { $item->update([ 'price' => $item->product->price, 'base_price' => $item->product->price, - 'total' => core()->convertPrice($item->child->product->price * ($item->quantity)), - 'base_total' => $item->child->product->price * ($item->quantity), + 'total' => core()->convertPrice($item->product->price * ($item->quantity)), + 'base_total' => $item->product->price * ($item->quantity), ]); } } @@ -991,7 +838,7 @@ class Cart { * Checks if cart has any error * * @return boolean - */ + */ public function hasError() { if(!$this->getCart()) @@ -1135,106 +982,27 @@ class Cart { * * Move a wishlist item to cart */ - public function moveToCart($productId) { - $product = $this->product->find($productId); + public function moveToCart($wishlistItem) { + $product = $wishlistItem->product; - if($product->parent_id == null ||$product->parent_id == 'null') { - $data = [ - 'product' => $productId, - 'quantity' => 1, - ]; + if($product->type == 'simple') { + $data['quantity'] = 1; + $data['product'] = $wishlistItem->product->id; - $result = $this->add($productId, $data); + $result = $this->add($product->id, $data); - if($result instanceof Collection || $result == true) { - return true; + if($result) { + return 1; } else { - return false; - } - } else { - //in case the product added is a configurable product. - $result = $this->moveConfigurableFromWishlistToCart($product->parent_id, $product->id); - - if(is_array($result)) { - $data['_token'] = 'null'; - $data['quantity'] = 1; - $data['product'] = $product->parent_id; - $data['selected_configurable_option'] = $product->id; - - $moved = $this->add($product->parent_id, $data, true, $result); - - if(isset($moved)) { - return true; - } else { - return false; - } + return 0; } + } else if($product->type == 'configurable' && $product->parent_id == null) { + return -1; } } /** - * Move a configurable product from wishlist to cart. - * - * @return mixed - */ - public function moveConfigurableFromWishlistToCart($configurableproductId, $productId) { - // dd($configurableproductId, $productId); - $product = $this->product->find($configurableproductId); - - $canAdd = $this->product->find($productId)->haveSufficientQuantity(1); - - if(!$canAdd) { - session()->flash('warning', trans('shop::app.checkout.cart.quantity.inventory_warning')); - - return false; - } - - $child = $childData = null; - if($product->type == 'configurable') { - $child = $this->product->findOneByField('id', $productId); - - $childData = [ - 'product_id' => $productId, - 'sku' => $child->sku, - 'name' => $child->name, - 'type' => 'simple' - ]; - } - - $price = ($product->type == 'configurable' ? $child->price : $product->price); - - $productAddtionalData = $this->getProductAttributeOptionDetails($child); - - unset($productAddtionalData['html']); - - $additional = [ - 'request' => $childData, - 'variant_id' => $productId, - 'attributes' => $productAddtionalData['attributes'] - ]; - - $parentData = [ - 'sku' => $product->sku, - 'product_id' => $configurableproductId, - 'quantity' => 1, - 'type' => $product->type, - 'name' => $product->name, - 'price' => core()->convertPrice($price), - 'base_price' => $price, - 'total' => core()->convertPrice($price), - 'base_total' => $price, - 'weight' => $weight = ($product->type == 'configurable' ? $child->weight : $product->weight), - 'total_weight' => $weight, - 'base_total_weight' => $weight, - 'additional' => $additional - ]; - // dd(['parent' => $parentData, 'child' => $childData]); - return ['parent' => $parentData, 'child' => $childData]; - } - - /** - * 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 */ @@ -1253,7 +1021,7 @@ class Cart { $wishlist['product_id'] = $item->product_id; } else { $wishlist['product_id'] = $item->child->product_id; - $wishtlist['options'] = $item->addtional; + $wishtlist['options'] = $item->additional; } $shouldBe = $this->wishlist->findWhere(['customer_id' => auth()->guard('customer')->user()->id, 'product_id' => $wishlist['product_id']]); @@ -1268,10 +1036,12 @@ class Cart { if($cart->items()->count() == 0) $this->cart->delete($cart->id); - session()->flash('success', 'Item Move To Wishlist Successfully'); + 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; } } @@ -1283,7 +1053,7 @@ class Cart { * * @return response mixed */ - public function proceedForBuyNow($id) { + public function proceedToBuyNow($id) { $product = $this->product->findOneByField('id', $id); if($product->type == 'configurable') { diff --git a/packages/Webkul/Checkout/src/Repositories/CartItemRepository.php b/packages/Webkul/Checkout/src/Repositories/CartItemRepository.php index 8f7204432..c0c1f7e40 100644 --- a/packages/Webkul/Checkout/src/Repositories/CartItemRepository.php +++ b/packages/Webkul/Checkout/src/Repositories/CartItemRepository.php @@ -24,18 +24,6 @@ class CartItemRepository extends Repository return 'Webkul\Checkout\Models\CartItem'; } - /** - * @param array $data - * @return mixed - */ - - public function create(array $data) - { - $cartitems = $this->model->create($data); - - return $cartitems; - } - /** * @param array $data * @param $id diff --git a/packages/Webkul/Core/src/Models/SubscribersList.php b/packages/Webkul/Core/src/Models/SubscribersList.php new file mode 100644 index 000000000..972d70d3c --- /dev/null +++ b/packages/Webkul/Core/src/Models/SubscribersList.php @@ -0,0 +1,22 @@ + + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ +class SubscribersListRepository extends Repository +{ + /** + * Specify Model class name + * + * @return mixed + */ + function model() + { + return 'Webkul\Core\Models\SubscribersList'; + } + + + /** + * Delete a slider item and delete the image from the disk or where ever it is + * + * @return Boolean + */ + public function destroy($id) { + return $this->model->destroy($id); + } +} \ No newline at end of file diff --git a/packages/Webkul/Customer/src/Http/Controllers/WishlistController.php b/packages/Webkul/Customer/src/Http/Controllers/WishlistController.php index 7f6ce8bd2..25e8a3d95 100644 --- a/packages/Webkul/Customer/src/Http/Controllers/WishlistController.php +++ b/packages/Webkul/Customer/src/Http/Controllers/WishlistController.php @@ -51,17 +51,11 @@ class WishlistController extends Controller * Displays the listing resources if the customer having items in wishlist. */ public function index() { - $wishlists = $this->wishlist->findWhere([ - 'channel_id' => core()->getCurrentChannel()->id, - 'customer_id' => auth()->guard('customer')->user()->id] - ); - - $wishlistItems = array(); - - foreach($wishlists as $wishlist) { - array_push($wishlistItems, $this->wishlist->getItemsWithProducts($wishlist->id)); - } - + $wishlistItems = $this->wishlist->findWhere([ + 'channel_id' => core()->getCurrentChannel()->id, + 'customer_id' => auth()->guard('customer')->user()->id] + ); + // dd($wishlistItems->count()); return view($this->_config['view'])->with('items', $wishlistItems); } @@ -73,14 +67,6 @@ class WishlistController extends Controller public function add($itemId) { $product = $this->product->findOneByField('id', $itemId); - if($product->type == "configurable") { - $slug = $product->url_key; - - session()->flash('warning', trans('customer::app.wishlist.select-options')); - - return redirect()->route('shop.products.index', $slug); - } - $data = [ 'channel_id' => core()->getCurrentChannel()->id, 'product_id' => $itemId, @@ -112,9 +98,10 @@ class WishlistController extends Controller * @param integer $itemId */ public function remove($itemId) { + $result = $this->wishlist->deleteWhere(['customer_id' => auth()->guard('customer')->user()->id, 'channel_id' => core()->getCurrentChannel()->id, 'id' => $itemId]); - if($this->wishlist->deleteWhere(['customer_id' => auth()->guard('customer')->user()->id, 'channel_id' => core()->getCurrentChannel()->id, 'product_id' => $itemId])) { - session()->flash('success', trans('customer::app.wishlist.remove')); + if($result) { + session()->flash('success', trans('customer::app.wishlist.removed')); return redirect()->back(); } else { @@ -124,52 +111,59 @@ class WishlistController extends Controller } } - /** - * Add the configurable product - * to the wishlist. - * - * @return response - */ - public function addconfigurable($urlkey) { - session()->flash('warning', trans('Select options before adding to wishlist')); - return redirect()->route('shop.products.index', $urlkey); - } - /** * Function to move item from wishlist to cart. * * @param integer $itemId */ - public function moveAll() { - Cart::moveAllToCart(); - } + public function move($itemId) { + $wishlistItem = $this->wishlist->findOneByField('id', $itemId); + $result = Cart::moveToCart($wishlistItem); - /** - * Function to move item from wishlist to cart. - * - * @param integer $itemId - */ - public function move($productId) { - $result = Cart::moveToCart($productId); + if($result == 1) { + if($wishlistItem->delete()) { + session()->flash('success', trans('shop::app.wishlist.moved')); - if($result) { - $wishlist = $this->wishlist->findWhere(['customer_id' => auth()->guard('customer')->user()->id, 'product_id' => $productId]); - - if($this->wishlist->delete($wishlist[0]->id)) { Cart::collectTotals(); - session()->flash('success', 'Item Moved To Cart Successfully'); - return redirect()->back(); } else { - session()->flash('error', 'Item Cannot Be Moved To Cart Successfully'); + session()->flash('error', trans('shop::app.wishlist.move-error')); return redirect()->back(); } - } else { - Session('error', 'Cannot Add The Product To Wishlist Due To Unknown Problems, Please Checkback Later'); + } else if($result == 0) { + Session('error', trans('shop::app.wishlist.error')); return redirect()->back(); + } else if($result == -1) { + if(!$wishlistItem->delete()) { + session()->flash('error', trans('shop::app.wishlist.move-error')); + + return redirect()->back(); + } + + session()->flash('warning', trans('shop::app.checkout.cart.add-config-warning')); + + return redirect()->route('shop.products.index', $wishlistItem->product->url_key); } } + + /** + * Function to remove all of the items items in the customer's wishlist + * + * @return Mixed Response & Boolean + */ + public function removeAll() { + $wishlistItems = auth()->guard('customer')->user()->wishlist_items; + + if($wishlistItems->count() > 0) { + foreach($wishlistItems as $wishlistItem) { + $this->wishlist->delete($wishlistItem->id); + } + } + + session()->flash('success', trans('customer::app.wishlist.remove-all-success')); + return redirect()->back(); + } } \ No newline at end of file diff --git a/packages/Webkul/Customer/src/Models/Customer.php b/packages/Webkul/Customer/src/Models/Customer.php index c2d172903..0c0be560e 100644 --- a/packages/Webkul/Customer/src/Models/Customer.php +++ b/packages/Webkul/Customer/src/Models/Customer.php @@ -5,7 +5,9 @@ namespace Webkul\Customer\Models; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; use Webkul\Customer\Models\CustomerGroup; +use Webkul\Checkout\Models\Cart; use Webkul\Sales\Models\Order; +use Webkul\Customer\Models\Wishlist; use Webkul\Customer\Notifications\CustomerResetPassword; @@ -19,8 +21,6 @@ class Customer extends Authenticatable protected $hidden = ['password', 'remember_token']; - protected $with = ['customerGroup']; - /** * Get the customer full name. */ @@ -62,4 +62,32 @@ class Customer extends Authenticatable { return $this->hasOne(CustomerAddress::class, 'customer_id')->where('default_address', 1); } + + /** + * Customer's relation with wishlist items + */ + public function wishlist_items() { + return $this->hasMany(Wishlist::class, 'customer_id'); + } + + /** + * get all cart inactive cart instance of a customer + */ + public function carts() { + return $this->hasMany(Cart::class, 'customer_id'); + } + + /** + * get inactive cart inactive cart instance of a customer + */ + public function inactive_carts() { + return $this->hasMany(Cart::class, 'customer_id')->where('is_active', 0); + } + + /** + * get active cart inactive cart instance of a customer + */ + public function active_carts() { + return $this->hasMany(Cart::class, 'customer_id')->where('is_active', 1); + } } diff --git a/packages/Webkul/Customer/src/Models/Wishlist.php b/packages/Webkul/Customer/src/Models/Wishlist.php index 320dd3ca4..2d95bcf61 100644 --- a/packages/Webkul/Customer/src/Models/Wishlist.php +++ b/packages/Webkul/Customer/src/Models/Wishlist.php @@ -11,7 +11,7 @@ class Wishlist extends Model protected $fillable = ['channel_id', 'product_id', 'customer_id', 'item_options','moved_to_cart','shared','time_of_moving']; - public function item_wishlist() { - return $this->belongsTo(Product::class, 'product_id'); + public function product() { + return $this->hasOne(Product::class, 'id', 'product_id'); } } diff --git a/packages/Webkul/Customer/src/Resources/lang/en/app.php b/packages/Webkul/Customer/src/Resources/lang/en/app.php index cbd32f946..5f4c1f5ee 100644 --- a/packages/Webkul/Customer/src/Resources/lang/en/app.php +++ b/packages/Webkul/Customer/src/Resources/lang/en/app.php @@ -5,12 +5,13 @@ return [ 'success' => 'Item Successfully Added To Wishlist', 'failure' => 'Item Cannot Be Added To Wishlist', 'already' => 'Item Already Present In Your Wishlist', - 'removed' => 'Item Successfully Added To Wishlist', + 'removed' => 'Item Successfully Removed From Wishlist', 'remove-fail' => 'Item Cannot Be Removed From Wishlist', 'empty' => 'You Don\'t Have Any Items In Your Wishlist', - 'select-options' => 'Need To Select Options Before Adding To Wishlist' + 'select-options' => 'Need To Select Options Before Adding To Wishlist', + 'remove-all-success' => 'All The Items From Your Wishlist Have Been Removed', ], 'reviews' => [ - 'empty' => 'You Haven\'t Reviewed Any Product Yet' + 'empty' => 'You Have Not Reviewed Any Of Product Yet' ] ]; \ No newline at end of file diff --git a/packages/Webkul/Shop/src/Http/Controllers/CartController.php b/packages/Webkul/Shop/src/Http/Controllers/CartController.php index 3f35ba5b9..972af7ef3 100644 --- a/packages/Webkul/Shop/src/Http/Controllers/CartController.php +++ b/packages/Webkul/Shop/src/Http/Controllers/CartController.php @@ -85,11 +85,14 @@ class CartController extends Controller * * @return Mixed */ - public function add($id) { - $data = request()->input(); + $result = Cart::add($id, request()->except('_token')); - Cart::add($id, $data); + if($result) { + session()->flash('success', trans('shop::app.checkout.cart.item.success')); + } else { + session()->flash('success', trans('shop::app.checkout.cart.item.error-add')); + } Cart::collectTotals(); @@ -115,9 +118,9 @@ class CartController extends Controller * @return response */ public function updateBeforeCheckout() { - $data = request()->except('_token'); + $request = request()->except('_token'); - foreach($data['qty'] as $id => $quantity) { + foreach($request['qty'] as $id => $quantity) { if($quantity <= 0) { session()->flash('warning', trans('shop::app.checkout.cart.quantity.illegal')); @@ -125,7 +128,16 @@ class CartController extends Controller } } - Cart::update($data); + foreach($request['qty'] as $key => $value) { + $item = $this->cartItem->findOneByField('id', $key); + + $data['quantity'] = $value; + + Cart::updateItem($item->product_id, $data, $key); + + unset($item); + unset($data); + } Cart::collectTotals(); @@ -144,7 +156,7 @@ class CartController extends Controller } public function buyNow($id) { - $result = Cart::proceedForBuyNow($id); + $result = Cart::proceedToBuyNow($id); Cart::collectTotals(); @@ -164,14 +176,14 @@ class CartController extends Controller public function moveToWishlist($id) { $result = Cart::moveToWishlist($id); - if($result) { + if(!$result) { Cart::collectTotals(); - session()->flash('success', 'Item Successfully Moved To Wishlist'); + session()->flash('success', trans('shop::app.wishlist.moved')); return redirect()->back(); } else { - session()->flash('warning', 'Cannot move item to wishlist'); + session()->flash('warning', trans('shop::app.wishlist.move-error')); return redirect()->back(); } diff --git a/packages/Webkul/Shop/src/Http/Controllers/SubscriptionController.php b/packages/Webkul/Shop/src/Http/Controllers/SubscriptionController.php index 19a387dca..6e018dbcf 100644 --- a/packages/Webkul/Shop/src/Http/Controllers/SubscriptionController.php +++ b/packages/Webkul/Shop/src/Http/Controllers/SubscriptionController.php @@ -6,6 +6,10 @@ use Webkul\Shop\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Http\Response; +use Illuminate\Support\Facades\Mail; +use Webkul\Shop\Mail\SubscriptionEmail; +use Webkul\Customer\Repositories\CustomerRepository as Customer; +use Webkul\Core\Repositories\SubscribersListRepository as Subscription; /** * Subscription controller @@ -23,30 +27,112 @@ class SubscriptionController extends Controller */ protected $user; + /** + * Customer Repository object + * + * @var array + */ + protected $customer; + + /** + * Subscription List Repository object + * + * @var array + */ + protected $subscription; + /** * Create a new controller instance. * * @return void */ - public function __construct() + public function __construct(Customer $customer, Subscription $subscription) { $this->user = auth()->guard('customer')->user(); + $this->customer = $customer; + + $this->subscription = $subscription; + $this->_config = request('_config'); } /** - * Display a listing of the resource. - * - * @param string $slug - * @return \Illuminate\Http\Response + * Subscribes Customers and Guests to subscription mailing list and checks if already subscribed */ - public function index($email) + public function subscribe() { $this->validate(request(), [ - 'email' => 'email' + 'email' => 'email|required' ]); + $email = request()->input('email'); + $unique = 0; + + if(auth()->guard('customer')->check()) { + $unique = function() use($email) { + $count = $this->customer->findWhere(['email' => $email]); + + if($count->count() > 0 && $count->first()->subscribed_to_news_letter == 1) { + return 0; + } else { + return 1; + } + }; + } else { + $unique = $this->subscription->findWhere(['email' => $email]); + + if($unique->count() > 0) { + return 0; + } else { + return 1; + } + } + + if($unique()) { + $token = uniqid(); + $result = false; + + if(!auth()->guard('customer')->check()) { + $result = $this->subscription->create([ + 'email' => $email, + 'channel_id' => core()->getCurrentChannel()->id, + 'is_subscribed' => 1, + 'token' => $token + ]); + } else { + $user = auth()->guard('customer')->user(); + + $result = $user->update(['subscribed_to_news_letter' => 1]); + } + + if(!$result) { + session()->flash('error', trans('shop::app.subscription.not-subscribed')); + + return redirect()->back(); + } + + Mail::send(new SubscriptionEmail); + + session()->flash('success', trans('shop::app.subscription.subscribed')); + + return redirect()->back(); + } else { + session()->flash('error', trans('shop::app.subscription.already')); + + return redirect()->back(); + } + + return redirect()->back(); + } + + /** + * To unsubscribe from a the subcription list + * + * @var string $token + */ + public function unsubscribe($token) { + dd('unsubscribing'); } } diff --git a/packages/Webkul/Shop/src/Http/routes.php b/packages/Webkul/Shop/src/Http/routes.php index af5d9e48a..631e50315 100644 --- a/packages/Webkul/Shop/src/Http/routes.php +++ b/packages/Webkul/Shop/src/Http/routes.php @@ -7,6 +7,13 @@ Route::group(['middleware' => ['web', 'theme', 'locale', 'currency']], function 'view' => 'shop::home.index' ])->name('shop.home.index'); + //subscription + //subscribe + Route::get('/subscribe', 'Webkul\Shop\Http\Controllers\SubscriptionController@subscribe')->name('shop.subscribe'); + + //unsubscribe + Route::get('/unsubscribe', 'Webkul\Shop\Http\Controllers\SubscriptionController@unSubscribe')->name('shop.unsubscribe'); + //Store front header nav-menu fetch Route::get('/categories/{slug}', 'Webkul\Shop\Http\Controllers\CategoryController@index')->defaults('_config', [ 'view' => 'shop::products.index' @@ -157,12 +164,12 @@ Route::group(['middleware' => ['web', 'theme', 'locale', 'currency']], function //Customer Wishlist remove Route::get('wishlist/remove/{id}', 'Webkul\Customer\Http\Controllers\WishlistController@remove')->name('customer.wishlist.remove'); + //Customer Wishlist remove + Route::get('wishlist/removeall', 'Webkul\Customer\Http\Controllers\WishlistController@removeAll')->name('customer.wishlist.removeall'); + //Customer Wishlist move to cart Route::get('wishlist/move/{id}', 'Webkul\Customer\Http\Controllers\WishlistController@move')->name('customer.wishlist.move'); - //Customer Wishlist move all to cart - Route::get('wishlist/moveall', 'Webkul\Customer\Http\Controllers\WishlistController@moveAll')->name('customer.wishlist.moveall'); - //customer account Route::prefix('account')->group(function () { //Customer Dashboard Route diff --git a/packages/Webkul/Shop/src/Mail/SubscriptionEmail.php b/packages/Webkul/Shop/src/Mail/SubscriptionEmail.php new file mode 100644 index 000000000..342816e46 --- /dev/null +++ b/packages/Webkul/Shop/src/Mail/SubscriptionEmail.php @@ -0,0 +1,31 @@ + + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ +class SubscriptionEmail extends Mailable +{ + use Queueable, SerializesModels; + + /** + * Build the message. + * + * @return $this + */ + public function build() + { + return $this->to('prashant.singh852@webkul.com', auth()->guard('customer')->user()) + ->subject('subscription email') + ->view('shop::emails.customer.subscription-email')->with('data', ['content' => 'You Are Subscribed', 'token' => 'token']); + } +} diff --git a/packages/Webkul/Shop/src/Resources/assets/sass/_variables.scss b/packages/Webkul/Shop/src/Resources/assets/sass/_variables.scss index 0d51e30fc..70722de4b 100644 --- a/packages/Webkul/Shop/src/Resources/assets/sass/_variables.scss +++ b/packages/Webkul/Shop/src/Resources/assets/sass/_variables.scss @@ -8,6 +8,7 @@ $link-color: #2650EF; $background-color: #F2F2F2; $dark-background: #121212; $disc-price: #FF6472; +$danger-color: #FF6472; $disc-price-pro: #A5A5A5; $other-font-color: #5E5E5E; //shop variables ends here \ No newline at end of file diff --git a/packages/Webkul/Shop/src/Resources/assets/sass/app.scss b/packages/Webkul/Shop/src/Resources/assets/sass/app.scss index 111aa857e..e0e662b24 100644 --- a/packages/Webkul/Shop/src/Resources/assets/sass/app.scss +++ b/packages/Webkul/Shop/src/Resources/assets/sass/app.scss @@ -281,12 +281,14 @@ input { .media { height: 125px; - width: 125px; + width: 110px; } .info { - display: block; margin-left: 20px; + display: flex; + flex-direction: column; + justify-content: space-evenly; .stars .icon { height: 16px; @@ -299,7 +301,7 @@ input { height: 120px; display: flex; flex-direction: column; - justify-content: flex-start; + justify-content: space-between; align-items: center; a { @@ -488,7 +490,9 @@ input { .product-card { width: 100%; - display: inline-block; + display: flex; + flex-direction: row; + align-items: center; margin-bottom: 20px; .product-image { @@ -1963,6 +1967,12 @@ section.cart { a.link { margin-right: 15px; } + + div { + button { + margin-right: 15px; + } + } } } @@ -1989,11 +1999,14 @@ section.cart { .item-image { height: 160px; width: 160px; + box-shadow: 1px 1px 1px $border-color; } .item-details { display: flex; flex-direction: column; + justify-content: space-between; + width: 100%; .item-title { font-size: 18px; @@ -2016,38 +2029,45 @@ section.cart { } .misc { - display: inline-flex; - align-items: center; + display: flex; + width: 100%; + flex-direction: row; justify-content: flex-start; + align-items: flex-start; - div.qty-text { - color: $font-color-light; - margin-right: 10px; + .control-group { + font-size: 16px !important; + width: 220px; + margin: 0px; + + .wrap { + display: inline-flex; + align-items: center; + } + + label { + margin-right: 15px; + } + + .control { + height: 38px; + width: 60px; + border-radius: 3px; + text-align: center; + line-height: 38px; + } } - input.box { - height: 38px; - width: 60px; - font-size: 16px; - text-align: center; - line-height: 38px; - border: 1px solid $border-color; - border-radius: 3px; - margin-right: 30px; - border-radius: 0px; + .remove, .towishlist { + margin-top: 18px; + margin-right: 15px; } - - .remove { - color: $brand-color; - margin-right: 30px; - } - - .towishlist { - color : $brand-color; - } - } } + + .error-message { + color: $disc-price; + } } } @@ -2845,7 +2865,6 @@ section.review { width: 100%; .account-head { - margin-bottom: 20px; .back-icon { display: none; @@ -2888,7 +2907,7 @@ section.review { .address-card-1 { width: 260px; - border: 1px solid #E8E8E8; + border: 1px solid $border-color; display: flex; position: relative; flex-direction: row; diff --git a/packages/Webkul/Shop/src/Resources/lang/en/app.php b/packages/Webkul/Shop/src/Resources/lang/en/app.php index d6296683c..5c711b7e7 100644 --- a/packages/Webkul/Shop/src/Resources/lang/en/app.php +++ b/packages/Webkul/Shop/src/Resources/lang/en/app.php @@ -9,14 +9,14 @@ return [ 'header' => [ 'title' => 'Account', - 'dropdown-text' => 'Manage Cart, Orders & Wishlist.', + 'dropdown-text' => 'Manage Cart, Orders & Wishlist', 'sign-in' => 'Sign In', 'sign-up' => 'Sign Up', 'profile' => 'Profile', 'wishlist' => 'Wishlist', 'cart' => 'Cart', 'logout' => 'Logout', - 'search-text' => 'Search products here...' + 'search-text' => 'Search products here' ], 'footer' => [ @@ -26,8 +26,16 @@ return [ 'currency' => 'Currency', ], + 'subscription' => [ + 'unsubscribe' => 'Unsubcribe', + 'subscribe' => 'Subscribe', + 'subscribed' => 'You Are Now Subscribed To Subscription Emails', + 'not-subscribed' => 'You Cannot Be Subscribed To Subscription Emails, Try Again After Some time', + 'already' => 'You Are Already Subscribed To Our Subscription List' + ], + 'search' => [ - 'no-results' => 'No Results Found.', + 'no-results' => 'No Results Found', 'page-title' => 'Bagisto - Search', 'found-results' => 'Search Results Found', 'found-result' => 'Search Result Found' @@ -65,7 +73,7 @@ return [ ], 'login-text' => [ - 'no_account' => 'Don\'t have account', + 'no_account' => 'Do not have account', 'title' => 'Sign Up', ], @@ -77,7 +85,7 @@ return [ 'forgot_pass' => 'Forgot Password?', 'button_title' => 'Sign In', 'remember' => 'Remember Me', - 'footer' => '© Copyright 2018 Webkul Software, All rights reserved.' + 'footer' => '© Copyright 2018 Webkul Software, All rights reserved' ], 'forgot-password' => [ @@ -130,7 +138,7 @@ return [ 'title' => 'Address', 'add' => 'Add Address', 'edit' => 'Edit', - 'empty' => 'You don\'t have any saved addresses here, please create a new one by clicking the link below.', + 'empty' => 'You do not have any saved addresses here, please try to create it by clicking the link below', 'create' => 'Create Address', 'delete' => 'Delete', 'make-default' => 'Make Default', @@ -145,7 +153,7 @@ return [ 'address2' => 'Address Line 2', 'country' => 'Country', 'state' => 'State', - 'select-state' => 'Select a region, state or province.', + 'select-state' => 'Select a region, state or province', 'city' => 'City', 'postcode' => 'Postal Code', 'phone' => 'Phone', @@ -252,7 +260,7 @@ return [ 'choose-option' => 'Choose an option', 'sale' => 'Sale', 'new' => 'New', - 'empty' => 'No products available in this category.', + 'empty' => 'No products available in this category', 'add-to-cart' => 'Add To Cart', 'buy-now' => 'Buy Now', 'whoops' => 'Whoops!', @@ -266,11 +274,24 @@ return [ 'deleteall' => 'Delete All', 'moveall' => 'Move All Products To Cart', 'move-to-cart' => 'Move To Cart', - 'empty' => 'You Have No Items In Your Wishlist', + 'error' => 'Cannot Add The Product To Wishlist Due To Unknown Problems, Please Checkback Later', 'add' => 'Item Successfully Added To Wishlist', - 'remove' => 'Item Successfully Removed From Wishlist' + 'remove' => 'Item Successfully Removed From Wishlist', + 'moved' => 'Item Successfully Moved To Wishlist', + 'move-error' => 'Item Cannot Be Moved To Wishlist, Please Try Again Later', + 'success' => 'Item Successfully Added To Wishlist', + 'failure' => 'Item Cannot Be Added To Wishlist, Please Try Again Later', + 'already' => 'Item Already Present In Your Wishlist', + 'removed' => 'Item Successfully Removed From Wishlist', + 'remove-fail' => 'Item Cannot Be Removed From Wishlist, Please Try Again Later', + 'empty' => 'You do not have any items in your Wishlist', + 'remove-all-success' => 'All The Items From Your Wishlist Have Been Removed', ], + // 'reviews' => [ + // 'empty' => 'You Have Not Reviewed Any Of Product Yet' + // ] + 'buynow' => [ 'no-options' => 'Please Select Options Before Buying This Product' ], @@ -280,32 +301,36 @@ return [ 'cart' => [ 'integrity' => [ 'missing_fields' =>'Cart System Integrity Violation, Some Required Fields Missing', - 'missing_options' =>'Cart System Integrity Violation, Configurable product\'s options are missing', + 'missing_options' =>'Cart System Integrity Violation, Options Are Missing For Configurable Product', ], - + 'create-error' => 'Encountered Some Issue While Making Cart Instance', 'title' => 'Shopping Cart', - 'empty' => 'Your shopping cart is empty.', + 'empty' => 'Your Shopping Cart Is Empty', 'update-cart' => 'Update Cart', 'continue-shopping' => 'Continue Shopping', 'proceed-to-checkout' => 'Proceed To Checkout', 'remove' => 'Remove', 'remove-link' => 'Remove', 'move-to-wishlist' => 'Move to Wishlist', + 'move-to-wishlist-success' => 'Item Moved To Wishlist', + 'move-to-wishlist-error' => 'Cannot Move Item To Wishlist, Please Try Again Later', 'add-config-warning' => 'Please Select Option Before Adding To Cart', 'quantity' => [ 'quantity' => 'Quantity', - 'success' => 'Quantity successfully updated', - 'illegal' => 'Quantity cannot be lesser than one', - 'inventory_warning' => 'The requested quantity is not available, please try again later' + 'success' => 'Cart Item(s) Successfully Updated', + 'illegal' => 'Quantity Cannot Be Lesser Than One', + 'inventory_warning' => 'The Requested Quantity Is Not Available, Please Try Again Later', + 'error' => 'Cannot Update The Item(s) At The Moment, Please Try Again Later' ], 'item' => [ - 'error_remove' => 'No items to remove from the cart', - 'success' => 'Item successfully added to cart', - 'success_remove' => 'Item removed successfully', - 'error_add' => 'Item cannot be added to cart', + 'error_remove' => 'No Items To Remove From The Cart', + 'success' => 'Item Was Successfully Added To Cart', + 'success-remove' => 'Item Was Removed Successfully From The Cart', + 'error-add' => 'Item Cannot Be Added To Cart, Please Try Again Later', ], - 'quantity-error' => 'Requested quantity is not available.', - 'cart-subtotal' => 'Cart Subtotal' + 'quantity-error' => 'Requested Quantity Is Not Available', + 'cart-subtotal' => 'Cart Subtotal', + 'cart-remove-action' => 'Do you really want to do this ?' ], 'onepage' => [ @@ -323,7 +348,7 @@ return [ 'address2' => 'Address 2', 'city' => 'City', 'state' => 'State', - 'select-state' => 'Select a region, state or province.', + 'select-state' => 'Select a region, state or province', 'postcode' => 'Zip/Postcode', 'phone' => 'Telephone', 'country' => 'Country', @@ -355,7 +380,7 @@ return [ 'title' => 'Order successfully placed', 'thanks' => 'Thank you for your order!', 'order-id-info' => 'Your order id is #:order_id', - 'info' => 'We will email you, your order details and tracking information.' + 'info' => 'We will email you, your order details and tracking information' ] ], @@ -377,7 +402,7 @@ return [ 'shipping-handling' => 'Shipping & Handling', 'tax' => 'Tax', 'grand-total' => 'Grand Total', - 'final-summary' => 'Thanks for showing your intrest in our store. we will send you track number once it shiped.', + 'final-summary' => 'Thanks for showing your intrest in our store we will send you track number once it shiped', 'help' => 'If you need any kind of help please contact us at :support_email', 'thanks' => 'Thanks!' ], @@ -395,14 +420,14 @@ return [ ], 'forget-password' => [ 'dear' => 'Dear :name', - 'info' => 'You are receiving this email because we received a password reset request for your account.', + 'info' => 'You are receiving this email because we received a password reset request for your account', 'reset-password' => 'Reset Password', - 'final-summary' => 'If you did not request a password reset, no further action is required.', + 'final-summary' => 'If you did not request a password reset, no further action is required', 'thanks' => 'Thanks!' ] ], 'webkul' => [ - 'copy-right' => '© Copyright 2018 Webkul Software, All rights reserved.' + 'copy-right' => '© Copyright 2018 Webkul Software, All rights reserved' ] ]; \ No newline at end of file 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 e4876c18f..d4938ec8c 100644 --- a/packages/Webkul/Shop/src/Resources/views/checkout/cart/index.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/checkout/cart/index.blade.php @@ -59,13 +59,16 @@ @endif -
-
{{ __('shop::app.checkout.cart.quantity.quantity') }}
+
+
+ - + +
- @{{ errors.first('qty') }} + @{{ errors.first('qty[{!!$item->id!!}]') }} +
{{ __('shop::app.checkout.cart.remove-link') }} @@ -74,14 +77,14 @@ @if($item->parent_id != 'null' ||$item->parent_id != null) {{ __('shop::app.checkout.cart.move-to-wishlist') }} @else - {{ __('shop::app.checkout.cart.move-to-wishlist') }} + {{ __('shop::app.checkout.cart.move-to-wishlist') }} @endif
@if (!cart()->isItemHaveQuantity($item)) -
- {{ __('shop::app.checkout.cart.quantity-error') }} +
+ * {{ __('shop::app.checkout.cart.quantity-error') }}
@endif
diff --git a/packages/Webkul/Shop/src/Resources/views/customers/account/address/index.blade.php b/packages/Webkul/Shop/src/Resources/views/customers/account/address/index.blade.php index f6e0d5077..4913a6671 100644 --- a/packages/Webkul/Shop/src/Resources/views/customers/account/address/index.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/customers/account/address/index.blade.php @@ -35,14 +35,14 @@
@foreach($addresses as $address)
-
+
{{ auth()->guard('customer')->user()->name }} {{ $address->name }}
{{ $address->address1 }}, {{ $address->address2 ? $address->address2 . ',' : '' }}
{{ $address->city }}
{{ $address->state }}
{{ country()->name($address->country) }} {{ $address->postcode }}

- {{ __('shop::app.customer.account.address.index.contact') }} : {{ $address->phone }} + {{ __('shop::app.customer.account.address.index.contact') }} : {{ $address->phone }}