Cart Refactored, Email Subscription, UI Bug Fix, Wishlist Order & Invoices Datagrid

This commit is contained in:
prashant-webkul 2018-11-16 17:21:10 +05:30
parent ede86c2d4d
commit 8c12e35621
34 changed files with 1072 additions and 698 deletions

View File

@ -140,11 +140,10 @@ return [
| this array to grant expanded functionality to your applications. | this array to grant expanded functionality to your applications.
| |
*/ */
/* /*
Code Editor Code Editor
*/ */
'editor' =>'vscode', 'editor' =>'vscode',

View File

@ -69,8 +69,20 @@ return [
], ],
'redis' => [ '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,
],
],
],
], ],
], ],

View File

@ -0,0 +1,127 @@
<?php
namespace Webkul\Admin\DataGrids;
use Illuminate\View\View;
use Webkul\Ui\DataGrid\Facades\DataGrid;
/**
* OrderInvoicesDataGrid
*
* @author Prashant Singh <prashant.singh852@webkul.com> @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();
}
}

View File

@ -0,0 +1,127 @@
<?php
namespace Webkul\Admin\DataGrids;
use Illuminate\View\View;
use Webkul\Ui\DataGrid\Facades\DataGrid;
/**
* OrderShipmentsDataGrid
*
* @author Prashant Singh <prashant.singh852@webkul.com> @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 '<span class="badge badge-md badge-success">Processing</span>';
else if($value == 'completed')
return '<span class="badge badge-md badge-success">Completed</span>';
else if($value == "canceled")
return '<span class="badge badge-md badge-danger">Canceled</span>';
else if($value == "closed")
return '<span class="badge badge-md badge-info">Closed</span>';
else if($value == "pending")
return '<span class="badge badge-md badge-warning">Pending</span>';
},
],
],
'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();
}
}

View File

@ -29,20 +29,19 @@ class EventServiceProvider extends ServiceProvider
'route' => 'admin.sales.orders.index', 'route' => 'admin.sales.orders.index',
'sort' => 1, 'sort' => 1,
'icon-class' => '', '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', 'key' => 'catalog',
'name' => 'Catalog', 'name' => 'Catalog',

View File

@ -144,6 +144,7 @@ return [
'cancel-confirm-msg' => 'Are you sure you want to cancel this order ?' 'cancel-confirm-msg' => 'Are you sure you want to cancel this order ?'
], ],
'invoices' => [ 'invoices' => [
'title' => 'Invoices',
'id' => 'Id', 'id' => 'Id',
'invoice-id' => 'Invoice Id', 'invoice-id' => 'Invoice Id',
'date' => 'Invoice Date', 'date' => 'Invoice Date',
@ -164,6 +165,7 @@ return [
'order-date' => 'Order Date' 'order-date' => 'Order Date'
], ],
'shipments' => [ 'shipments' => [
'title' => 'Shipments',
'id' => 'Id', 'id' => 'Id',
'date' => 'Shipment Date', 'date' => 'Shipment Date',
'order-id' => 'Order Id', 'order-id' => 'Order Id',

View File

@ -0,0 +1,23 @@
@extends('admin::layouts.content')
@section('page_title')
{{ __('admin::app.sales.invoices.title') }}
@stop
@section('content')
<div class="content full-page">
<div class="page-header">
<div class="page-title">
<h1>{{ __('admin::app.sales.invoices.title') }}</h1>
</div>
<div class="page-action">
</div>
</div>
<div class="page-content">
@inject('orderInvoicesGrid', 'Webkul\Admin\DataGrids\OrderInvoicesDataGrid')
{!! $orderInvoicesGrid->render() !!}
</div>
</div>
@stop

View File

@ -0,0 +1,23 @@
@extends('admin::layouts.content')
@section('page_title')
{{ __('admin::app.sales.shipments.title') }}
@stop
@section('content')
<div class="content full-page">
<div class="page-header">
<div class="page-title">
<h1>{{ __('admin::app.sales.shipments.title') }}</h1>
</div>
<div class="page-action">
</div>
</div>
<div class="page-content">
@inject('orderShipmentsGrid', 'Webkul\Admin\DataGrids\OrderShipmentsDataGrid')
{!! $orderShipmentsGrid->render() !!}
</div>
</div>
@stop

View File

@ -70,6 +70,11 @@ class Cart {
*/ */
protected $wishlist; protected $wishlist;
/**
* Suppress the session flash messages
*/
protected $suppressFlash;
/** /**
* Create a new controller instance. * Create a new controller instance.
* *
@ -104,21 +109,150 @@ class Cart {
$this->taxCategory = $taxCategory; $this->taxCategory = $taxCategory;
$this->wishlist = $wishlist; $this->wishlist = $wishlist;
$this->suppressFlash = false;
} }
/** /**
* Prepare the other data for the product to be success. * Create new cart instance.
* *
* @param integer $id * @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'])) { if(!isset($data['product']) || !isset($data['quantity'])) {
session()->flash('error', trans('shop::app.checkout.cart.integrity.missing_fields')); session()->flash('error', trans('shop::app.checkout.cart.integrity.missing_fields'));
@ -133,286 +267,135 @@ class Cart {
$child = $childData = null; $child = $childData = null;
$additional = []; $additional = [];
if($product->type == 'configurable') { $price = ($product->type == 'configurable' ? $parentProduct->price : $product->price);
$child = $this->product->findOneByField('id', $data['selected_configurable_option']); $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']); unset($additional['html']);
$additional['request'] = $data; $additional['request'] = $data;
$additional['variant_id'] = $data['selected_configurable_option']; $additional['variant_id'] = $data['selected_configurable_option'];
$childData = [ $childData['product_id'] = (int)$data['selected_configurable_option'];
'product_id' => $data['selected_configurable_option'], $childData['sku'] = $parentProduct->sku;
'sku' => $child->sku, $childData['name'] = $parentProduct->name;
'name' => $child->name, $childData['type'] = 'simple';
'type' => 'simple' $childData['cart_id'] = $this->getCart()->id;
];
} }
$price = ($product->type == 'configurable' ? $child->price : $product->price); $result = $this->cartItem->create($parentData);
$parentData = [ if ($childData != null) {
'sku' => $product->sku, $childData['parent_id'] = $result->id;
'product_id' => $productId, $this->cartItem->create($childData);
'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];
} }
/** if($result)
* Add Items in a cart with some cart and item details. return true;
* else
* @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(!$itemData) {
return false; return false;
} }
/**
* Update the cartItem on cart checkout page and if already added item is added again
*
* @return boolean
*/
public function updateItem($id, $data, $itemId)
{
$item = $this->cartItem->findOneByField('id', $itemId);
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;
}
} else {
$product = $this->product->findOneByField('id', $item->product_id);
if(!$product->haveSufficientQuantity($data['quantity'])) {
session()->flash('warning', trans('shop::app.checkout.cart.quantity.inventory_warning'));
return false;
}
}
$quantity = $data['quantity'];
$result = $item->update([
'quantity' => $quantity,
'total' => core()->convertPrice($item->price * ($quantity)),
'base_total' => $item->price * ($quantity),
'total_weight' => $item->weight * ($quantity),
'base_total_weight' => $item->weight * ($quantity)
]);
$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()) { if($cart = $this->getCart()) {
if($prepared == true) { $this->cartItem->delete($itemId);
$product = $this->product->find($preparedData['parent']['product_id']);
} else {
$product = $this->product->find($id);
}
$cartItems = $cart->items; //delete the cart instance if no items are there
if($cart->items()->get()->count() == 0) {
//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); $this->cart->delete($cart->id);
} else {
if($prepared == false) { $this->deActivateCart();
return $this->createNewCart($id, $data);
}
else {
return $this->createNewCart($id, $data, true, $preparedData);
} }
} session()->flash('success', trans('shop::app.checkout.cart.item.success-remove'));
}
} else {
if($prepared == false) {
return $this->createNewCart($id, $data);
}
else {
return $this->createNewCart($id, $data, true, $preparedData);
}
}
}
/** return true;
* Create new cart instance with the current item success.
*
* @param integer $id
* @param array $data
*
* @return Booleans
*/
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']);
} }
if(!$canAdd) {
session()->flash('warning', trans('shop::app.checkout.cart.quantity.inventory_warning'));
return false;
}
$itemData = $this->prepareItemData($id, $data);
} else {
$itemData = $preparedData;
}
//if the item data is not valid to be processed it will be returning false
if($itemData == false) {
return false;
}
$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;
}
}
}
session()->flash('error', trans('shop::app.checkout.cart.item.error_add'));
return false; return false;
} }
@ -455,23 +438,18 @@ class Cart {
if($guestCartItem->type == "simple") { if($guestCartItem->type == "simple") {
if($cartItem->product_id == $guestCartItem->product_id) { if($cartItem->product_id == $guestCartItem->product_id) {
$prevQty = $cartItem->quantity; $prevQty = $cartItem->quantity;
$newQty = $guestCartItem->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); $this->cartItem->delete($guestCartItem->id);
continue; continue;
} }
$cartItem->update([ $data['quantity'] = $newQty + $prevQty;
'quantity' => $prevQty + $newQty,
'total' => core()->convertPrice($cartItem->price * ($prevQty + $newQty)), $this->updateItem($cartItem->product_id, $data, $cartItem->id);
'base_total' => $cartItem->price * ($prevQty + $newQty),
'total_weight' => $cartItem->weight * ($prevQty + $newQty),
'base_total_weight' => $cartItem->weight * ($prevQty + $newQty)
]);
$guestCartItems->forget($key); $guestCartItems->forget($key);
$this->cartItem->delete($guestCartItem->id); $this->cartItem->delete($guestCartItem->id);
@ -485,34 +463,26 @@ class Cart {
$prevQty = $guestCartItem->quantity; $prevQty = $guestCartItem->quantity;
$newQty = $cartItem->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); $this->cartItem->delete($guestCartItem->id);
continue; continue;
} }
$cartItem->update([ $data['quantity'] = $newQty + $prevQty;
'quantity' => $prevQty + $newQty,
'total' => core()->convertPrice($cartItem->price * ($prevQty + $newQty)), $this->updateItem($cartItem->product_id, $data, $cartItem->id);
'base_total' => $cartItem->price * ($prevQty + $newQty),
'total_weight' => $cartItem->weight * ($prevQty + $newQty),
'base_total_weight' => $cartItem->weight * ($prevQty + $newQty)
]);
$guestCartItems->forget($key); $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); $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) { foreach($guestCartItems as $guestCartItem) {
if($guestCartItem->type == "configurable") { 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 * Save cart
* *
@ -929,8 +776,8 @@ class Cart {
$item->update([ $item->update([
'price' => $item->product->price, 'price' => $item->product->price,
'base_price' => $item->product->price, 'base_price' => $item->product->price,
'total' => core()->convertPrice($item->child->product->price * ($item->quantity)), 'total' => core()->convertPrice($item->product->price * ($item->quantity)),
'base_total' => $item->child->product->price * ($item->quantity), 'base_total' => $item->product->price * ($item->quantity),
]); ]);
} }
} }
@ -1135,106 +982,27 @@ class Cart {
* *
* Move a wishlist item to cart * Move a wishlist item to cart
*/ */
public function moveToCart($productId) { public function moveToCart($wishlistItem) {
$product = $this->product->find($productId); $product = $wishlistItem->product;
if($product->parent_id == null ||$product->parent_id == 'null') { if($product->type == 'simple') {
$data = [
'product' => $productId,
'quantity' => 1,
];
$result = $this->add($productId, $data);
if($result instanceof Collection || $result == true) {
return true;
} 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['quantity'] = 1;
$data['product'] = $product->parent_id; $data['product'] = $wishlistItem->product->id;
$data['selected_configurable_option'] = $product->id;
$moved = $this->add($product->parent_id, $data, true, $result); $result = $this->add($product->id, $data);
if(isset($moved)) { if($result) {
return true; return 1;
} else { } else {
return false; return 0;
}
} }
} else if($product->type == 'configurable' && $product->parent_id == null) {
return -1;
} }
} }
/** /**
* Move a configurable product from wishlist to cart. * Function to move a already added product to wishlist will run only on customer authentication.
*
* @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.
* *
* @param instance cartItem $id * @param instance cartItem $id
*/ */
@ -1253,7 +1021,7 @@ class Cart {
$wishlist['product_id'] = $item->product_id; $wishlist['product_id'] = $item->product_id;
} else { } else {
$wishlist['product_id'] = $item->child->product_id; $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']]); $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) if($cart->items()->count() == 0)
$this->cart->delete($cart->id); $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; return $result;
} else { } else {
session()->flash('success', trans('shop::app.checkout.cart.move-to-wishlist-error'));
return $result; return $result;
} }
} }
@ -1283,7 +1053,7 @@ class Cart {
* *
* @return response mixed * @return response mixed
*/ */
public function proceedForBuyNow($id) { public function proceedToBuyNow($id) {
$product = $this->product->findOneByField('id', $id); $product = $this->product->findOneByField('id', $id);
if($product->type == 'configurable') { if($product->type == 'configurable') {

View File

@ -24,18 +24,6 @@ class CartItemRepository extends Repository
return 'Webkul\Checkout\Models\CartItem'; 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 array $data
* @param $id * @param $id

View File

@ -0,0 +1,22 @@
<?php
namespace Webkul\Core\Models;
use Illuminate\Database\Eloquent\Model;
class SubscribersList extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $table = 'subscribers_list';
protected $fillable = [
'email', 'is_subscribed', 'token', 'channel_id'
];
protected $hidden = ['token'];
}

View File

@ -0,0 +1,35 @@
<?php
namespace Webkul\Core\Repositories;
use Illuminate\Container\Container as App;
use Webkul\Core\Eloquent\Repository;
/**
* SubscribersList Repository
*
* @author Prashant Singh <prashant.singh852@webkul.com>
* @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);
}
}

View File

@ -51,17 +51,11 @@ class WishlistController extends Controller
* Displays the listing resources if the customer having items in wishlist. * Displays the listing resources if the customer having items in wishlist.
*/ */
public function index() { public function index() {
$wishlists = $this->wishlist->findWhere([ $wishlistItems = $this->wishlist->findWhere([
'channel_id' => core()->getCurrentChannel()->id, 'channel_id' => core()->getCurrentChannel()->id,
'customer_id' => auth()->guard('customer')->user()->id] 'customer_id' => auth()->guard('customer')->user()->id]
); );
// dd($wishlistItems->count());
$wishlistItems = array();
foreach($wishlists as $wishlist) {
array_push($wishlistItems, $this->wishlist->getItemsWithProducts($wishlist->id));
}
return view($this->_config['view'])->with('items', $wishlistItems); return view($this->_config['view'])->with('items', $wishlistItems);
} }
@ -73,14 +67,6 @@ class WishlistController extends Controller
public function add($itemId) { public function add($itemId) {
$product = $this->product->findOneByField('id', $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 = [ $data = [
'channel_id' => core()->getCurrentChannel()->id, 'channel_id' => core()->getCurrentChannel()->id,
'product_id' => $itemId, 'product_id' => $itemId,
@ -112,9 +98,10 @@ class WishlistController extends Controller
* @param integer $itemId * @param integer $itemId
*/ */
public function remove($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])) { if($result) {
session()->flash('success', trans('customer::app.wishlist.remove')); session()->flash('success', trans('customer::app.wishlist.removed'));
return redirect()->back(); return redirect()->back();
} else { } 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. * Function to move item from wishlist to cart.
* *
* @param integer $itemId * @param integer $itemId
*/ */
public function moveAll() { public function move($itemId) {
Cart::moveAllToCart(); $wishlistItem = $this->wishlist->findOneByField('id', $itemId);
} $result = Cart::moveToCart($wishlistItem);
/** if($result == 1) {
* Function to move item from wishlist to cart. if($wishlistItem->delete()) {
* session()->flash('success', trans('shop::app.wishlist.moved'));
* @param integer $itemId
*/
public function move($productId) {
$result = Cart::moveToCart($productId);
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(); Cart::collectTotals();
session()->flash('success', 'Item Moved To Cart Successfully');
return redirect()->back(); return redirect()->back();
} else { } else {
session()->flash('error', 'Item Cannot Be Moved To Cart Successfully'); session()->flash('error', trans('shop::app.wishlist.move-error'));
return redirect()->back(); return redirect()->back();
} }
} else { } else if($result == 0) {
Session('error', 'Cannot Add The Product To Wishlist Due To Unknown Problems, Please Checkback Later'); 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(); 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();
} }
} }

View File

@ -5,7 +5,9 @@ namespace Webkul\Customer\Models;
use Illuminate\Notifications\Notifiable; use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Foundation\Auth\User as Authenticatable;
use Webkul\Customer\Models\CustomerGroup; use Webkul\Customer\Models\CustomerGroup;
use Webkul\Checkout\Models\Cart;
use Webkul\Sales\Models\Order; use Webkul\Sales\Models\Order;
use Webkul\Customer\Models\Wishlist;
use Webkul\Customer\Notifications\CustomerResetPassword; use Webkul\Customer\Notifications\CustomerResetPassword;
@ -19,8 +21,6 @@ class Customer extends Authenticatable
protected $hidden = ['password', 'remember_token']; protected $hidden = ['password', 'remember_token'];
protected $with = ['customerGroup'];
/** /**
* Get the customer full name. * Get the customer full name.
*/ */
@ -62,4 +62,32 @@ class Customer extends Authenticatable
{ {
return $this->hasOne(CustomerAddress::class, 'customer_id')->where('default_address', 1); 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);
}
} }

View File

@ -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']; protected $fillable = ['channel_id', 'product_id', 'customer_id', 'item_options','moved_to_cart','shared','time_of_moving'];
public function item_wishlist() { public function product() {
return $this->belongsTo(Product::class, 'product_id'); return $this->hasOne(Product::class, 'id', 'product_id');
} }
} }

