diff --git a/config/paymentmethods.php b/config/paymentmethods.php index af7fd8ec5..5c559b8a4 100644 --- a/config/paymentmethods.php +++ b/config/paymentmethods.php @@ -6,7 +6,7 @@ return [ 'title' => 'Cash On Delivery', 'description' => 'Cash On Delivery', 'class' => 'Webkul\Payment\Payment\CashOnDelivery', - 'order_status' => 'Pending', + 'order_status' => 'pending', 'active' => true ], @@ -15,7 +15,7 @@ return [ 'title' => 'Money Transfer', 'description' => 'Money Transfer', 'class' => 'Webkul\Payment\Payment\MoneyTransfer', - 'order_status' => 'Pending', + 'order_status' => 'pending', 'active' => true ] ]; diff --git a/packages/Webkul/Checkout/src/Cart.php b/packages/Webkul/Checkout/src/Cart.php index eb4924901..1a60ef414 100644 --- a/packages/Webkul/Checkout/src/Cart.php +++ b/packages/Webkul/Checkout/src/Cart.php @@ -83,7 +83,7 @@ class Cart { } /** - * Prepare the other data for the product to be added. + * Prepare the other data for the product to be success. * * @param integer $id * @param array $data @@ -96,14 +96,14 @@ class Cart { unset($data['_token']); - //Check if the product is salable + //Check if the product is saleable if(!isset($data['product']) ||!isset($data['quantity'])) { - session()->flash('error', 'Cart System Integrity Violation, Some Required Fields Missing.'); + session()->flash('error', trans('shop::app.checkout.cart.integrity.missing_fields')); return redirect()->back(); } else { if($product->type == 'configurable' && !isset($data['super_attribute'])) { - session()->flash('error', 'Cart System Integrity Violation, Configurable Options Not Found In Request.'); + session()->flash('error', trans('shop::app.checkout.cart.integrity.missing_options')); return redirect()->back(); } @@ -153,13 +153,13 @@ class Cart { 'total_weight' => $product->weight * $data['quantity'], 'base_total_weight' => $product->weight * $data['quantity'], ]; - + return ['parent' => $parentData, 'child' => null]; } } /** - * Create new cart instance with the current item added. + * Create new cart instance with the current item success. * * @param integer $id * @param array $data @@ -172,13 +172,15 @@ class Cart { $cartData['channel_id'] = core()->getCurrentChannel()->id; - // this will auto set the customer id for the cart instances if customer is authenticated + //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_full_name'] = auth()->guard('customer')->user()->first_name .' '. auth()->guard('customer')->user()->last_name; + $cartData['customer_first_name'] = auth()->guard('customer')->user()->first_name; + + $cartData['customer_last_name'] = auth()->guard('customer')->user()->last_name; } else { $cartData['is_guest'] = 1; } @@ -190,43 +192,38 @@ class Cart { if($cart = $this->cart->create($cartData)) { $itemData['parent']['cart_id'] = $cart->id; - if ($data['is_configurable'] == "true") { - //parent product entry + if ($this->product->find($id)->type == "configurable") { + //parent item entry $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'])) { session()->put('cart', $cart); - session()->flash('success', 'Item Added To Cart Successfully'); + session()->flash('success', trans('shop::app.checkout.cart.item.success')); + + $this->collectTotals(); return redirect()->back(); } } - - // $cart->update(['subtotal' => $itemData['parent']['price'], 'base_sub_total' => $itemData['parent']['price']]); - $this->collectQuantities(); - - $this->collectTotals(); - } else if($data['is_configurable'] == "false") { + } else if($this->product->find($id)->type != "configurable") { if($result = $this->cartItem->create($itemData['parent'])) { session()->put('cart', $cart); - session()->flash('success', 'Item Added To Cart Successfully'); + session()->flash('success', trans('shop::app.checkout.cart.item.success')); + + $this->collectTotals(); return redirect()->back(); } - - // $cart->update(['subtotal' => $itemData['parent']['price'], 'base_sub_total' => $itemData['parent']['price']]); - $this->collectQuantities(); - - $this->collectTotals(); } } - session()->flash('error', 'Some Error Occured'); + session()->flash('error', trans('shop::app.checkout.cart.item.error_add')); return redirect()->back(); } @@ -238,10 +235,35 @@ class Cart { */ public function getCart() { - if(!$cart = session()->get('cart')) - return false; + $cart = null; - return $this->cart->find($cart->id); + if(session()->has('cart')) { + $cart = $this->cart->find(session()->get('cart')->id); + } else if(auth()->guard('customer')->check()) { + $cart = $this->cart->findOneByField('customer_id', auth()->guard('customer')->user()->id); + } + + return $cart && $cart->is_active ? $cart : null; + } + + /** + * Returns cart details in array + * + * @return array + */ + public function toArray() + { + $cart = $this->getCart(); + + $data = $cart->toArray(); + + $data['shipping_address'] = current($data['shipping_address']); + + $data['billing_address'] = current($data['billing_address']); + + $data['selected_shipping_rate'] = $cart->selected_shipping_rate->toArray(); + + return $data; } /** @@ -269,12 +291,12 @@ class Cart { } if ($quantity < 1) { - session()->flash('warning', 'Cannot Add Or Update Lesser than 1'); + session()->flash('warning', trans('shop::app.checkout.cart.quantity.warning')); return redirect()->back(); } - if($quantity < $totalQty) { + if($quantity <= $totalQty) { return true; } else { return false; @@ -294,13 +316,13 @@ class Cart { $itemData = $this->prepareItemData($id, $data); if(session()->has('cart')) { - $cart = session()->get('cart'); + $cart = $this->getCart(); $cartItems = $cart->items()->get(); if(isset($cartItems)) { foreach($cartItems as $cartItem) { - if($data['is_configurable'] == "false") { + if($this->product->find($id)->type == "simple") { if($cartItem->product_id == $id) { $prevQty = $cartItem->quantity; @@ -309,7 +331,7 @@ class Cart { $canBe = $this->canAddOrUpdate($cartItem->id, $prevQty + $newQty); if($canBe == false) { - session()->flash('warning', 'The requested quantity is not available, please try back later.'); + session()->flash('warning', trans('shop::app.checkout.cart.quantity.inventory_warning')); return redirect()->back(); } @@ -320,15 +342,13 @@ class Cart { 'base_total' => $cartItem->price * ($prevQty + $newQty) ]); - $this->collectQuantities(); - $this->collectTotals(); - session()->flash('success', "Product Quantity Successfully Updated"); + session()->flash('success', trans('shop::app.checkout.cart.quantity.success')); return redirect()->back(); } - } else if($data['is_configurable'] == "true") { + } else if($this->product->find($id)->type == "configurable") { if($cartItem->type == "configurable") { $temp = $this->cartItem->findOneByField('parent_id', $cartItem->id); if($temp->product_id == $data['selected_configurable_option']) { @@ -343,7 +363,7 @@ class Cart { $canBe = $this->canAddOrUpdate($cartItem->child->id, $prevQty + $newQty); if($canBe == false) { - session()->flash('warning', 'The requested quantity is not available, please try back later.'); + session()->flash('warning', trans('shop::app.checkout.cart.quantity.inventory_warning')); return redirect()->back(); } @@ -354,11 +374,9 @@ class Cart { 'base_total' => $parentPrice * ($prevQty + $newQty) ]); - $this->collectQuantities(); - $this->collectTotals(); - session()->flash('success', "Product Quantity Successfully Updated"); + session()->flash('success', trans('shop::app.checkout.cart.quantity.success')); return redirect()->back(); } @@ -366,7 +384,7 @@ class Cart { } } - if($data['is_configurable'] == "true") { + if($this->product->find($id)->type == "configurable") { $parent = $cart->items()->create($itemData['parent']); $itemData['child']['parent_id'] = $parent->id; @@ -374,17 +392,15 @@ class Cart { // $this->canAddOrUpdate($parent->child->id, $parent->quantity); $cart->items()->create($itemData['child']); - } else if($data['is_configurable'] == "false"){ + } else if($this->product->find($id)->type != "configurable"){ // $this->canAddOrUpdate($parent->id, $parent->quantity); $parent = $cart->items()->create($itemData['parent']); } - $this->collectQuantities(); - $this->collectTotals(); - session()->flash('success', 'Item Successfully Added To Cart'); + session()->flash('success', trans('shop::app.checkout.cart.item.success')); return redirect()->back(); } else { @@ -406,7 +422,7 @@ class Cart { public function update($itemIds) { if(session()->has('cart')) { - $cart = session()->get('cart'); + $cart = $this->getCart(); $items = $cart->items; @@ -420,19 +436,18 @@ class Cart { } if($canBe == false) { - session()->flash('warning', 'The requested quantity is not available, please try back later.'); + session()->flash('warning', trans('shop::app.checkout.cart.quantity.inventory_warning')); return redirect()->back(); } $item->update(['quantity' => $quantity]); + + $this->collectTotals(); } } } - - $items = $cart->items; - - session()->flash('success', 'Cart Updated Successfully'); + session()->flash('success', trans('shop::app.checkout.cart.quantity.success')); return redirect()->back(); } @@ -445,9 +460,8 @@ class Cart { */ public function removeItem($itemId) { - dd($itemId); if(session()->has('cart')) { - $cart = session()->get('cart'); + $cart = $this->getCart(); $items = $cart->items; @@ -461,12 +475,10 @@ class Cart { if($result) $result = $this->cartItem->delete($item->id); - $this->collectQuantities(); $this->collectTotals(); } else if($item->type == "simple" && $item->parent_id == null){ $result = $this->cartItem->delete($item->id); - $this->collectQuantities(); $this->collectTotals(); } } @@ -485,13 +497,11 @@ class Cart { } if ($result) { - session()->flash('sucess', trans('shop::app.checkout.cart.remove.success')); + session()->flash('sucess', trans('shop::app.checkout.cart.quantity.success_remove')); } else { - session()->flash('error', trans('shop::app.checkout.cart.remove.error')); + session()->flash('error', trans('shop::app.checkout.cart.quantity.error_remove')); } } - session()->flash('warning', trans('shop::app.checkout.cart.remove.cannot')); - return redirect()->back(); } @@ -536,7 +546,7 @@ class Cart { $shippingAddress = $data['shipping']; $billingAddress['cart_id'] = $shippingAddress['cart_id'] = $cart->id; - if($billingAddressModel = $cart->biling_address) { + if($billingAddressModel = $cart->billing_address) { $this->cartAddress->update($billingAddress, $billingAddressModel->id); if($shippingAddress = $cart->shipping_address) { @@ -611,28 +621,6 @@ class Cart { return $cartPayment; } - /** - * Update Cart Quantities, Weight - * - * @return void - */ - public function collectQuantities() - { - if(!$cart = $this->getCart()) - return false; - - $quantities = 0; - - foreach($cart->items as $item) { - $quantities = $quantities + $item->quantity; - } - - $itemCount = $cart->items->count(); - - $cart->update(['items_count' => $itemCount, 'items_qty' => $quantities]); - - } - /** * Updates cart totals * @@ -651,8 +639,8 @@ class Cart { $cart->base_sub_total_with_discount = 0; foreach ($cart->items()->get() as $item) { - $cart->grand_total = (float) $cart->grand_total + $item->price * $item->quantity; - $cart->base_grand_total = (float) $cart->base_grand_total + $item->base_price * $item->quantity; + $cart->grand_total = (float) $cart->grand_total + $item->total; + $cart->base_grand_total = (float) $cart->base_grand_total + $item->base_total; $cart->sub_total = (float) $cart->sub_total + $item->price * $item->quantity; $cart->base_sub_total = (float) $cart->base_sub_total + $item->base_price * $item->quantity; @@ -663,6 +651,15 @@ class Cart { $cart->base_grand_total = (float) $cart->base_grand_total + $shipping->base_price; } + $quantities = 0; + foreach($cart->items as $item) { + $quantities = $quantities + $item->quantity; + } + + $cart->items_count = $cart->items->count(); + + $cart->items_qty = $quantities; + $cart->save(); } @@ -676,10 +673,10 @@ class Cart { if(session()->has('cart')) { $cart = $this->cart->findOneByField('customer_id', auth()->guard('customer')->user()->id); - $guestCart = session()->get('cart'); + $guestCart = $this->getCart(); if(!isset($cart)) { - $guestCart->update(['customer_id' => auth()->guard('customer')->user()->id]); + $guestCart->update(['customer_id' => auth()->guard('customer')->user()->id, 'is_guest' => 0]); session()->forget('cart'); @@ -780,8 +777,6 @@ class Cart { //put the customer cart instance session()->put('cart', $cart); - $this->collectQuantities(); - $this->collectTotals(); return redirect()->back(); @@ -791,9 +786,7 @@ class Cart { } /** - * Destroys the session - * maintained for cart - * on customer logout. + * Destroys the session maintained for cart on customer logout. * * @return response */ @@ -807,4 +800,140 @@ class Cart { return redirect()->back(); } } + + /** + * Checks if cart has any error + * + * @return boolean + */ + public function hasError() + { + if(!$this->getCart()) + return true; + + if(!$this->isItemsHaveSufficientQuantity()) + return true; + + return false; + } + + /** + * Checks if all cart items have sufficient quantity. + * + * @return boolean + */ + public function isItemsHaveSufficientQuantity() + { + foreach ($this->getCart()->items as $item) { + if(!$this->isItemHaveQuantity($item)) + return false; + } + + return true; + } + + /** + * Checks if all cart items have sufficient quantity. + * + * @return boolean + */ + public function isItemHaveQuantity($item) + { + $product = $item->type == 'configurable' ? $item->child->product : $item->product; + + if(!$product->haveSufficientQuantity($item->quantity)) + return false; + + return true; + } + + + /** + * Deactivates current cart + * + * @return void + */ + public function deActivateCart() + { + if($cart = $this->getCart()) { + $this->cart->update(['is_active' => false], $cart->id); + + if(session()->has('cart')) { + session()->forget('cart'); + } + } + } + + /** + * Validate order before creation + * + * @return array + */ + public function prepareDataForOrder() + { + $data = $this->toArray(); + + $finalData = [ + 'customer_id' => $data['customer_id'], + 'is_guest' => $data['is_guest'], + 'customer_email' => $data['customer_email'], + 'customer_first_name' => $data['customer_first_name'], + 'customer_last_name' => $data['customer_last_name'], + 'customer' => auth()->guard('customer')->check() ? auth()->guard('customer')->user : null, + + 'shipping_method' => $data['selected_shipping_rate']['method'], + 'shipping_description' => $data['selected_shipping_rate']['method_description'], + 'shipping_amount' => $data['selected_shipping_rate']['price'], + 'base_shipping_amount' => $data['selected_shipping_rate']['base_price'], + + 'total_item_count' => $data['items_count'], + 'total_qty_ordered' => $data['items_qty'], + 'base_currency_code' => $data['base_currency_code'], + 'channel_currency_code' => $data['channel_currency_code'], + 'order_currency_code' => $data['cart_currency_code'], + 'grand_total' => $data['grand_total'], + 'base_grand_total' => $data['base_grand_total'], + 'sub_total' => $data['sub_total'], + 'base_sub_total' => $data['base_sub_total'], + + 'shipping_address' => array_except($data['shipping_address'], ['id', 'cart_id']), + 'billing_address' => array_except($data['billing_address'], ['id', 'cart_id']), + 'payment' => array_except($data['payment'], ['id', 'cart_id']), + ]; + + foreach($data['items'] as $item) { + $finalData['items'][] = $this->prepareDataForOrderItem($item); + } + + return $finalData; + } + + /** + * Prepares data for order item + * + * @return array + */ + public function prepareDataForOrderItem($data) + { + $finalData = [ + 'product' => $this->product->find($data['product_id']), + 'sku' => $data['sku'], + 'type' => $data['type'], + 'name' => $data['name'], + 'weight' => $data['weight'], + 'total_weight' => $data['total_weight'], + 'qty_ordered' => $data['quantity'], + 'price' => $data['price'], + 'base_price' => $data['base_price'], + 'total' => $data['total'], + 'base_total' => $data['base_total'], + 'additional' => $data['additional'], + ]; + + if(isset($data['child']) && $data['child']) { + $finalData['child'] = $this->prepareDataForOrderItem($data['child']); + } + + return $finalData; + } } \ No newline at end of file diff --git a/packages/Webkul/Checkout/src/Database/Migrations/2018_09_05_150444_create_cart_table.php b/packages/Webkul/Checkout/src/Database/Migrations/2018_09_05_150444_create_cart_table.php index b142835c8..be526e01e 100644 --- a/packages/Webkul/Checkout/src/Database/Migrations/2018_09_05_150444_create_cart_table.php +++ b/packages/Webkul/Checkout/src/Database/Migrations/2018_09_05_150444_create_cart_table.php @@ -15,10 +15,11 @@ class CreateCartTable extends Migration { Schema::create('cart', function (Blueprint $table) { $table->increments('id'); - $table->integer('customer_id')->unsigned()->nullable(); - $table->foreign('customer_id')->references('id')->on('customers')->onDelete('cascade'); - $table->integer('channel_id')->unsigned(); - $table->foreign('channel_id')->references('id')->on('channels')->onDelete('cascade'); + + $table->string('customer_email')->nullable(); + $table->string('customer_first_name')->nullable(); + $table->string('customer_last_name')->nullable(); + $table->string('shipping_method')->nullable(); $table->string('coupon_code')->nullable(); $table->boolean('is_gift')->default(0); @@ -27,8 +28,8 @@ class CreateCartTable extends Migration $table->decimal('exchange_rate', 12, 4)->nullable(); $table->string('global_currency_code')->nullable(); $table->string('base_currency_code')->nullable(); - $table->string('store_currency_code')->nullable(); - $table->string('quote_currency_code')->nullable(); + $table->string('channel_currency_code')->nullable(); + $table->string('cart_currency_code')->nullable(); $table->decimal('grand_total', 12, 4)->default(0)->nullable(); $table->decimal('base_grand_total', 12, 4)->default(0)->nullable(); $table->decimal('sub_total', 12, 4)->default(0)->nullable(); @@ -37,9 +38,16 @@ class CreateCartTable extends Migration $table->decimal('base_sub_total_with_discount', 12, 4)->default(0)->nullable(); $table->string('checkout_method')->nullable(); $table->boolean('is_guest')->nullable(); - $table->boolean('is_active')->nullable()->default(0); - $table->string('customer_full_name')->nullable(); + $table->boolean('is_active')->nullable()->default(1); + $table->string('customer_first_name')->nullable(); + $table->string('customer_last_name')->nullable(); + $table->string('customer_email')->nullable(); $table->dateTime('conversion_time')->nullable(); + + $table->integer('customer_id')->unsigned()->nullable(); + $table->foreign('customer_id')->references('id')->on('customers')->onDelete('cascade'); + $table->integer('channel_id')->unsigned(); + $table->foreign('channel_id')->references('id')->on('channels')->onDelete('cascade'); $table->timestamps(); }); } diff --git a/packages/Webkul/Checkout/src/Http/ViewComposers/CartComposer.php b/packages/Webkul/Checkout/src/Http/ViewComposers/CartComposer.php index 5fc83ca5d..c301b0a8d 100644 --- a/packages/Webkul/Checkout/src/Http/ViewComposers/CartComposer.php +++ b/packages/Webkul/Checkout/src/Http/ViewComposers/CartComposer.php @@ -44,53 +44,6 @@ class CartComposer } public function compose(View $view) { - // session()->forget('cart'); - // return redirect()->back(); - if(auth()->guard('customer')->check()) { - $cart = $this->cart->findOneByField('customer_id', auth()->guard('customer')->user()->id); - - if(isset($cart)) { - $cartItems = $this->cart->items($cart['id']); - - $products = array(); - - foreach($cartItems as $cartItem) { - $image = $this->productImage->getGalleryImages($cartItem->product); - - if(isset($image[0]['small_image_url'])) { - $products[$cartItem->product->id] = [$cartItem->product->name, $cartItem->price, $image[0]['small_image_url'], $cartItem->quantity]; - } - else { - $products[$cartItem->product->id] = [$cartItem->product->name, $cartItem->price, 'null', $cartItem->quantity]; - } - - } - session()->put('cart', $cart); - - $view->with('cart', $products); - } - } else { - if($cart = session()->get('cart')) { - if(isset($cart)) { - $cartItems = $this->cart->items($cart['id']); - - $products = array(); - - foreach($cartItems as $cartItem) { - $image = $this->productImage->getGalleryImages($cartItem->product); - - if(isset($image[0]['small_image_url'])) { - $products[$cartItem->product->id] = [$cartItem->product->name, $cartItem->price, $image[0]['small_image_url'], $cartItem->quantity]; - } - else { - $products[$cartItem->product->id] = [$cartItem->product->name, $cartItem->price, 'null', $cartItem->quantity]; - } - - } - - $view->with('cart', $products); - } - } - } + } } diff --git a/packages/Webkul/Checkout/src/Http/helpers.php b/packages/Webkul/Checkout/src/Http/helpers.php index adfa358ae..ded8b05f1 100644 --- a/packages/Webkul/Checkout/src/Http/helpers.php +++ b/packages/Webkul/Checkout/src/Http/helpers.php @@ -1,10 +1,10 @@ make(Cart::class); } } ?> \ No newline at end of file diff --git a/packages/Webkul/Checkout/src/Models/Cart.php b/packages/Webkul/Checkout/src/Models/Cart.php index eb7938a66..d3ba95f1b 100644 --- a/packages/Webkul/Checkout/src/Models/Cart.php +++ b/packages/Webkul/Checkout/src/Models/Cart.php @@ -13,10 +13,12 @@ class Cart extends Model { protected $table = 'cart'; - protected $fillable = ['customer_id', 'session_id', 'channel_id', 'coupon_code', 'is_gift', 'items_count', 'items_qty', 'exchange_rate', 'global_currency_code', 'base_currency_code', 'store_currency_code', 'quote_currency_code', 'grand_total', 'base_grand_total', 'sub_total', 'base_sub_total', 'sub_total_with_discount', 'base_sub_total_with_discount', 'checkout_method', 'is_guest', 'is_active', 'customer_full_name', 'conversion_time']; + protected $fillable = ['customer_id', 'session_id', 'channel_id', 'coupon_code', 'is_gift', 'items_count', 'items_qty', 'exchange_rate', 'global_currency_code', 'base_currency_code', 'channel_currency_code', 'cart_currency_code', 'grand_total', 'base_grand_total', 'sub_total', 'base_sub_total', 'sub_total_with_discount', 'base_sub_total_with_discount', 'checkout_method', 'is_guest', 'is_active', 'customer_first_name', 'conversion_time']; protected $hidden = ['coupon_code']; + protected $with = ['items', 'items.child', 'shipping_address', 'billing_address', 'selected_shipping_rate', 'payment']; + public function items() { return $this->hasMany(CartItem::class)->whereNull('parent_id'); } @@ -73,12 +75,20 @@ class Cart extends Model return $this->hasManyThrough(CartShippingRate::class, CartAddress::class, 'cart_id', 'cart_address_id'); } + /** + * Get all of the attributes for the attribute groups. + */ + public function selected_shipping_rate() + { + return $this->shipping_rates()->where('method', $this->shipping_method); + } + /** * Get all of the attributes for the attribute groups. */ public function getSelectedShippingRateAttribute() { - return $this->shipping_rates()->where('method', $this->shipping_method)->first(); + return $this->selected_shipping_rate()->where('method', $this->shipping_method)->first(); } /** diff --git a/packages/Webkul/Checkout/src/Providers/CheckoutServiceProvider.php b/packages/Webkul/Checkout/src/Providers/CheckoutServiceProvider.php index 768a0bd21..76568ab9c 100644 --- a/packages/Webkul/Checkout/src/Providers/CheckoutServiceProvider.php +++ b/packages/Webkul/Checkout/src/Providers/CheckoutServiceProvider.php @@ -23,8 +23,6 @@ class CheckoutServiceProvider extends ServiceProvider $router->aliasMiddleware('admin', RedirectIfNotAdmin::class); $router->aliasMiddleware('customer', RedirectIfNotCustomer::class); - - $this->app->register(ComposerServiceProvider::class); } /** @@ -44,7 +42,6 @@ class CheckoutServiceProvider extends ServiceProvider */ protected function registerFacades() { - //to make the cart facade and bind the //alias to the class needed to be called. $loader = AliasLoader::getInstance(); diff --git a/packages/Webkul/Checkout/src/Providers/ComposerServiceProvider.php b/packages/Webkul/Checkout/src/Providers/ComposerServiceProvider.php deleted file mode 100644 index 73007f3fa..000000000 --- a/packages/Webkul/Checkout/src/Providers/ComposerServiceProvider.php +++ /dev/null @@ -1,32 +0,0 @@ -model->destroy($cart_id); } - - /** - * Used to get items - * for cart explicitly, - * use cart instance - * instead. - * - * @return Mixed - */ - public function items($cartId) { - return $this->model->find($cartId)->items; - } } \ No newline at end of file diff --git a/packages/Webkul/Customer/src/Database/migrations/2018_10_03_025230_create_wishlist_table.php b/packages/Webkul/Customer/src/Database/migrations/2018_10_03_025230_create_wishlist_table.php index 08f8adae4..29ccc32c6 100644 --- a/packages/Webkul/Customer/src/Database/migrations/2018_10_03_025230_create_wishlist_table.php +++ b/packages/Webkul/Customer/src/Database/migrations/2018_10_03_025230_create_wishlist_table.php @@ -17,14 +17,17 @@ class CreateWishlistTable extends Migration $table->increments('id'); $table->integer('channel_id')->unsigned(); $table->foreign('channel_id')->references('id')->on('channels'); + $table->integer('product_id')->unsigned(); $table->foreign('product_id')->references('id')->on('products'); + $table->integer('customer_id')->unsigned(); $table->foreign('customer_id')->references('id')->on('customers')->onDelete('cascade'); + $table->json('item_options')->nullable(); $table->date('moved_to_cart')->nullable(); $table->boolean('shared')->nullable(); - $table->date('time_of_moving'); + $table->date('time_of_moving')->nullable(); $table->timestamps(); }); } diff --git a/packages/Webkul/Customer/src/Http/Controllers/WishlistController.php b/packages/Webkul/Customer/src/Http/Controllers/WishlistController.php index fb8567d66..306b40d0e 100644 --- a/packages/Webkul/Customer/src/Http/Controllers/WishlistController.php +++ b/packages/Webkul/Customer/src/Http/Controllers/WishlistController.php @@ -5,6 +5,7 @@ namespace Webkul\Customer\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Http\Response; use Webkul\Customer\Repositories\CustomerRepository; +use Webkul\Customer\Repositories\WishlistRepository; use Auth; /** @@ -18,44 +19,101 @@ use Auth; */ class WishlistController extends Controller { - /** - * Display a listing of the resource. - * - * @return \Illuminate\Http\Response - */ + protected $_config; + protected $customer; + protected $wishlist; - public function __construct(CustomerRepository $customer) + /** + * Initializes the required repository instances. + * + * @param $customer + * @param $wishlist + */ + public function __construct(CustomerRepository $customer, WishlistRepository $wishlist) { $this->middleware('customer'); $this->_config = request('_config'); $this->customer = $customer; + + $this->wishlist = $wishlist; } /** - * For taking the customer - * to the dashboard after - * authentication - * @return view + * Displays the listing resources if the customer having items in wishlist. */ - private function getCustomer($id) { - $customer = collect($this->customer->findOneWhere(['id'=>$id])); - return $customer; - } - public function index() { - $id = auth()->guard('customer')->user()->id; + $wishlists = $this->wishlist->findWhere(['channel_id' => core()->getCurrentChannel()->id,'customer_id' => auth()->guard('customer')->user()->id]); - $customer = $this->getCustomer($id); + $wishlistItems = array(); - return view($this->_config['view'])->with('customer', $customer); + foreach($wishlists as $wishlist) { + array_push($wishlistItems, $this->wishlist->getItemsWithProducts($wishlist->id)); + } + + return view($this->_config['view'])->with('items', $wishlistItems); } - public function wishlist() { - return view($this->_config['view']); + /** + * Function to add item to the wishlist. + * + * @param integer $itemId + */ + public function add($itemId) { + + $data = [ + 'channel_id' => core()->getCurrentChannel()->id, + 'product_id' => $itemId, + 'customer_id' => auth()->guard('customer')->user()->id + ]; + + $checked = $this->wishlist->findWhere(['channel_id' => core()->getCurrentChannel()->id, 'product_id' => $itemId, 'customer_id' => auth()->guard('customer')->user()->id]); + + if($checked->isEmpty()) { + if($this->wishlist->create($data)) { + session()->flash('success', trans('customer::app.wishlist.success')); + + return redirect()->back(); + } else { + session()->flash('error', trans('customer::app.wishlist.failure')); + + return redirect()->back(); + } + } else { + session()->flash('warning', trans('customer::app.wishlist.already')); + + return redirect()->back(); + } + } + + /** + * Function to remove item to the wishlist. + * + * @param integer $itemId + */ + public function remove($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')); + + return redirect()->back(); + } else { + session()->flash('error', trans('customer::app.wishlist.remove-fail')); + + return redirect()->back(); + } + } + + /** + * Function to move item from wishlist to cart. + * + * @param integer $itemId + */ + public function moveToCart() { + dd('adding item to wishlist'); } } diff --git a/packages/Webkul/Customer/src/Models/Wishlist.php b/packages/Webkul/Customer/src/Models/Wishlist.php new file mode 100644 index 000000000..320dd3ca4 --- /dev/null +++ b/packages/Webkul/Customer/src/Models/Wishlist.php @@ -0,0 +1,17 @@ +belongsTo(Product::class, 'product_id'); + } +} diff --git a/packages/Webkul/Customer/src/Providers/CustomerServiceProvider.php b/packages/Webkul/Customer/src/Providers/CustomerServiceProvider.php index fedbe7294..0cd3b1e83 100644 --- a/packages/Webkul/Customer/src/Providers/CustomerServiceProvider.php +++ b/packages/Webkul/Customer/src/Providers/CustomerServiceProvider.php @@ -15,6 +15,8 @@ class CustomerServiceProvider extends ServiceProvider { $router->aliasMiddleware('customer', RedirectIfNotCustomer::class); + $this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'customer'); + $this->loadMigrationsFrom(__DIR__ . '/../Database/migrations'); $this->loadViewsFrom(__DIR__ . '/../Resources/views', 'customer'); diff --git a/packages/Webkul/Customer/src/Repositories/WishlistRepository.php b/packages/Webkul/Customer/src/Repositories/WishlistRepository.php new file mode 100644 index 000000000..b9070d286 --- /dev/null +++ b/packages/Webkul/Customer/src/Repositories/WishlistRepository.php @@ -0,0 +1,64 @@ + + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ + +class WishlistRepository extends Repository +{ + /** + * Specify Model class name + * + * @return mixed + */ + + function model() + { + return 'Webkul\Customer\Models\Wishlist'; + } + + /** + * @param array $data + * @return mixed + */ + + public function create(array $data) + { + $wishlist = $this->model->create($data); + + return $wishlist; + } + + /** + * @param array $data + * @param $id + * @param string $attribute + * @return mixed + */ + + public function update(array $data, $id, $attribute = "id") + { + $wishlist = $this->find($id); + + $wishlist->update($data); + + return $wishlist; + } + + /** + * To retrieve products with wishlist m + * for a listing resource. + * + * @param integer $id + */ + public function getItemsWithProducts($id) { + return $this->model->find($id)->item_wishlist; + } +} \ No newline at end of file diff --git a/packages/Webkul/Customer/src/Resources/lang/en/app.php b/packages/Webkul/Customer/src/Resources/lang/en/app.php new file mode 100644 index 000000000..470145c57 --- /dev/null +++ b/packages/Webkul/Customer/src/Resources/lang/en/app.php @@ -0,0 +1,12 @@ + [ + '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', + 'remove-fail' => 'Item Cannot Be Removed From Wishlist', + 'empty' => 'You Don\'t Have Any Items In Your Wishlist' + ], +]; \ No newline at end of file diff --git a/packages/Webkul/Product/src/Models/Product.php b/packages/Webkul/Product/src/Models/Product.php index 73c475242..b6a910fd5 100644 --- a/packages/Webkul/Product/src/Models/Product.php +++ b/packages/Webkul/Product/src/Models/Product.php @@ -141,15 +141,36 @@ class Product extends Model */ public function isSaleable() { - if($this->status) { - if($this->inventories->sum('qty')) { - return true; - } - } + if(!$this->status) + return false; + + if($this->haveSufficientQuantity(1)) + return true; return false; } + /** + * @param integer $qty + * + * @return bool + */ + public function haveSufficientQuantity($qty) + { + $inventories = $this->inventory_sources()->orderBy('priority', 'asc')->get(); + + $total = 0; + + foreach($inventories as $inventorySource) { + if(!$inventorySource->status) + continue; + + $total += $inventorySource->pivot->qty; + } + + return $qty <= $total ? true : false; + } + /** * Get an attribute from the model. * diff --git a/packages/Webkul/Product/src/Repositories/ProductRepository.php b/packages/Webkul/Product/src/Repositories/ProductRepository.php index 9bbb48d87..1a5b92783 100644 --- a/packages/Webkul/Product/src/Repositories/ProductRepository.php +++ b/packages/Webkul/Product/src/Repositories/ProductRepository.php @@ -395,7 +395,7 @@ class ProductRepository extends Repository ])); $params = request()->input(); - + return $this->scopeQuery(function($query){ return $query->distinct()->addSelect('products.*'); })->paginate(isset($params['limit']) ? $params['limit'] : 9, ['products.id']); diff --git a/packages/Webkul/Sales/src/Contracts/OrderItemInventory.php b/packages/Webkul/Sales/src/Contracts/OrderItemInventory.php new file mode 100644 index 000000000..7e3fb76cd --- /dev/null +++ b/packages/Webkul/Sales/src/Contracts/OrderItemInventory.php @@ -0,0 +1,7 @@ +increments('id'); $table->string('increment_id'); + $table->string('status')->nullable(); $table->boolean('is_guest')->nullable(); $table->string('customer_email')->nullable(); diff --git a/packages/Webkul/Sales/src/Database/Migrations/2018_10_04_124730_create_order_item_inventories.php b/packages/Webkul/Sales/src/Database/Migrations/2018_10_04_124730_create_order_item_inventories.php new file mode 100644 index 000000000..ef1d20284 --- /dev/null +++ b/packages/Webkul/Sales/src/Database/Migrations/2018_10_04_124730_create_order_item_inventories.php @@ -0,0 +1,34 @@ +increments('id'); + $table->integer('qty')->default(0); + $table->integer('inventory_source_id')->unsigned()->nullable(); + $table->integer('order_item_id')->unsigned()->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('order_item_inventories'); + } +} diff --git a/packages/Webkul/Sales/src/Models/Order.php b/packages/Webkul/Sales/src/Models/Order.php index 14ee0649e..7c30a7723 100644 --- a/packages/Webkul/Sales/src/Models/Order.php +++ b/packages/Webkul/Sales/src/Models/Order.php @@ -7,13 +7,13 @@ use Webkul\Sales\Contracts\Order as OrderContract; class Order extends Model implements OrderContract { - protected $guarded = ['id', 'created_at', 'updated_at']; + protected $guarded = ['id', 'items', 'shipping_address', 'billing_address', 'payment', 'created_at', 'updated_at']; /** * Get the order items record associated with the order. */ public function items() { - return $this->hasMany(CartItemProxy::modelClass())->whereNull('parent_id'); + return $this->hasMany(OrderItemProxy::modelClass())->whereNull('parent_id'); } /** diff --git a/packages/Webkul/Sales/src/Models/OrderAddress.php b/packages/Webkul/Sales/src/Models/OrderAddress.php index e34b97b0e..73f88c680 100644 --- a/packages/Webkul/Sales/src/Models/OrderAddress.php +++ b/packages/Webkul/Sales/src/Models/OrderAddress.php @@ -10,6 +10,8 @@ class OrderAddress extends Model implements OrderAddressContract { protected $table = 'order_address'; + protected $guarded = ['id', 'created_at', 'updated_at']; + /** * Get of the customer fullname. */ diff --git a/packages/Webkul/Sales/src/Models/OrderItem.php b/packages/Webkul/Sales/src/Models/OrderItem.php index ef5aa78c3..795bee0f5 100644 --- a/packages/Webkul/Sales/src/Models/OrderItem.php +++ b/packages/Webkul/Sales/src/Models/OrderItem.php @@ -7,6 +7,8 @@ use Webkul\Sales\Contracts\OrderItem as OrderItemContract; class OrderItem extends Model implements OrderItemContract { + protected $guarded = ['id', 'child', 'created_at', 'updated_at']; + /** * Get the order record associated with the order item. */ @@ -30,4 +32,11 @@ class OrderItem extends Model implements OrderItemContract { return $this->belongsTo(OrderItemProxy::modelClass(), 'parent_id'); } + + /** + * Get the inventories record associated with the order item. + */ + public function inventories() { + return $this->hasMany(CartItemInventoyrProxy::modelClass()); + } } \ No newline at end of file diff --git a/packages/Webkul/Sales/src/Models/OrderItemInventory.php b/packages/Webkul/Sales/src/Models/OrderItemInventory.php new file mode 100644 index 000000000..1d6101016 --- /dev/null +++ b/packages/Webkul/Sales/src/Models/OrderItemInventory.php @@ -0,0 +1,19 @@ +belongsTo(OrderItemProxy::modelClass()); + } +} \ No newline at end of file diff --git a/packages/Webkul/Sales/src/Models/OrderItemInventoryProxy.php b/packages/Webkul/Sales/src/Models/OrderItemInventoryProxy.php new file mode 100644 index 000000000..75a62abf4 --- /dev/null +++ b/packages/Webkul/Sales/src/Models/OrderItemInventoryProxy.php @@ -0,0 +1,10 @@ + + * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) + */ + +class OrderItemInventoryRepository extends Repository +{ + /** + * Specify Model class name + * + * @return Mixed + */ + + function model() + { + return 'Webkul\Sales\Contracts\OrderItemInventory'; + } + + /** + * @param array $data + * @return mixed + */ + public function create(array $data) + { + $orderItem = $data['orderItem']; + + $orderedQuantity = $orderItem->qty_ordered; + + $product = $orderItem->type == 'configurable' ? $orderItem->child->product : $orderItem->product; + + if($product) { + $inventories = $product->inventory_sources()->orderBy('priority', 'asc')->get(); + + foreach($inventories as $inventorySource) { + if(!$orderedQuantity) + break; + + $sourceQuantity = $inventorySource->pivot->qty; + + if(!$inventorySource->status || !$sourceQuantity) + continue; + + if($sourceQuantity >= $orderedQuantity) { + $orderItemQuantity = $orderedQuantity; + + $sourceQuantity -= $orderItemQuantity; + + $orderedQuantity = 0; + } else { + $orderItemQuantity = $sourceQuantity; + + $sourceQuantity = 0; + + $orderedQuantity -= $orderItemQuantity; + } + + $this->model->create([ + 'qty' => $orderItemQuantity, + 'order_item_id' => $orderItem->id, + 'inventory_source_id' => $inventorySource->id, + ]); + + $inventorySource->pivot->update([ + 'qty' => $sourceQuantity + ]); + } + } + } +} \ No newline at end of file diff --git a/packages/Webkul/Sales/src/Repositories/OrderItemRepository.php b/packages/Webkul/Sales/src/Repositories/OrderItemRepository.php index d9cb23486..50b3f2d1d 100644 --- a/packages/Webkul/Sales/src/Repositories/OrderItemRepository.php +++ b/packages/Webkul/Sales/src/Repositories/OrderItemRepository.php @@ -24,4 +24,20 @@ class OrderItemRepository extends Repository { return 'Webkul\Sales\Contracts\OrderItem'; } + + /** + * @param array $data + * @return mixed + */ + public function create(array $data) + { + if(isset($data['product']) && $data['product']) { + $data['product_id'] = $data['product']->id; + $data['product_type'] = get_class($data['product']); + + unset($data['product']); + } + + return $this->model->create($data); + } } \ No newline at end of file diff --git a/packages/Webkul/Sales/src/Repositories/OrderRepository.php b/packages/Webkul/Sales/src/Repositories/OrderRepository.php index 513957c48..25428b334 100644 --- a/packages/Webkul/Sales/src/Repositories/OrderRepository.php +++ b/packages/Webkul/Sales/src/Repositories/OrderRepository.php @@ -3,9 +3,12 @@ namespace Webkul\Sales\Repositories; use Illuminate\Container\Container as App; -use Webkul\Core\Eloquent\Repository; use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\DB; +use Illuminate\Database\Eloquent\Model; +use Webkul\Core\Eloquent\Repository; +use Webkul\Sales\Repositories\OrderItemRepository; +use Webkul\Sales\Repositories\OrderItemInventoryRepository; /** * Order Reposotory @@ -23,19 +26,30 @@ class OrderRepository extends Repository */ protected $orderItem; + /** + * OrderItemInventoryRepository object + * + * @var Object + */ + protected $orderItemInventory; + /** * Create a new repository instance. * - * @param Webkul\Sales\Repositories\OrderItemRepository $orderItem + * @param Webkul\Sales\Repositories\OrderItemRepository $orderItem + * @param Webkul\Sales\Repositories\OrderItemInventoryRepository $orderItemInventory * @return void */ public function __construct( OrderItemRepository $orderItem, + OrderItemInventoryRepository $orderItemInventory, App $app ) { $this->orderItem = $orderItem; + $this->orderItemInventory = $orderItemInventory; + parent::__construct($app); } @@ -56,15 +70,37 @@ class OrderRepository extends Repository */ public function create(array $data) { - $this->validateOrder(); - DB::beginTransaction(); try { Event::fire('checkout.order.save.before', $data); - $order = null; + if(isset($data['customer']) && $data['customer'] instanceof Model) { + $data['customer_id'] = $data['customer']->id; + $data['customer_type'] = get_class($data['customer']); + } else { + unset($data['customer']); + } + $data['status'] = core()->getConfigData('paymentmethods.' . $data['payment']['method'] . '.status') ?? 'pending'; + + $order = $this->model->create(array_merge($data, ['increment_id' => $this->generateIncrementId()])); + + $order->payment()->create($data['payment']); + + $order->addresses()->create($data['shipping_address']); + + $order->addresses()->create($data['billing_address']); + + foreach($data['items'] as $item) { + $orderItem = $this->orderItem->create(array_merge($item, ['order_id' => $order->id])); + + if(isset($item['child']) && $item['child']) { + $orderItem->child = $this->orderItem->create(array_merge($item['child'], ['order_id' => $order->id, 'parent_id' => $orderItem->id])); + } + + $this->orderItemInventory->create(['orderItem' => $orderItem]); + } } catch (\Exception $e) { DB::rollBack(); @@ -77,4 +113,16 @@ class OrderRepository extends Repository return $order; } + + /** + * @inheritDoc + */ + public function generateIncrementId() + { + $lastOrder = $this->model->orderBy('id', 'desc')->limit(1)->first(); + + $lastId = $lastOrder ? $lastOrder->id : 0; + + return $lastId + 1; + } } \ 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 4ee3c1194..30f4a4635 100644 --- a/packages/Webkul/Shop/src/Http/Controllers/CartController.php +++ b/packages/Webkul/Shop/src/Http/Controllers/CartController.php @@ -122,7 +122,6 @@ class CartController extends Controller $data = request()->except('_token'); foreach($data['qty'] as $id => $quantity) { - // dd($id, $quantity); if($quantity <= 0) { session()->flash('warning', trans('shop::app.checkout.cart.quantity.illegal')); @@ -135,5 +134,6 @@ class CartController extends Controller } public function test() { + $result = Cart::isConfigurable(9); } } \ No newline at end of file diff --git a/packages/Webkul/Shop/src/Http/Controllers/OnepageController.php b/packages/Webkul/Shop/src/Http/Controllers/OnepageController.php index dca74b824..1be580622 100644 --- a/packages/Webkul/Shop/src/Http/Controllers/OnepageController.php +++ b/packages/Webkul/Shop/src/Http/Controllers/OnepageController.php @@ -53,10 +53,10 @@ class OnepageController extends Controller */ public function index() { - if(!$cart = Cart::getCart()) + if(Cart::hasError()) return redirect()->route('shop.checkout.cart.index'); - return view($this->_config['view'])->with('cart', $cart); + return view($this->_config['view'])->with('cart', Cart::getCart()); } /** @@ -67,7 +67,7 @@ class OnepageController extends Controller */ public function saveAddress(CustomerAddressForm $request) { - if(!Cart::saveCustomerAddress(request()->all()) || !$rates = Shipping::collectRates()) + if(Cart::hasError() || !Cart::saveCustomerAddress(request()->all()) || !$rates = Shipping::collectRates()) return response()->json(['redirect_url' => route('shop.checkout.cart.index')], 403); return response()->json($rates); @@ -82,7 +82,7 @@ class OnepageController extends Controller { $shippingMethod = request()->get('shipping_method'); - if(!$shippingMethod || !Cart::saveShippingMethod($shippingMethod)) + if(Cart::hasError() || !$shippingMethod || !Cart::saveShippingMethod($shippingMethod)) return response()->json(['redirect_url' => route('shop.checkout.cart.index')], 403); Cart::collectTotals(); @@ -99,7 +99,7 @@ class OnepageController extends Controller { $payment = request()->get('payment'); - if(!$payment || !Cart::savePaymentMethod($payment)) + if(Cart::hasError() || !$payment || !Cart::savePaymentMethod($payment)) return response()->json(['redirect_url' => route('shop.checkout.cart.index')], 403); $cart = Cart::getCart(); @@ -117,11 +117,16 @@ class OnepageController extends Controller */ public function saveOrder() { + if(Cart::hasError()) + return response()->json(['redirect_url' => route('shop.checkout.cart.index')], 403); + Cart::collectTotals(); $this->validateOrder(); - $order = $this->orderRepository->create([]); + $order = $this->orderRepository->create(Cart::prepareDataForOrder()); + + Cart::deActivateCart(); session()->flash('order', $order); @@ -150,5 +155,22 @@ class OnepageController extends Controller */ public function validateOrder() { + $cart = Cart::getCart(); + + if(!$cart->shipping_address) { + throw new \Exception(trans('Please check shipping address.')); + } + + if(!$cart->billing_address) { + throw new \Exception(trans('Please check billing address.')); + } + + if(!$cart->selected_shipping_rate) { + throw new \Exception(trans('Please specify shipping method.')); + } + + if(!$cart->payment) { + throw new \Exception(trans('Please specify payment method.')); + } } } \ No newline at end of file diff --git a/packages/Webkul/Shop/src/Http/routes.php b/packages/Webkul/Shop/src/Http/routes.php index dff2ea127..c68c46d59 100644 --- a/packages/Webkul/Shop/src/Http/routes.php +++ b/packages/Webkul/Shop/src/Http/routes.php @@ -10,10 +10,23 @@ Route::group(['middleware' => ['web']], function () { 'view' => 'shop::products.index' ]); - Route::get('/checkout/cart', 'Webkul\Shop\Http\Controllers\CartController@index')->defaults('_config', [ + //checkout and cart + Route::get('checkout/cart', 'Webkul\Shop\Http\Controllers\CartController@index')->defaults('_config', [ 'view' => 'shop::checkout.cart.index' ])->name('shop.checkout.cart.index'); + Route::post('checkout/cart/add/{id}', 'Webkul\Shop\Http\Controllers\CartController@add')->name('cart.add'); + + Route::get('checkout/cart/remove/{id}', 'Webkul\Shop\Http\Controllers\CartController@remove')->name('cart.remove'); + + Route::post('/checkout/cart', 'Webkul\Shop\Http\Controllers\CartController@updateBeforeCheckout')->defaults('_config',[ + 'redirect' => 'shop.checkout.cart.index' + ])->name('shop.checkout.cart.update'); + + Route::get('/checkout/cart/remove/{id}', 'Webkul\Shop\Http\Controllers\CartController@remove')->defaults('_config',[ + 'redirect' => 'shop.checkout.cart.index' + ])->name('shop.checkout.cart.remove'); + Route::get('/checkout/onepage', 'Webkul\Shop\Http\Controllers\OnepageController@index')->defaults('_config', [ 'view' => 'shop::checkout.onepage' ])->name('shop.checkout.onepage.index'); @@ -30,10 +43,6 @@ Route::group(['middleware' => ['web']], function () { 'view' => 'shop::checkout.success' ])->name('shop.checkout.success'); - Route::get('test', 'Webkul\Shop\Http\Controllers\CartController@test'); - - Route::get('mtest', 'Webkul\Shop\Http\Controllers\CartController@mergeTest'); - //dummy Route::get('test', 'Webkul\Shop\Http\Controllers\CartController@test'); @@ -41,18 +50,6 @@ Route::group(['middleware' => ['web']], function () { 'view' => 'shop::products.view' ])->name('shop.products.index'); - Route::post('product/cart/add/{id}', 'Webkul\Shop\Http\Controllers\CartController@add')->name('cart.add'); - - Route::get('product/cart/remove/{id}', 'Webkul\Shop\Http\Controllers\CartController@remove')->name('cart.remove'); - - Route::post('/checkout/cart', 'Webkul\Shop\Http\Controllers\CartController@updateBeforeCheckout')->defaults('_config',[ - 'redirect' => 'shop.checkout.cart.index' - ])->name('shop.checkout.cart.update'); - - Route::get('/checkout/cart/remove/{id}', 'Webkul\Shop\Http\Controllers\CartController@remove')->defaults('_config',[ - 'redirect' => 'shop.checkout.cart.index' - ])->name('shop.checkout.cart.remove'); - //Routes for product cart ends // Product Review routes Route::get('/reviews/{slug}', 'Webkul\Shop\Http\Controllers\ReviewController@show')->defaults('_config', [ @@ -101,6 +98,11 @@ Route::group(['middleware' => ['web']], function () { 'redirect' => 'customer.session.index' ])->name('customer.session.destroy'); + //wishlist + Route::get('wishlist/add/{id}', 'Webkul\Customer\Http\Controllers\WishlistController@add')->name('customer.wishlist.add'); + + Route::get('wishlist/remove/{id}', 'Webkul\Customer\Http\Controllers\WishlistController@remove')->name('customer.wishlist.remove'); + //customer account Route::prefix('account')->group(function () { @@ -122,12 +124,9 @@ Route::group(['middleware' => ['web']], function () { Route::post('profile/edit', 'Webkul\Customer\Http\Controllers\CustomerController@edit')->defaults('_config', [ 'view' => 'shop::customers.account.profile.edit' ])->name('customer.profile.edit'); - /* Profile Routes Ends Here */ - /* Routes for Addresses */ - Route::get('address/index', 'Webkul\Customer\Http\Controllers\AddressController@index')->defaults('_config', [ 'view' => 'shop::customers.account.address.address' ])->name('customer.address.index'); @@ -152,7 +151,7 @@ Route::group(['middleware' => ['web']], function () { /* Routes for Addresses ends here */ /* Wishlist route */ - Route::get('wishlist', 'Webkul\Customer\Http\Controllers\WishlistController@wishlist')->defaults('_config', [ + Route::get('wishlist', 'Webkul\Customer\Http\Controllers\WishlistController@index')->defaults('_config', [ 'view' => 'shop::customers.account.wishlist.wishlist' ])->name('customer.wishlist.index'); @@ -165,7 +164,6 @@ Route::group(['middleware' => ['web']], function () { Route::get('reviews', 'Webkul\Customer\Http\Controllers\CustomerController@reviews')->defaults('_config', [ 'view' => 'shop::customers.account.reviews.reviews' ])->name('customer.reviews.index'); - }); }); }); diff --git a/packages/Webkul/Shop/src/Providers/ComposerServiceProvider.php b/packages/Webkul/Shop/src/Providers/ComposerServiceProvider.php index b60018b7a..fb5a97bcc 100644 --- a/packages/Webkul/Shop/src/Providers/ComposerServiceProvider.php +++ b/packages/Webkul/Shop/src/Providers/ComposerServiceProvider.php @@ -5,6 +5,7 @@ namespace Webkul\Shop\Providers; use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Blade; use Illuminate\Support\ServiceProvider; +use Webkul\Product\Product\ProductImage; use View; class ComposerServiceProvider extends ServiceProvider diff --git a/packages/Webkul/Shop/src/Resources/assets/js/components/category-item.vue b/packages/Webkul/Shop/src/Resources/assets/js/components/category-item.vue index 1308bce97..e521a4638 100644 --- a/packages/Webkul/Shop/src/Resources/assets/js/components/category-item.vue +++ b/packages/Webkul/Shop/src/Resources/assets/js/components/category-item.vue @@ -1,7 +1,16 @@ @endpush + diff --git a/packages/Webkul/Shop/src/Resources/views/layouts/master.blade.php b/packages/Webkul/Shop/src/Resources/views/layouts/master.blade.php index d19b67b0b..d5537e8df 100644 --- a/packages/Webkul/Shop/src/Resources/views/layouts/master.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/layouts/master.blade.php @@ -20,6 +20,7 @@
+
diff --git a/packages/Webkul/Shop/src/Resources/views/products/add-to.blade.php b/packages/Webkul/Shop/src/Resources/views/products/add-to.blade.php index 8af90c782..c919c822d 100644 --- a/packages/Webkul/Shop/src/Resources/views/products/add-to.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/products/add-to.blade.php @@ -2,6 +2,6 @@ @include ('shop::products.add-to-cart', ['product' => $product]) - + @include('shop::products.wishlist')
\ No newline at end of file diff --git a/packages/Webkul/Shop/src/Resources/views/products/list/toolbar.blade.php b/packages/Webkul/Shop/src/Resources/views/products/list/toolbar.blade.php index 3a20a086a..7ac644c27 100644 --- a/packages/Webkul/Shop/src/Resources/views/products/list/toolbar.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/products/list/toolbar.blade.php @@ -76,7 +76,6 @@
-
@@ -115,6 +114,4 @@
-
- - +
\ No newline at end of file diff --git a/packages/Webkul/Shop/src/Resources/views/products/sharelinks.blade.php b/packages/Webkul/Shop/src/Resources/views/products/sharelinks.blade.php index c23ab4214..fd0807215 100644 --- a/packages/Webkul/Shop/src/Resources/views/products/sharelinks.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/products/sharelinks.blade.php @@ -1,4 +1 @@ - -
- -
+ diff --git a/packages/Webkul/Shop/src/Resources/views/products/view.blade.php b/packages/Webkul/Shop/src/Resources/views/products/view.blade.php index 82338f73c..dcec1ea95 100644 --- a/packages/Webkul/Shop/src/Resources/views/products/view.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/products/view.blade.php @@ -4,7 +4,6 @@ {{ $product->name }} @stop - @section('content-wrapper')
@@ -36,8 +35,11 @@
+ + + @{{ errors.first('quantity') }}
diff --git a/packages/Webkul/Shop/src/Resources/views/products/view/configurable-options.blade.php b/packages/Webkul/Shop/src/Resources/views/products/view/configurable-options.blade.php index 53e7d6939..13736e778 100644 --- a/packages/Webkul/Shop/src/Resources/views/products/view/configurable-options.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/products/view/configurable-options.blade.php @@ -49,7 +49,7 @@ template: '#product-options-template', - inject: ['$validator'], + inject: ['$validator'], data: () => ({ config: @json($config), diff --git a/packages/Webkul/Shop/src/Resources/views/products/view/gallery.blade.php b/packages/Webkul/Shop/src/Resources/views/products/view/gallery.blade.php index 677c2219c..40ecc4717 100644 --- a/packages/Webkul/Shop/src/Resources/views/products/view/gallery.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/products/view/gallery.blade.php @@ -1,5 +1,4 @@ @inject ('productImageHelper', 'Webkul\Product\Product\ProductImage') - getGalleryImages($product); ?>
@@ -32,10 +31,10 @@ -
- - @include ('shop::products.sharelinks') + {{-- Uncomment the line below for activating share links --}} + {{-- @include('shop::products.sharelinks') --}} + @include('shop::products.wishlist')
diff --git a/packages/Webkul/Shop/src/Resources/views/products/wishlist.blade.php b/packages/Webkul/Shop/src/Resources/views/products/wishlist.blade.php new file mode 100644 index 000000000..07c17d4be --- /dev/null +++ b/packages/Webkul/Shop/src/Resources/views/products/wishlist.blade.php @@ -0,0 +1,5 @@ +@auth('customer') + + + +@endauth diff --git a/public/themes/default/assets/css/shop.css b/public/themes/default/assets/css/shop.css index f68cab024..62752cf9a 100644 --- a/public/themes/default/assets/css/shop.css +++ b/public/themes/default/assets/css/shop.css @@ -178,12 +178,71 @@ white-space: nowrap; } -.product-card .cart-fav-seg .product-card.wishlist-icon { - cursor: pointer; +.add-to-wishlist .wishlist-icon:hover { + background-image: url("../images/wishadd.svg"); } -.product-card.wishlist-icon:hover { - background-image: url("../images/wishadd.svg"); +.wishlist-item { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + width: 100%; + height: 125px; +} + +.wishlist-item .media-info { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; +} + +.wishlist-item .media-info .media { + height: 125px; + width: 100px; +} + +.wishlist-item .media-info .info { + display: block; + margin-left: 20px; +} + +.wishlist-item .operations { + height: 120px; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} + +.wishlist-item .operations a { + width: 100%; +} + +.wishlist-item .operations a span { + float: right; } .product-price { @@ -207,6 +266,12 @@ color: #FF6472; } +.horizontal-rule { + width: 100%; + height: 1px; + background: #E8E8E8; +} + body { margin: 0; padding: 0; diff --git a/public/themes/default/assets/js/shop.js b/public/themes/default/assets/js/shop.js index 09ee618c4..38ea57bf0 100644 --- a/public/themes/default/assets/js/shop.js +++ b/public/themes/default/assets/js/shop.js @@ -30844,6 +30844,15 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); // // // +// +// +// +// +// +// +// +// +// // define the item component /* harmony default export */ __webpack_exports__["default"] = ({ @@ -30873,13 +30882,21 @@ var render = function() { var _h = _vm.$createElement var _c = _vm._self._c || _h return _c("li", [ - _c("a", { attrs: { href: this.item["translations"][0].slug } }, [ - _vm._v(_vm._s(this.item["translations"][0].name) + " "), - _vm.haveChildren && _vm.item.parent_id != null - ? _c("i", { staticClass: "icon dropdown-right-icon" }) - : _vm._e() + _c("div", { staticClass: "name" }, [ + _c("a", { attrs: { href: this.item["translations"][0].slug } }, [ + _vm._v(_vm._s(this.item["translations"][0].name) + " "), + _vm.haveChildren && _vm.item.parent_id != null + ? _c("i", { staticClass: "icon dropdown-right-icon" }) + : _vm._e() + ]) ]), _vm._v(" "), + _vm.haveChildren + ? _c("div", { staticClass: "click" }, [ + _c("i", { staticClass: "icon dropdown-right-icon" }) + ]) + : _vm._e(), + _vm._v(" "), _vm.haveChildren ? _c( "ul", @@ -31937,6 +31954,15 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); // // // +// +// +// +// +// +// +// +// +// // define the item component /* harmony default export */ __webpack_exports__["default"] = ({ @@ -31965,7 +31991,24 @@ var render = function() { var _vm = this var _h = _vm.$createElement var _c = _vm._self._c || _h - return _c("li") + return _c("li", [ + _c("a", { attrs: { href: this.item["translations"][0].slug } }, [ + _vm._v(_vm._s(this.item["translations"][0].name) + " "), + _vm.haveChildren && _vm.item.parent_id != null + ? _c("i", { staticClass: "icon dropdown-right-icon" }) + : _vm._e() + ]), + _vm._v(" "), + _vm.haveChildren + ? _c( + "ul", + { attrs: { id: "child" } }, + _vm._l(_vm.item.children, function(child, index) { + return _c("category-item", { key: index, attrs: { item: child } }) + }) + ) + : _vm._e() + ]) } var staticRenderFns = [] render._withStripped = true