View File

@ -5,12 +5,13 @@ return [
'success' => 'Item Successfully Added To Wishlist', 'success' => 'Item Successfully Added To Wishlist',
'failure' => 'Item Cannot Be Added To Wishlist', 'failure' => 'Item Cannot Be Added To Wishlist',
'already' => 'Item Already Present In Your 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', 'remove-fail' => 'Item Cannot Be Removed From Wishlist',
'empty' => 'You Don\'t Have Any Items In Your 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' => [ 'reviews' => [
'empty' => 'You Haven\'t Reviewed Any Product Yet' 'empty' => 'You Have Not Reviewed Any Of Product Yet'
] ]
]; ];

View File

@ -85,11 +85,14 @@ class CartController extends Controller
* *
* @return Mixed * @return Mixed
*/ */
public function add($id) { 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(); Cart::collectTotals();
@ -115,9 +118,9 @@ class CartController extends Controller
* @return response * @return response
*/ */
public function updateBeforeCheckout() { 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) { if($quantity <= 0) {
session()->flash('warning', trans('shop::app.checkout.cart.quantity.illegal')); 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(); Cart::collectTotals();
@ -144,7 +156,7 @@ class CartController extends Controller
} }
public function buyNow($id) { public function buyNow($id) {
$result = Cart::proceedForBuyNow($id); $result = Cart::proceedToBuyNow($id);
Cart::collectTotals(); Cart::collectTotals();
@ -164,14 +176,14 @@ class CartController extends Controller
public function moveToWishlist($id) { public function moveToWishlist($id) {
$result = Cart::moveToWishlist($id); $result = Cart::moveToWishlist($id);
if($result) { if(!$result) {
Cart::collectTotals(); Cart::collectTotals();
session()->flash('success', 'Item Successfully Moved To Wishlist'); session()->flash('success', trans('shop::app.wishlist.moved'));
return redirect()->back(); return redirect()->back();
} else { } else {
session()->flash('warning', 'Cannot move item to wishlist'); session()->flash('warning', trans('shop::app.wishlist.move-error'));
return redirect()->back(); return redirect()->back();
} }

View File

@ -6,6 +6,10 @@ use Webkul\Shop\Http\Controllers\Controller;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Http\Response; 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 * Subscription controller
@ -23,30 +27,112 @@ class SubscriptionController extends Controller
*/ */
protected $user; protected $user;
/**
* Customer Repository object
*
* @var array
*/
protected $customer;
/**
* Subscription List Repository object
*
* @var array
*/
protected $subscription;
/** /**
* Create a new controller instance. * Create a new controller instance.
* *
* @return void * @return void
*/ */
public function __construct() public function __construct(Customer $customer, Subscription $subscription)
{ {
$this->user = auth()->guard('customer')->user(); $this->user = auth()->guard('customer')->user();
$this->customer = $customer;
$this->subscription = $subscription;
$this->_config = request('_config'); $this->_config = request('_config');
} }
/** /**
* Display a listing of the resource. * Subscribes Customers and Guests to subscription mailing list and checks if already subscribed
*
* @param string $slug
* @return \Illuminate\Http\Response
*/ */
public function index($email) public function subscribe()
{ {
$this->validate(request(), [ $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');
} }
} }

View File

@ -7,6 +7,13 @@ Route::group(['middleware' => ['web', 'theme', 'locale', 'currency']], function
'view' => 'shop::home.index' 'view' => 'shop::home.index'
])->name('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 //Store front header nav-menu fetch
Route::get('/categories/{slug}', 'Webkul\Shop\Http\Controllers\CategoryController@index')->defaults('_config', [ Route::get('/categories/{slug}', 'Webkul\Shop\Http\Controllers\CategoryController@index')->defaults('_config', [
'view' => 'shop::products.index' 'view' => 'shop::products.index'
@ -157,12 +164,12 @@ Route::group(['middleware' => ['web', 'theme', 'locale', 'currency']], function
//Customer Wishlist remove //Customer Wishlist remove
Route::get('wishlist/remove/{id}', 'Webkul\Customer\Http\Controllers\WishlistController@remove')->name('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 //Customer Wishlist move to cart
Route::get('wishlist/move/{id}', 'Webkul\Customer\Http\Controllers\WishlistController@move')->name('customer.wishlist.move'); 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 //customer account
Route::prefix('account')->group(function () { Route::prefix('account')->group(function () {
//Customer Dashboard Route //Customer Dashboard Route

View File

@ -0,0 +1,31 @@
<?php
namespace Webkul\Shop\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
/**
* Subscriber Mail class
*
* @author Prashant Singh <prashant.singh852@webkul.com>
* @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']);
}
}

View File

@ -8,6 +8,7 @@ $link-color: #2650EF;
$background-color: #F2F2F2; $background-color: #F2F2F2;
$dark-background: #121212; $dark-background: #121212;
$disc-price: #FF6472; $disc-price: #FF6472;
$danger-color: #FF6472;
$disc-price-pro: #A5A5A5; $disc-price-pro: #A5A5A5;
$other-font-color: #5E5E5E; $other-font-color: #5E5E5E;
//shop variables ends here //shop variables ends here

View File

@ -281,12 +281,14 @@ input {
.media { .media {
height: 125px; height: 125px;
width: 125px; width: 110px;
} }
.info { .info {
display: block;
margin-left: 20px; margin-left: 20px;
display: flex;
flex-direction: column;
justify-content: space-evenly;
.stars .icon { .stars .icon {
height: 16px; height: 16px;
@ -299,7 +301,7 @@ input {
height: 120px; height: 120px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: flex-start; justify-content: space-between;
align-items: center; align-items: center;
a { a {
@ -488,7 +490,9 @@ input {
.product-card { .product-card {
width: 100%; width: 100%;
display: inline-block; display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 20px; margin-bottom: 20px;
.product-image { .product-image {
@ -1963,6 +1967,12 @@ section.cart {
a.link { a.link {
margin-right: 15px; margin-right: 15px;
} }
div {
button {
margin-right: 15px;
}
}
} }
} }
@ -1989,11 +1999,14 @@ section.cart {
.item-image { .item-image {
height: 160px; height: 160px;
width: 160px; width: 160px;
box-shadow: 1px 1px 1px $border-color;
} }
.item-details { .item-details {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between;
width: 100%;
.item-title { .item-title {
font-size: 18px; font-size: 18px;
@ -2016,37 +2029,44 @@ section.cart {
} }
.misc { .misc {
display: flex;
width: 100%;
flex-direction: row;
justify-content: flex-start;
align-items: flex-start;
.control-group {
font-size: 16px !important;
width: 220px;
margin: 0px;
.wrap {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: flex-start;
div.qty-text {
color: $font-color-light;
margin-right: 10px;
} }
input.box { label {
margin-right: 15px;
}
.control {
height: 38px; height: 38px;
width: 60px; width: 60px;
font-size: 16px; border-radius: 3px;
text-align: center; text-align: center;
line-height: 38px; line-height: 38px;
border: 1px solid $border-color; }
border-radius: 3px;
margin-right: 30px;
border-radius: 0px;
} }
.remove { .remove, .towishlist {
color: $brand-color; margin-top: 18px;
margin-right: 30px; margin-right: 15px;
}
}
} }
.towishlist { .error-message {
color : $brand-color; color: $disc-price;
}
}
} }
} }
} }
@ -2845,7 +2865,6 @@ section.review {
width: 100%; width: 100%;
.account-head { .account-head {
margin-bottom: 20px;
.back-icon { .back-icon {
display: none; display: none;
@ -2888,7 +2907,7 @@ section.review {
.address-card-1 { .address-card-1 {
width: 260px; width: 260px;
border: 1px solid #E8E8E8; border: 1px solid $border-color;
display: flex; display: flex;
position: relative; position: relative;
flex-direction: row; flex-direction: row;

View File

@ -9,14 +9,14 @@ return [
'header' => [ 'header' => [
'title' => 'Account', 'title' => 'Account',
'dropdown-text' => 'Manage Cart, Orders & Wishlist.', 'dropdown-text' => 'Manage Cart, Orders & Wishlist',
'sign-in' => 'Sign In', 'sign-in' => 'Sign In',
'sign-up' => 'Sign Up', 'sign-up' => 'Sign Up',
'profile' => 'Profile', 'profile' => 'Profile',
'wishlist' => 'Wishlist', 'wishlist' => 'Wishlist',
'cart' => 'Cart', 'cart' => 'Cart',
'logout' => 'Logout', 'logout' => 'Logout',
'search-text' => 'Search products here...' 'search-text' => 'Search products here'
], ],
'footer' => [ 'footer' => [
@ -26,8 +26,16 @@ return [
'currency' => 'Currency', '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' => [ 'search' => [
'no-results' => 'No Results Found.', 'no-results' => 'No Results Found',
'page-title' => 'Bagisto - Search', 'page-title' => 'Bagisto - Search',
'found-results' => 'Search Results Found', 'found-results' => 'Search Results Found',
'found-result' => 'Search Result Found' 'found-result' => 'Search Result Found'
@ -65,7 +73,7 @@ return [
], ],
'login-text' => [ 'login-text' => [
'no_account' => 'Don\'t have account', 'no_account' => 'Do not have account',
'title' => 'Sign Up', 'title' => 'Sign Up',
], ],
@ -77,7 +85,7 @@ return [
'forgot_pass' => 'Forgot Password?', 'forgot_pass' => 'Forgot Password?',
'button_title' => 'Sign In', 'button_title' => 'Sign In',
'remember' => 'Remember Me', 'remember' => 'Remember Me',
'footer' => '© Copyright 2018 Webkul Software, All rights reserved.' 'footer' => '© Copyright 2018 Webkul Software, All rights reserved'
], ],
'forgot-password' => [ 'forgot-password' => [
@ -130,7 +138,7 @@ return [
'title' => 'Address', 'title' => 'Address',
'add' => 'Add Address', 'add' => 'Add Address',
'edit' => 'Edit', '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', 'create' => 'Create Address',
'delete' => 'Delete', 'delete' => 'Delete',
'make-default' => 'Make Default', 'make-default' => 'Make Default',
@ -145,7 +153,7 @@ return [
'address2' => 'Address Line 2', 'address2' => 'Address Line 2',
'country' => 'Country', 'country' => 'Country',
'state' => 'State', 'state' => 'State',
'select-state' => 'Select a region, state or province.', 'select-state' => 'Select a region, state or province',
'city' => 'City', 'city' => 'City',
'postcode' => 'Postal Code', 'postcode' => 'Postal Code',
'phone' => 'Phone', 'phone' => 'Phone',
@ -252,7 +260,7 @@ return [
'choose-option' => 'Choose an option', 'choose-option' => 'Choose an option',
'sale' => 'Sale', 'sale' => 'Sale',
'new' => 'New', 'new' => 'New',
'empty' => 'No products available in this category.', 'empty' => 'No products available in this category',
'add-to-cart' => 'Add To Cart', 'add-to-cart' => 'Add To Cart',
'buy-now' => 'Buy Now', 'buy-now' => 'Buy Now',
'whoops' => 'Whoops!', 'whoops' => 'Whoops!',
@ -266,11 +274,24 @@ return [
'deleteall' => 'Delete All', 'deleteall' => 'Delete All',
'moveall' => 'Move All Products To Cart', 'moveall' => 'Move All Products To Cart',
'move-to-cart' => 'Move 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', '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' => [ 'buynow' => [
'no-options' => 'Please Select Options Before Buying This Product' 'no-options' => 'Please Select Options Before Buying This Product'
], ],
@ -280,32 +301,36 @@ return [
'cart' => [ 'cart' => [
'integrity' => [ 'integrity' => [
'missing_fields' =>'Cart System Integrity Violation, Some Required Fields Missing', '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', 'title' => 'Shopping Cart',
'empty' => 'Your shopping cart is empty.', 'empty' => 'Your Shopping Cart Is Empty',
'update-cart' => 'Update Cart', 'update-cart' => 'Update Cart',
'continue-shopping' => 'Continue Shopping', 'continue-shopping' => 'Continue Shopping',
'proceed-to-checkout' => 'Proceed To Checkout', 'proceed-to-checkout' => 'Proceed To Checkout',
'remove' => 'Remove', 'remove' => 'Remove',
'remove-link' => 'Remove', 'remove-link' => 'Remove',
'move-to-wishlist' => 'Move to Wishlist', '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', 'add-config-warning' => 'Please Select Option Before Adding To Cart',
'quantity' => [ 'quantity' => [
'quantity' => 'Quantity', 'quantity' => 'Quantity',
'success' => 'Quantity successfully updated', 'success' => 'Cart Item(s) Successfully Updated',
'illegal' => 'Quantity cannot be lesser than one', 'illegal' => 'Quantity Cannot Be Lesser Than One',
'inventory_warning' => 'The requested quantity is not available, please try again later' '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' => [ 'item' => [
'error_remove' => 'No items to remove from the cart', 'error_remove' => 'No Items To Remove From The Cart',
'success' => 'Item successfully added to cart', 'success' => 'Item Was Successfully Added To Cart',
'success_remove' => 'Item removed successfully', 'success-remove' => 'Item Was Removed Successfully From The Cart',
'error_add' => 'Item cannot be added to cart', 'error-add' => 'Item Cannot Be Added To Cart, Please Try Again Later',
], ],
'quantity-error' => 'Requested quantity is not available.', 'quantity-error' => 'Requested Quantity Is Not Available',
'cart-subtotal' => 'Cart Subtotal' 'cart-subtotal' => 'Cart Subtotal',
'cart-remove-action' => 'Do you really want to do this ?'
], ],
'onepage' => [ 'onepage' => [
@ -323,7 +348,7 @@ return [
'address2' => 'Address 2', 'address2' => 'Address 2',
'city' => 'City', 'city' => 'City',
'state' => 'State', 'state' => 'State',
'select-state' => 'Select a region, state or province.', 'select-state' => 'Select a region, state or province',
'postcode' => 'Zip/Postcode', 'postcode' => 'Zip/Postcode',
'phone' => 'Telephone', 'phone' => 'Telephone',
'country' => 'Country', 'country' => 'Country',
@ -355,7 +380,7 @@ return [
'title' => 'Order successfully placed', 'title' => 'Order successfully placed',
'thanks' => 'Thank you for your order!', 'thanks' => 'Thank you for your order!',
'order-id-info' => 'Your order id is #:order_id', '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', 'shipping-handling' => 'Shipping & Handling',
'tax' => 'Tax', 'tax' => 'Tax',
'grand-total' => 'Grand Total', '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', 'help' => 'If you need any kind of help please contact us at :support_email',
'thanks' => 'Thanks!' 'thanks' => 'Thanks!'
], ],
@ -395,14 +420,14 @@ return [
], ],
'forget-password' => [ 'forget-password' => [
'dear' => 'Dear :name', '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', '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!' 'thanks' => 'Thanks!'
] ]
], ],
'webkul' => [ 'webkul' => [
'copy-right' => '© Copyright 2018 Webkul Software, All rights reserved.' 'copy-right' => '© Copyright 2018 Webkul Software, All rights reserved'
] ]
]; ];

View File

@ -59,13 +59,16 @@
</div> </div>
@endif @endif
<div class="misc"> <div class="misc">
<div class="qty-text" :class="[errors.has('qty') ? 'has-error' : '']">{{ __('shop::app.checkout.cart.quantity.quantity') }}</div> <div class="control-group" :class="[errors.has('qty[{{$item->id}}]') ? 'has-error' : '']">
<div class="wrap">
<label for="qty[{{$item->id}}]">{{ __('shop::app.checkout.cart.quantity.quantity') }}</label>
<input class="box" type="text" class="control" v-validate="'required|numeric|min_value:1'" name="qty[{{$item->id}}]" value="{{ $item->quantity }}"> <input type="text" class="control" v-validate="'required|numeric|min_value:1'" name="qty[{{$item->id}}]" value="{{ $item->quantity }}">
</div>
<span class="control-error" v-if="errors.has('qty[{{$item->id}}]')">@{{ errors.first('qty') }}</span> <span class="control-error" v-if="errors.has('qty[{{$item->id}}]')">@{{ errors.first('qty[{!!$item->id!!}]') }}</span>
</div>
<span class="remove"> <span class="remove">
<a href="{{ route('shop.checkout.cart.remove', $item->id) }}" onclick="removeLink('Do you really want to do this?')">{{ __('shop::app.checkout.cart.remove-link') }}</a></span> <a href="{{ route('shop.checkout.cart.remove', $item->id) }}" onclick="removeLink('Do you really want to do this?')">{{ __('shop::app.checkout.cart.remove-link') }}</a></span>
@ -74,14 +77,14 @@
@if($item->parent_id != 'null' ||$item->parent_id != null) @if($item->parent_id != 'null' ||$item->parent_id != null)
<a href="{{ route('shop.movetowishlist', $item->id) }}" onclick="removeLink('Do you really want to do this?')">{{ __('shop::app.checkout.cart.move-to-wishlist') }}</a> <a href="{{ route('shop.movetowishlist', $item->id) }}" onclick="removeLink('Do you really want to do this?')">{{ __('shop::app.checkout.cart.move-to-wishlist') }}</a>
@else @else
<a href="{{ route('shop.movetowishlist', $item->child->id) }}" onclick="removeLink('Do you really want to do this?')">{{ __('shop::app.checkout.cart.move-to-wishlist') }}</a> <a href="{{ route('shop.movetowishlist', $item->child->id) }}" onclick="removeLink('{{ __('shop::app.checkout.cart.cart-remove-action') }}')">{{ __('shop::app.checkout.cart.move-to-wishlist') }}</a>
@endif @endif
</span> </span>
</div> </div>
@if (!cart()->isItemHaveQuantity($item)) @if (!cart()->isItemHaveQuantity($item))
<div class="error-message"> <div class="error-message mt-15">
{{ __('shop::app.checkout.cart.quantity-error') }} * {{ __('shop::app.checkout.cart.quantity-error') }}
</div> </div>
@endif @endif
</div> </div>

View File

@ -35,7 +35,7 @@
<div class="address-holder"> <div class="address-holder">
@foreach($addresses as $address) @foreach($addresses as $address)
<div class="address-card-1"> <div class="address-card-1">
<div class="details"> <div class="details @if($address->default_address) mt-20 @endif">
<span class="bold">{{ auth()->guard('customer')->user()->name }}</span> <span class="bold">{{ auth()->guard('customer')->user()->name }}</span>
{{ $address->name }}</br> {{ $address->name }}</br>
{{ $address->address1 }}, {{ $address->address2 ? $address->address2 . ',' : '' }}</br> {{ $address->address1 }}, {{ $address->address2 ? $address->address2 . ',' : '' }}</br>

View File

@ -49,7 +49,17 @@
</td> </td>
<td> <td>
<span class="order-status {{ $order->status }}">{{ $order->status_label }}</span> @if($order->status == 'processing')
<span class="badge badge-md badge-success">Processing</span>
@elseif($order->status == 'completed')
<span class="badge badge-md badge-success">Completed</span>
@elseif($order->status == "canceled")
<span class="badge badge-md badge-danger">Canceled</span>
@elseif($order->status == "closed")
<span class="badge badge-md badge-info">Closed</span>
@elseif($order->status == "pending")
<span class="badge badge-md badge-warning">Pending</span>
@endif
</td> </td>
</tr> </tr>

View File

@ -28,7 +28,7 @@
<div class="product-name">{{$review->product->name}}</div> <div class="product-name">{{$review->product->name}}</div>
<div> <div>
@for($i=0 ; $i < $review->rating ; $i++) @for($i=0;$i<$review->rating;$i++)
<span class="icon star-icon"></span> <span class="icon star-icon"></span>
@endfor @endfor
</div> </div>

View File

@ -14,8 +14,7 @@
@if(count($items)) @if(count($items))
<div class="account-action"> <div class="account-action">
<a href="" style="margin-right: 15px;">{{ __('shop::app.wishlist.deleteall') }}</a> <a href="{{ route('customer.wishlist.removeall') }}" style="margin-right: 15px;">{{ __('shop::app.wishlist.deleteall') }}</a>
<a href="">{{ __('shop::app.wishlist.moveall') }}</a>
</div> </div>
@endif @endif
<div class="horizontal-rule"></div> <div class="horizontal-rule"></div>
@ -23,23 +22,28 @@
<div class="account-items-list"> <div class="account-items-list">
@if(count($items)) @if($items->count())
@foreach($items as $item) @foreach($items as $item)
<div class="account-item-card mt-15 mb-15"> <div class="account-item-card mt-15 mb-15">
<div class="media-info"> <div class="media-info">
@php @php
$image = $productImageHelper->getProductBaseImage($item); $image = $productImageHelper->getProductBaseImage($item->product);
@endphp @endphp
<a href="{{ url()->to('/').'/products/'.$item->product->url_key }}" title="{{ $item->product->name }}">
<img class="media" src="{{ $image['small_image_url'] }}" /> <img class="media" src="{{ $image['small_image_url'] }}" />
</a>
{{-- {{ dd($item['url_key'])}} --}} <div class="info">
<div class="info mt-20">
<div class="product-name"> <div class="product-name">
{{-- <a href="{{ url()->to('/').'/products/'.$item->product->url_key }}" title="{{ $item->product->name }}"> --}} <a href="{{ url()->to('/').'/products/'.$item->product->url_key }}" title="{{ $item->product->name }}">
{{$item->name}} {{$item->product->name}}
{{-- </a> --}} </a>
</div> </div>
@inject ('reviewHelper', 'Webkul\Product\Helpers\Review')
<span class="stars" style="display: inline">
@for($i=1;$i<=$reviewHelper->getAverageRating($item->product);$i++)
<span class="icon star-icon"></span>
@endfor
</span>
</div> </div>
</div> </div>

View File

@ -0,0 +1,18 @@
@component('shop::emails.layouts.master')
<div style="text-align: center;">
<a href="{{ config('app.url') }}">
<img src="{{ bagisto_asset('images/logo.svg') }}">
</a>
</div>
<div style="padding: 30px;">
{{ $data['content'] }}
<div>
You Can Unsubscribe From The List By Clicking Link Below.
</div>
<span>
<a href="{{ route('shop.unsubscribe', $data['token']) }}" class="btn btn-success btn-md">{{ __('shop::app.subscription.unsubscribe') }}</a>
</span>
</div>
@endcomponent

View File

@ -18,10 +18,15 @@
<div class="list-container"> <div class="list-container">
<span class="list-heading">{{ __('shop::app.footer.subscribe-newsletter') }}</span> <span class="list-heading">{{ __('shop::app.footer.subscribe-newsletter') }}</span>
<div class="form-container"> <div class="form-container">
<div class="control-group"> <form action="{{ route('shop.subscribe') }}" @submit.prevent="onSubmit">
<input type="text" class="control subscribe-field" placeholder="Email Address"><br/> <div class="control-group" :class="[errors.has('email') ? 'has-error' : '']">
<button class="btn btn-md btn-primary">{{ __('shop::app.footer.subscribe') }}</button> <input type="text" class="control subscribe-field" name="email" placeholder="Email Address" required><br/>
<span class="control-error" v-if="errors.has('email')">@{{ errors.first('email') }}</span>
<button class="btn btn-md btn-primary">{{ __('shop::app.subscription.subscribe') }}</button>
</div> </div>
</form>
</div> </div>
<span class="list-heading">{{ __('shop::app.footer.locale') }}</span> <span class="list-heading">{{ __('shop::app.footer.locale') }}</span>

View File

@ -62,6 +62,9 @@
@elseif($error = session('error')) @elseif($error = session('error'))
window.flashMessages = [{'type': 'alert-error', 'message': "{{ $error }}" } window.flashMessages = [{'type': 'alert-error', 'message': "{{ $error }}" }
]; ];
@elseif($info = session('info'))
window.flashMessages = [{'type': 'alert-info', 'message': "{{ $info }}" }
];
@endif @endif
window.serverErrors = []; window.serverErrors = [];

View File

@ -37,9 +37,9 @@
@else @else
@if($product->type == "configurable") @if($product->type == "configurable")
<div class="cart-wish-wrap"> <div class="cart-wish-wrap">
<button href="{{ route('cart.add.configurable', $product->url_key) }}" class="btn btn-lg btn-primary addtocart"> <a href="{{ route('cart.add.configurable', $product->url_key) }}" class="btn btn-lg btn-primary addtocart">
{{ __('shop::app.products.add-to-cart') }} {{ __('shop::app.products.add-to-cart') }}
</button> </a>
@include('shop::products.wishlist') @include('shop::products.wishlist')
</div> </div>

View File

@ -66,7 +66,7 @@
{{ $reviewHelper->getAverageRating($product) }} {{ $reviewHelper->getAverageRating($product) }}
</span> </span>
@for($i = 1; $i <= $reviewHelper->getAverageRating($product) ; $i++) @for($i=1;$i<=$reviewHelper->getAverageRating($product);$i++)
<span class="stars"> <span class="stars">
<span class="icon star-icon"></span> <span class="icon star-icon"></span>
</span> </span>

View File

@ -1,7 +1,7 @@
<div class="{{ $css->filter }}filter-wrapper"> <div class="{{ $css->filter }} filter-wrapper">
<div class="filter-row-one"> <div class="filter-row-one">
<div class="search-filter" style="display: inline-flex; align-items: center;"> <div class="search-filter" style="display: inline-flex; align-items: center;">
<input type="search" class="control search-field" placeholder="Search Users" value="" /> <input type="search" class="control search-field" placeholder="Search Here..." value="" />
<div class="ic-wrapper"> <div class="ic-wrapper">
<span class="icon search-icon search-btn"></span> <span class="icon search-icon search-btn"></span>
</div> </div>