Merge pull request #196 from bagisto/prashant

Prashant
This commit is contained in:
Prashant Singh 2018-11-28 14:54:46 +05:30 committed by GitHub
commit 6758e05b95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
91 changed files with 1829 additions and 876 deletions

View File

@ -11,6 +11,7 @@
"php": "^7.1.3",
"barryvdh/laravel-dompdf": "^0.8.0@dev",
"dimsav/laravel-translatable": "^9.0",
"doctrine/dbal": "^2.9@dev",
"fideloper/proxy": "^4.0",
"flynsarmy/db-blade-compiler": "*",
"intervention/image": "^2.4",

View File

@ -6,8 +6,10 @@ use Webkul\API\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Event;
use Webkul\Customer\Repositories\CustomerAddressRepository as CustomerAddress;
use Auth;
use Cart;
use Validator;
/**
* Address controller for the APIs Customer Address
@ -18,33 +20,107 @@ use Cart;
class AddressController extends Controller
{
protected $customer;
protected $customerAddress;
public function __construct()
public function __construct(CustomerAddress $customerAddress)
{
$this->middleware('auth:customer');
$this->customerAddress = $customerAddress;
if(auth()->guard('customer')->check()) {
$this->customer = auth()->guard('customer')->user();
} else {
return response()->json('Unauthorized', 401);
$this->customer['message'] = 'unauthorized';
$this->unAuthorized();
}
}
public function unAuthorized() {
return response()->json($this->customer, 401);
}
/**
* To get the details of user to display on profile
*
* @return response JSON
*/
public function getAddress() {
$addresses = $this->customer->addresses;
public function get() {
if($this->customer == false) {
return response()->json($this->customer, 401);
} else {
$addresses = $this->customer->addresses;
return response()->json($addresses, 200);
return response()->json($addresses, 200);
}
}
public function getDefaultAddress() {
public function getDefault() {
if($this->customer == false) {
return response()->json($this->customer, 401);
} else {
$defaultAddress = $this->customer->default_address;
if ($defaultAddress->count() > 0) {
return response()->json($defaultAddress, 200);
} else {
return response()->json(['false, default address not found'], 200);
}
}
}
public function create() {
$data = request()->all();
$validator = Validator::make(request()->all(), [
'address1' => 'string|required',
'address2' => 'string',
'country' => 'string|required',
'state' => 'string|required',
'city' => 'string|required',
'postcode' => 'required',
'phone' => 'required'
]);
if ($validator->fails()) {
return response()->json($validator->messages(), 400);
}
$cust_id['customer_id'] = $this->customer->id;
$data = array_merge($cust_id, $data);
if($this->customer->addresses->count() == 0) {
$data['default_address'] = 1;
}
$result = $this->customerAddress->create($data);
if($result) {
return response()->json(true, 200);
} else {
return response()->json(false, 200);
}
}
public function delete($id) {
$result = $this->customerAddress->delete($id);
return response()->json($result, 200);
}
public function makeDefault($id) {
$defaultAddress = $this->customer->default_address;
if($defaultAddress->count() > 0)
return response()->json($defaultAddress, 200);
else
if($defaultAddress != null && $defaultAddress->count() > 0) {
$defaultAddress->update(['default_address' => 0]);
}
if($this->customerAddress->find($id)->default_address == 1) {
return response()->json(false, 200);
}
$result = $this->customerAddress->update(['default_address' => 1], $id);
return response()->json($result, 200);
}
}

View File

@ -18,14 +18,6 @@ use Cart;
*/
class AuthController extends Controller
{
public function __construct()
{
// $this->middleware('customer')->except(['show','create']);
// $this->_config = request('_config');
// $subscriber = new CustomerEventsHandler;
// Event::subscribe($subscriber);
}
/**
* To get the details of user to display on profile
*
@ -34,10 +26,19 @@ class AuthController extends Controller
public function create() {
$data = request()->except('_token');
if(!auth()->guard('customer')->attempt($data)) {
return response()->json('Incorrect Credentials', 200);
if(!auth()->guard('customer')->check()) {
if(!auth()->guard('customer')->attempt($data)) {
return response()->json(['message' => 'unauthenticated', 'details' => 'invalid creds'], 401);
} else {
return response()->json(['message' => 'authenticated', 'user' => auth()->guard('customer')->user()], 200);
}
} else {
return response()->json(auth()->guard('customer')->user(), 200);
return response()->json(['message' => 'already authenticated'], 200);
}
}
public function destroy() {
auth()->guard('customer')->logout();
return response()->json(['message' => 'logged out'], 200);
}
}

View File

@ -8,6 +8,8 @@ use Illuminate\Http\Response;
use Illuminate\Support\Facades\Event;
use Auth;
use Cart;
use Validator;
use Hash;
/**
* Customer controller for the APIs of Profile customer
@ -24,16 +26,91 @@ class CustomerController extends Controller
if(auth()->guard('customer')->check()) {
$this->customer = auth()->guard('customer')->user();
} else {
return response()->json('Unauthorized', 401);
$this->customer['message'] = 'unauthorized';
$this->unAuthorized();
}
}
public function unAuthorized() {
return response()->json($this->customer, 401);
}
/**
* To get the details of user to display on profile
* Only accepts the id of simple or configurable product
*
* @return response JSON
*/
public function getProfile() {
return $this->customer;
public function getProfile()
{
return response()->json($this->customer, 200);
}
public function updateProfile($id)
{
$validator = Validator::make(request()->all(), [
'first_name' => 'string|required',
'last_name' => 'string|required',
'gender' => 'required',
'date_of_birth' => 'date',
'email' => 'email|required|unique:customers,email,'.$id,
'password' => 'confirmed|required_if:oldpassword,!=,null'
]);
if ($validator->fails()) {
return response()->json($validator->messages(), 400);
}
$data = collect(request()->all())->toArray();
if($data['oldpassword'] == null) {
$data = collect(request()->input())->except([ 'oldpassword', 'password', 'password_confirmation'])->toArray();
} else {
if(Hash::check($data['oldpassword'], auth()->guard('customer')->user()->password)) {
$data = collect(request()->input())->toArray();
$data['password'] = bcrypt($data['password']);
} else {
return response()->json('Old password does not match', 200);
}
}
$result = $this->customer->update($data);
if($result) {
return response()->json(true, 200);
} else {
return response()->json(false, 200);
}
}
/**
* Get all instances of cart for currently logged in customer
*
* @return collection Cart
*/
public function getAllCart() {
$carts = $this->customer->carts;
if($cart->count() > 0) {
return response()->json(['message' => 'successful','items' => $cart], 200);
} else {
return response()->json(['message' => 'empty', 'items' => null], 200);
}
}
public function getActiveCart() {
$cart = Cart::getCart();
if($cart == null) {
return response()->json(['message' => 'empty', 'items' => 'null']);
}
if($cart->count() > 0 ) {
return response()->json(['message' => 'success', 'items' => $cart]);
} else {
return response()->json(['message' => 'empty', 'items' => 'null']);
}
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace Webkul\API\Http\Controllers\Customer;
use Webkul\API\Http\Controllers\Controller;
use Webkul\Customer\Repositories\CustomerRepository as Customer;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Event;
use Validator;
/**
* Registration controller for the APIs of Customer Registration
*
* @author Prashant Singh <prashant.singh852@webkul.com> @prashant-webkul
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class RegistrationController extends Controller
{
protected $customer;
public function __construct(Customer $customer) {
$this->customer = $customer;
}
public function create() {
$validator = Validator::make(request()->all(), [
'first_name' => 'string|required',
'last_name' => 'string|required',
'email' => 'email|required|unique:customers,email',
'password' => 'confirmed|min:6|required',
'agreement' => 'required'
]);
if ($validator->fails()) {
return response()->json($validator->messages(), 400);
}
$data = request()->all();
$data['password'] = bcrypt($data['password']);
$data['channel_id'] = core()->getCurrentChannel()->id;
$data['is_verified'] = 0;
$result = $this->customer->create($data);
if ($result) {
return response()->json(true, 200);
} else {
return response()->json(false, 200);
}
}
}

View File

@ -5,6 +5,8 @@ namespace Webkul\API\Http\Controllers\Customer;
use Webkul\API\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Webkul\Product\Repositories\ProductRepository as Product;
use Webkul\Customer\Repositories\WishlistRepository as Wishlist;
use Auth;
use Cart;
@ -17,16 +19,26 @@ use Cart;
class WishlistController extends Controller
{
protected $customer;
protected $product;
protected $wishlist;
public function __construct()
public function __construct(Product $product, Wishlist $wishlist)
{
if(auth()->guard('customer')->check()) {
$this->product = $product;
$this->wishlist = $wishlist;
$this->customer = auth()->guard('customer')->user();
} else {
return response()->json('Unauthorized', 401);
$this->customer['message'] = 'unauthorized';
$this->unAuthorized();
}
}
public function unAuthorized()
{
return response()->json($this->customer, 401);
}
public function getWishlist()
{
$wishlist = $this->customer->wishlist_items;
@ -34,7 +46,57 @@ class WishlistController extends Controller
if($wishlist->count() > 0) {
return response()->json($wishlist, 200);
} else {
return response()->json('Wishlist Empty', 200);
return response()->json(['message' => 'Wishlist Empty', 'Items' => null], 200);
}
}
/**
* Function to add item to the wishlist.
* Only accepts the id of simple or configurable product
*
* @param integer $productId
*/
public function add($productId)
{
$product = $this->product->findOneByField('id', $productId);
$data = [
'channel_id' => core()->getCurrentChannel()->id,
'product_id' => $productId,
'customer_id' => auth()->guard('customer')->user()->id
];
//accidental case if some one adds id of the product in the anchor tag amd gives id of a variant.
if($product->parent_id != null) {
$data['product_id'] = $productId = $product->parent_id;
}
$checked = $this->wishlist->findWhere(['channel_id' => core()->getCurrentChannel()->id, 'product_id' => $productId, 'customer_id' => auth()->guard('customer')->user()->id]);
if($checked->isEmpty()) {
if($wishlistItem = $this->wishlist->create($data)) {
return response()->json(['message' => 'Successfully Added Item To Wishlist', 'items' => $wishlistItem], 200);
} else {
return response()->json(['message' => 'Error! Cannot Add Item To Wishlist', 'items' => null], 401);
}
} else {
return response()->json(['message' => trans('customer::app.wishlist.already'), 'items' => null], 200);
}
}
/**
* Function to remove item to the wishlist.
*
* @param integer $itemId
*/
public function delete($itemId)
{
$result = $this->wishlist->deleteWhere(['customer_id' => auth()->guard('customer')->user()->id, 'channel_id' => core()->getCurrentChannel()->id, 'id' => $itemId]);
if($result) {
return response()->json(['message' => 'Item Successfully Removed From Wishlist', 'status' => $result]);
} else {
return response()->json(['message' => 'Error! While Removing Item From Wishlist', 'status' => $result]);
}
}
}

View File

@ -6,32 +6,70 @@ use Webkul\API\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Webkul\Product\Repositories\ProductRepository as Product;
use Auth;
/**
* Product controller for the APIs of Getting Products
* Product controller
*
* @author Prashant Singh <prashant.singh852@webkul.com> @prashant-webkul
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class ProductController extends Controller
{
/**
* Contains route related configuration
*
* @var array
*/
protected $_config;
/**
* ProductRepository object
*
* @var array
*/
protected $product;
public function __construct(Product $product)
/**
* Create a new controller instance.
*
* @param Webkul\Product\Repositories\ProductRepository $product
* @return void
*/
public function __construct( Product $product)
{
$this->product = $product;
$this->_config = request('_config');
}
public function getAllProducts() {
/**
* Display a listing of the resource.
*
* @param string $slug
* @return \Illuminate\Http\Response
*/
public function getBySlug($slug)
{
$product = $this->product->findBySlugOrFail($slug);
return response()->json(['message' => 'success', 'product' => $product]);
}
public function getAll() {
$products = $this->product->all();
return response()->json($products, 200);
}
public function getNewProducts() {
$newProducts = $this->product->getNewProduct();
public function getNew() {
$newProducts = $this->product->getNewProducts();
return response()->json($newProducts, 200);
}
}
public function getFeatured() {
$featuredProducts = $this->product->getFeaturedProducts();
return response()->json($featuredProducts, 200);
}
}

View File

@ -0,0 +1,127 @@
<?php
namespace Webkul\API\Http\Controllers\Product;
use Webkul\API\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Webkul\Product\Repositories\ProductRepository as Product;
use Webkul\Product\Repositories\ProductReviewRepository as ProductReview;
use Webkul\Product\Helpers\Review;
use Validator;
/**
* Review controller
*
* @author Prashant Singh <prashant.singh852@webkul.com> @prashant-webkul
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class ReviewController extends Controller
{
/**
* Contains route related configuration
*
* @var array
*/
protected $_config;
/**
* ProductRepository object
*
* @var array
*/
protected $product;
/**
* ProductReviewRepository object
*
* @var array
*/
protected $productReview;
/**
* Review helper Object
*
*/
protected $reviewHelper;
/**
* Create a new controller instance.
*
* @param Webkul\Product\Repositories\ProductRepository $product
* @param Webkul\Product\Repositories\ProductReviewRepository $productReview
* @return void
*/
public function __construct(Product $product, ProductReview $productReview, Review $reviewHelper)
{
// $this->middleware('customer')->only(['create', 'store', 'destroy']);
$this->product = $product;
$this->productReview = $productReview;
$this->reviewHelper = $reviewHelper;
$this->_config = request('_config');
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request , $id)
{
$this->validate(request(), [
'comment' => 'required',
'rating' => 'required',
'title' => 'required',
]);
$data = request()->all();
$customer_id = auth()->guard('customer')->user()->id;
$data['status'] = 'pending';
$data['product_id'] = $id;
$data['customer_id'] = $customer_id;
$result = $this->productReview->create($data);
if($result) {
return response()->json(['message' => 'success', 'status' => $result]);
} else {
return response()->json(['message' => 'failed', 'status' => $result]);
}
}
/**
* Display reviews accroding to product.
*
* @param string $slug
* @return \Illuminate\Http\Response
*/
public function show($slug)
{
$product = $this->product->findBySlugOrFail($slug);
$productReviews = $this->reviewHelper->getReviews($product)->get();
return $productReviews;
}
/**
* Delete the review of the current product
*
* @return response
*/
public function destroy($id)
{
$this->productReview->delete($id);
session()->flash('success', 'Product Review Successfully Deleted');
return redirect()->back();
}
}

View File

@ -6,9 +6,11 @@ use Webkul\API\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Event;
use Auth;
// use Cart;
use Webkul\Checkout\Repositories\CartRepository;
use Webkul\Checkout\Repositories\CartItemRepository as CartItem;
use Webkul\API\Http\Controllers\Shop\Presenter as Presenter;
use Auth;
use Cart;
/**
* Cart controller for the APIs of User Cart
@ -19,31 +21,106 @@ use Webkul\Checkout\Repositories\CartRepository;
class CartController extends Controller
{
protected $customer;
protected $cart;
protected $cartItem;
public function __construct(CartRepository $cart)
public function __construct(CartRepository $cart, CartItem $cartItem)
{
$this->cart = $cart;
if(auth()->guard('customer')->check()) {
$this->customer = auth()->guard('customer')->user();
$this->cartItem = $cartItem;
}
/**
* Function to get the current cart instance for customer or guest
*
* @return Response array && Collection Cart
*/
public function get() {
$cart = Cart::getCart();
if($cart == null || $cart == 'null') {
return response()->json(['message' => 'empty', 'items' => null]);
}
return response()->json(['message' => 'success', 'items' => $cart]);
}
/**
* Function for guests user to add the product in the cart.
*
* @return Mixed
*/
public function add($id) {
$result = Cart::add($id, request()->all());
if($result) {
Cart::collectTotals();
return response()->json(['message' => 'successful', 'items' => Cart::getCart()->items]);
} else {
return response()->json('Unauthorized', 401);
return response()->json(['message' => 'failed', 'items' => Cart::getCart()->items]);
}
}
public function getAllCart() {
$carts = $this->customer->carts;
/**
* Removes the item from the cart if it exists
*
* @param integer $itemId
*/
public function remove($itemId) {
$result = Cart::removeItem($itemId);
if($cart->count() > 0) {
return response()->json($cart, 200);
} else {
return response()->json('Cart Empty', 200);
}
Cart::collectTotals();
return response()->json(['message' => $result, 'items' => Cart::getCart()]);
}
public function getActiveCart() {
return $this->customer->cart;
/**
* Before checkout starts or full details on the cart
*
* @return response json
*/
public function onePage() {
$cart = Cart::getCart();
if($cart == null || $cart == 'null') {
return response()->json(['message' => 'empty', 'items' => null]);
}
$presenter = new Presenter();
$summary = $presenter->onePagePresenter($cart);
return response()->json(['message' => 'success', 'items' => $cart->items, 'summary' => $summary]);
}
/**
* Updates the quantity of the items present in the cart.
*
* @return response JSON
*/
public function updateOnePage() {
$request = request()->except('_token');
foreach($request['qty'] as $id => $quantity) {
if($quantity <= 0) {
return response()->json(['message' => 'Illegal Quantity', 'status' => 'error']);
}
}
foreach($request['qty'] as $key => $value) {
$item = $this->cartItem->findOneByField('id', $key);
$data['quantity'] = $value;
$result = Cart::updateItem($item->product_id, $data, $key);
unset($item);
unset($data);
}
Cart::collectTotals();
return response()->json(['message' => 'success', 'items' => Cart::getCart()]);
}
}

View File

@ -0,0 +1,49 @@
<?php
namespace Webkul\API\Http\Controllers\Shop;
use Webkul\API\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Collection;
use Webkul\Category\Repositories\CategoryRepository as Category;
/**
* Category controller for getting the categories
*
* @author Prashant Singh <prashant.singh852@webkul.com> @prashant-webkul
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class CategoryController extends Controller
{
/**
* The category implementation.
*
* for shop bundle's navigation
* menu
*/
protected $category;
/**
* Category Repository DI.
*
* @param $category Category Instance
* @return void
*/
public function __construct(Category $category)
{
$this->category = $category;
}
public function get() {
$categories = [];
foreach ($this->category->getVisibleCategoryTree() as $category) {
array_push($categories, collect($category));
}
return $categories;
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace Webkul\API\Http\Controllers\Shop;
/**
* Presenter Class for cart and mini cart(if implemented)
*/
class Presenter {
/**
* presenter method will handle the cart and collect all the necessary data to be displayed on the onepage cart
*/
public function onePagePresenter($cart) {
$cartSummary['grand_total'] = $cart->grand_total;
$cartSummary['tax_total'] = $cart->tax_total;
$cartSummary['total_items'] = $cart->items_count;
$cartSummary['total_items_qty'] = $cart->items_qty;
$cartSummary['total_items_qty'] = $cart->items_qty;
return $cartSummary;
}
}

View File

@ -1,39 +1,76 @@
<?php
Route::group(['namespace' => 'Webkul\API\Http\Controllers\Customer', 'prefix' => 'api/customer'], function ($router) {
//customer registration API
Route::post('/register', 'RegistrationController@create');
//auth route for customer
Route::post('login', 'AuthController@create');
//auth route for customer
Route::post('logout', 'AuthController@destroy');
//get user
Route::get('get/user', 'CustomerController@getProfile');
//get customer profile
Route::get('get/profile', 'CustomerController@getProfile');
Route::put('update/profile/{id}', 'CustomerController@updateProfile');
//wishlist
//get wishlist
Route::get('get/wishlist', 'WishlistController@getWishlist');
//add the item in the wishlist
Route::get('add/wishlist/{id}', 'WishlistController@add');
//delete the item from the wishlist
Route::get('delete/wishlist/{id}', 'WishlistController@delete');
//Move the item from the wishlist to cart
// Route::get('delete/wishlist/{id}', 'WishlistController@delete');
//address
Route::get('get/address', 'AddressController@getAddress');
Route::get('get/default/address', 'AddressController@getDefaultAddress');
});
Route::get('get/address', 'AddressController@get');
Route::get('get/default/address', 'AddressController@getDefault');
Route::post('create/address', 'AddressController@create');
Route::put('make/default/address/{id}', 'AddressController@makeDefault');
Route::delete('delete/address/{id}', 'AddressController@delete');
Route::group(['namespace' => 'Webkul\API\Http\Controllers\Shop', 'prefix' => 'api/cart'], function ($router) {
//cart
//cart -> not to be used
//active + inactive instances of cart for the current logged in user
Route::get('get/all', 'CartController@getAllCart');
Route::get('get/all', 'CustomerController@getAllCart');
//active instances of cart for the current logged in user
Route::get('get/active', 'CartController@getActiveCart');
//inactive instances of cart for the current logged in user
Route::get('get/inactive', 'CartController@getInactiveCart');
Route::get('get/active', 'CustomerController@getActiveCart');
});
//all the cart related API for customer and guests
Route::group(['namespace' => 'Webkul\API\Http\Controllers\Shop', 'prefix' => 'api/cart'], function ($router) {
//cart
Route::get('get', 'CartController@get');
//add item in the cart
Route::post('add/{id}', 'CartController@add');
//remove item to the cart
Route::get('remove/{id}', 'CartController@remove');
//get cart and all item for cart checkout
Route::get('/onepage', 'CartController@onePage');
//update OnePage
Route::put('/update/onepage', 'CartController@updateOnePage');
});
//all the product related API to be used for store front
Route::group(['namespace' => 'Webkul\API\Http\Controllers\Product', 'prefix' => 'api/product'], function ($router) {
//product
//to fetch the new product
Route::get('get/all', 'ProductController@getAllProducts');
//to get all products
Route::get('get/all', 'ProductController@getAll');
//to fetch the new products
Route::get('get/new', 'ProductController@getNew');
//to fetch the featured product
Route::get('get/featured', 'ProductController@getFeatured');
//to get the product by its slug
Route::get('get/{slug}', 'ProductController@getBySlug');
//product reviews get and create
//to get the reviews of the product
Route::get('review/{slug}', 'ReviewController@show');
//to store the review for a product
Route::post('review/{slug}', 'ReviewController@create');
});
Route::group(['namespace' => 'Webkul\API\Http\Controllers\Admin', 'prefix' => 'api/admin'], function ($router) {
//all the shop related API to be used for store front
Route::group(['namespace' => 'Webkul\API\Http\Controllers\Shop', 'prefix' => 'api/shop'], function ($router) {
Route::get('get/category', 'CategoryController@get');
});

View File

@ -5,7 +5,6 @@ namespace Webkul\Admin\DataGrids;
use Illuminate\View\View;
use Webkul\Ui\DataGrid\Facades\DataGrid;
/**
* Attributes DataGrid
*
@ -33,12 +32,12 @@ class AttributeDataGrid
'aliased' => true,
'massoperations' => [
[
'route' => route('admin.datagrid.delete'),
'method' => 'DELETE',
'label' => 'Delete',
'type' => 'button',
],
// [
// 'route' => route('admin.datagrid.delete'),
// 'method' => 'DELETE',
// 'label' => 'Delete',
// 'type' => 'button',
// ],
],
'actions' => [
@ -148,20 +147,17 @@ class AttributeDataGrid
'alias' => 'attributeId',
'type' => 'number',
'label' => 'ID',
],
[
], [
'column' => 'code',
'alias' => 'attributeCode',
'type' => 'string',
'label' => 'Code',
],
[
], [
'column' => 'admin_name',
'alias' => 'attributeAdminName',
'type' => 'string',
'label' => 'AdminName',
],
[
'label' => 'Name',
], [
'column' => 'type',
'alias' => 'attributeType',
'type' => 'string',
@ -175,13 +171,11 @@ class AttributeDataGrid
'column' => 'code',
'alias' => 'attributeCode',
'type' => 'string',
],
[
], [
'column' => 'admin_name',
'alias' => 'attributeAdminName',
'type' => 'string',
],
[
], [
'column' => 'type',
'alias' => 'attributeType',
'type' => 'string',

View File

@ -33,12 +33,12 @@ class AttributeFamilyDataGrid
'aliased' => false, //use this with false as default and true in case of joins
'massoperations' =>[
[
'route' => route('admin.datagrid.delete'),
'method' => 'DELETE',
'label' => 'Delete',
'type' => 'button',
],
// [
// 'route' => route('admin.datagrid.delete'),
// 'method' => 'DELETE',
// 'label' => 'Delete',
// 'type' => 'button',
// ],
],
'actions' => [
@ -87,7 +87,7 @@ class AttributeFamilyDataGrid
'name' => 'name',
'alias' => 'attributeFamilyName',
'type' => 'string',
'label' => 'Code',
'label' => 'Name',
'sortable' => true,
],
],

View File

@ -33,12 +33,12 @@ class CategoryDataGrid
'aliased' => true, //use this with false as default and true in case of joins
'massoperations' =>[
[
'route' => route('admin.datagrid.delete'),
'method' => 'DELETE',
'label' => 'Delete',
'type' => 'button',
],
// [
// 'route' => route('admin.datagrid.delete'),
// 'method' => 'DELETE',
// 'label' => 'Delete',
// 'type' => 'button',
// ],
],
'actions' => [
@ -112,7 +112,7 @@ class CategoryDataGrid
'alias' => 'cat_locale',
'type' => 'string',
'label' => 'Locale',
'sortable' => true,
'sortable' => false,
'filter' => [
'function' => 'orWhere',
'condition' => ['ct.locale', app()->getLocale()]
@ -123,12 +123,12 @@ class CategoryDataGrid
'filterable' => [
[
'column' => 'cat.id',
'alias' => 'catID',
'alias' => 'cat_id',
'type' => 'number',
'label' => 'Category ID',
], [
'column' => 'ct.name',
'alias' => 'catName',
'alias' => 'cat_name',
'type' => 'string',
'label' => 'Category Name',
],
@ -140,7 +140,7 @@ class CategoryDataGrid
// ],
[
'column' => 'cat.status',
'alias' => 'catStatus',
'alias' => 'cat_status',
'type' => 'string',
'label' => 'Visible in Menu',
],

View File

@ -33,12 +33,12 @@ class ChannelDataGrid
'aliased' => false, //use this with false as default and true in case of joins
'massoperations' =>[
[
'route' => route('admin.datagrid.delete'),
'method' => 'DELETE',
'label' => 'Delete',
'type' => 'button',
],
// [
// 'route' => route('admin.datagrid.delete'),
// 'method' => 'DELETE',
// 'label' => 'Delete',
// 'type' => 'button',
// ],
],
'actions' => [

View File

@ -33,12 +33,12 @@ class CountryDataGrid
'aliased' => false, //use this with false as default and true in case of joins
'massoperations' =>[
[
'route' => route('admin.datagrid.delete'),
'method' => 'DELETE',
'label' => 'Delete',
'type' => 'button',
],
// [
// 'route' => route('admin.datagrid.delete'),
// 'method' => 'DELETE',
// 'label' => 'Delete',
// 'type' => 'button',
// ],
],
'actions' => [

View File

@ -32,12 +32,12 @@ class CurrencyDataGrid
'aliased' => false, //use this with false as default and true in case of joins
'massoperations' =>[
[
'route' => route('admin.datagrid.delete'),
'method' => 'DELETE',
'label' => 'Delete',
'type' => 'button',
],
// [
// 'route' => route('admin.datagrid.delete'),
// 'method' => 'DELETE',
// 'label' => 'Delete',
// 'type' => 'button',
// ],
],
'actions' => [

View File

@ -31,12 +31,12 @@ class CustomerDataGrid
'aliased' => true, //use this with false as default and true in case of joins
'massoperations' =>[
[
'route' => route('admin.datagrid.delete'),
'method' => 'DELETE',
'label' => 'Delete',
'type' => 'button', //select || button only
],
// [
// 'route' => route('admin.datagrid.delete'),
// 'method' => 'DELETE',
// 'label' => 'Delete',
// 'type' => 'button', //select || button only
// ],
],
'actions' => [

View File

@ -32,23 +32,23 @@ class CustomerGroupDataGrid
'aliased' => true, //use this with false as default and true in case of joins
'massoperations' =>[
[
'route' => route('admin.datagrid.delete'),
'method' => 'DELETE',
'label' => 'Delete',
'type' => 'button',
],
[
'route' => route('admin.datagrid.index'),
'method' => 'POST',
'label' => 'View Grid',
'type' => 'select',
'options' =>[
1 => 'Edit',
2 => 'Set',
3 => 'Change Status'
]
],
// [
// 'route' => route('admin.datagrid.delete'),
// 'method' => 'DELETE',
// 'label' => 'Delete',
// 'type' => 'button',
// ],
// [
// 'route' => route('admin.datagrid.index'),
// 'method' => 'POST',
// 'label' => 'View Grid',
// 'type' => 'select',
// 'options' =>[
// 1 => 'Edit',
// 2 => 'Set',
// 3 => 'Change Status'
// ]
// ],
],
'actions' => [
[

View File

@ -33,12 +33,12 @@ class ExchangeRatesDataGrid
'aliased' => true, //use this with false as default and true in case of joins
'massoperations' =>[
[
'route' => route('admin.datagrid.delete'),
'method' => 'DELETE',
'label' => 'Delete',
'type' => 'button',
],
// [
// 'route' => route('admin.datagrid.delete'),
// 'method' => 'DELETE',
// 'label' => 'Delete',
// 'type' => 'button',
// ],
],
'actions' => [
@ -68,54 +68,47 @@ class ExchangeRatesDataGrid
//use aliasing on secodary columns if join is performed
'columns' => [
[
'name' => 'cer.id',
'alias' => 'exchID',
'alias' => 'exchid',
'type' => 'number',
'label' => 'Rate ID',
'sortable' => true,
],
[
], [
'name' => 'curr.name',
'alias' => 'currencyname',
'alias' => 'exchcurrname',
'type' => 'string',
'label' => 'Currency Name',
'sortable' => true,
],
[
], [
'name' => 'cer.rate',
'alias' => 'exchRate',
'alias' => 'exchrate',
'type' => 'string',
'label' => 'Exchange Rate',
],
],
//don't use aliasing in case of filters
'filterable' => [
[
'column' => 'cer.id',
'alias' => 'exchId',
'alias' => 'exchid',
'type' => 'number',
'label' => 'Rate ID',
],
[
], [
'column' => 'curr.name',
'alias' => 'exchTargetCurrency',
'alias' => 'exchcurrname',
'type' => 'string',
'label' => 'Target Currency',
'sortable' => true,
'label' => 'Currency Name',
],
],
//don't use aliasing in case of searchables
'searchable' => [
[
'column' => 'target_currency',
'column' => 'exchcurrname',
'type' => 'string',
'label' => 'Target Currency',
'label' => 'Currency Name',
],
],

View File

@ -31,12 +31,12 @@ class InventorySourcesDataGrid
'aliased' => false, //use this with false as default and true in case of joins
'massoperations' =>[
[
'route' => route('admin.datagrid.delete'),
'method' => 'DELETE',
'label' => 'Delete',
'type' => 'button',
],
// [
// 'route' => route('admin.datagrid.delete'),
// 'method' => 'DELETE',
// 'label' => 'Delete',
// 'type' => 'button',
// ],
],
'actions' => [

View File

@ -32,12 +32,12 @@ class LocalesDataGrid
'aliased' => false, //use this with false as default and true in case of joins
'massoperations' =>[
[
'route' => route('admin.datagrid.delete'),
'method' => 'DELETE',
'label' => 'Delete',
'type' => 'button',
],
// [
// 'route' => route('admin.datagrid.delete'),
// 'method' => 'DELETE',
// 'label' => 'Delete',
// 'type' => 'button',
// ],
],
'actions' => [

View File

@ -31,21 +31,22 @@ class OrderInvoicesDataGrid
'aliased' => false,
'massoperations' =>[
[
'route' => route('admin.datagrid.delete'),
'method' => 'DELETE',
'label' => 'Delete',
'type' => 'button',
],
// [
// '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' => '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?',
@ -53,7 +54,15 @@ class OrderInvoicesDataGrid
// ]
],
'join' => [],
'join' => [
[
'join' => 'leftjoin',
'table' => 'orders as ors',
'primaryKey' => 'inv.order_id',
'condition' => '=',
'secondaryKey' => 'ors.id',
]
],
//use aliasing on secodary columns if join is performed
@ -65,23 +74,29 @@ class OrderInvoicesDataGrid
'label' => 'ID',
'sortable' => true
], [
'name' => 'inv.state',
'alias' => 'invstate',
'name' => 'inv.order_id',
'alias' => 'invorderid',
'type' => 'number',
'label' => 'State',
'label' => 'Order ID',
'sortable' => true
], [
'name' => 'inv.total_qty',
'alias' => 'invtotalqty',
'type' => 'number',
'label' => 'Quantity',
'sortable' => true
'name' => 'inv.state',
'alias' => 'invstate',
'type' => 'string',
'label' => 'State',
'sortable' => false
], [
'name' => 'inv.grand_total',
'alias' => 'invgrandtotal',
'type' => 'number',
'label' => 'Grand Total',
'sortable' => true
'label' => 'Amount',
'sortable' => false
], [
'name' => 'inv.created_at',
'alias' => 'invcreated_at',
'type' => 'date',
'label' => 'Invoice Date',
'sortable' => false
]
],

View File

@ -4,6 +4,7 @@ namespace Webkul\Admin\DataGrids;
use Illuminate\View\View;
use Webkul\Ui\DataGrid\Facades\DataGrid;
use DB;
/**
* OrderShipmentsDataGrid
@ -22,41 +23,42 @@ class OrderShipmentsDataGrid
*/
public function createOrderShipmentsDataGrid()
{
return DataGrid::make([
'name' => 'shipments',
'table' => 'shipments as ship',
'select' => 'ship.id',
'perpage' => 10,
'aliased' => false,
'aliased' => true,
'massoperations' =>[
[
'route' => route('admin.datagrid.delete'),
'method' => 'DELETE',
'label' => 'Delete',
'type' => 'button',
],
// [
// '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',
// ]
[
'type' => 'View',
'route' => route('admin.datagrid.delete'),
'confirm_text' => 'Do you really want to do this?',
'icon' => 'icon pencil-lg-icon',
],
],
'join' => [],
'join' => [
[
'join' => 'leftjoin',
'table' => 'orders as ors',
'primaryKey' => 'ship.order_id',
'condition' => '=',
'secondaryKey' => 'ors.id',
]
],
//use aliasing on secodary columns if join is performed
'columns' => [
[
'name' => 'ship.id',
@ -64,6 +66,33 @@ class OrderShipmentsDataGrid
'type' => 'number',
'label' => 'ID',
'sortable' => true
], [
'name' => 'ship.order_id',
'alias' => 'order_id',
'type' => 'number',
'label' => 'Order ID',
'sortable' => true
], [
'name' => 'ship.total_qty',
'alias' => 'total_qty',
'type' => 'number',
'label' => 'Total Quantity',
'sortable' => true
], [
'name' => 'ors.customer_first_name',
'alias' => 'order_customer_first_name',
'type' => 'string',
'label' => 'Customer Name',
'sortable' => false,
// 'wrapper' => function($value) {
// return $value.$last_name;
// }
], [
'name' => 'ors.created_at',
'alias' => 'orscreated',
'type' => 'date',
'label' => 'Order Date',
'sortable' => true
], [
'name' => 'ship.status',
'alias' => 'shipstatus',
@ -81,8 +110,16 @@ class OrderShipmentsDataGrid
return '<span class="badge badge-md badge-info">Closed</span>';
else if($value == "pending")
return '<span class="badge badge-md badge-warning">Pending</span>';
else
return 'Un-Attended';
},
],
], [
'name' => 'ship.created_at',
'alias' => 'ship_date',
'type' => 'string',
'label' => 'Shipment Date',
'sortable' => false
]
],
'filterable' => [

View File

@ -168,7 +168,6 @@ class ProductDataGrid
'nlike' => "not like",
],
// 'css' => []
]);
}

View File

@ -34,12 +34,12 @@ class ProductReviewDataGrid
'aliased' => true, //use this with false as default and true in case of joins
'massoperations' =>[
[
'route' => route('admin.datagrid.delete'),
'method' => 'DELETE',
'label' => 'Delete',
'type' => 'button',
],
// [
// 'route' => route('admin.datagrid.delete'),
// 'method' => 'DELETE',
// 'label' => 'Delete',
// 'type' => 'button',
// ],
],
'actions' => [

View File

@ -33,12 +33,12 @@ class RolesDataGrid
'aliased' => false, //use this with false as default and true in case of joins
'massoperations' =>[
[
'route' => route('admin.datagrid.delete'),
'method' => 'DELETE',
'label' => 'Delete',
'type' => 'button',
],
// [
// 'route' => route('admin.datagrid.delete'),
// 'method' => 'DELETE',
// 'label' => 'Delete',
// 'type' => 'button',
// ],
],
'actions' => [

View File

@ -32,12 +32,12 @@ class SliderDataGrid
'aliased' => true, //use this with false as default and true in case of joins
'massoperations' =>[
[
'route' => route('admin.datagrid.delete'),
'method' => 'DELETE',
'label' => 'Delete',
'type' => 'button',
],
// [
// 'route' => route('admin.datagrid.delete'),
// 'method' => 'DELETE',
// 'label' => 'Delete',
// 'type' => 'button',
// ],
],
'actions' => [

View File

@ -32,23 +32,23 @@ class TaxCategoryDataGrid
'aliased' => true, //use this with false as default and true in case of joins
'massoperations' =>[
[
'route' => route('admin.datagrid.delete'),
'method' => 'DELETE',
'label' => 'Delete',
'type' => 'button',
],
[
'route' => route('admin.datagrid.index'),
'method' => 'POST',
'label' => 'View Grid',
'type' => 'select',
'options' =>[
1 => 'Edit',
2 => 'Set',
3 => 'Change Status'
]
],
// [
// 'route' => route('admin.datagrid.delete'),
// 'method' => 'DELETE',
// 'label' => 'Delete',
// 'type' => 'button',
// ],
// [
// 'route' => route('admin.datagrid.index'),
// 'method' => 'POST',
// 'label' => 'View Grid',
// 'type' => 'select',
// 'options' =>[
// 1 => 'Edit',
// 2 => 'Set',
// 3 => 'Change Status'
// ]
// ],
],
'actions' => [
[

View File

@ -31,23 +31,23 @@ class TaxRateDataGrid
'aliased' => true, //use this with false as default and true in case of joins
'massoperations' =>[
[
'route' => route('admin.datagrid.delete'),
'method' => 'DELETE',
'label' => 'Delete',
'type' => 'button',
],
[
'route' => route('admin.datagrid.index'),
'method' => 'POST',
'label' => 'View Grid',
'type' => 'select',
'options' =>[
1 => 'Edit',
2 => 'Set',
3 => 'Change Status'
]
],
// [
// 'route' => route('admin.datagrid.delete'),
// 'method' => 'DELETE',
// 'label' => 'Delete',
// 'type' => 'button',
// ],
// [
// 'route' => route('admin.datagrid.index'),
// 'method' => 'POST',
// 'label' => 'View Grid',
// 'type' => 'select',
// 'options' =>[
// 1 => 'Edit',
// 2 => 'Set',
// 3 => 'Change Status'
// ]
// ],
],
'actions' => [
[

View File

@ -32,25 +32,26 @@ class UserDataGrid
'perpage' => 10,
'aliased' => true, //use this with false as default and true in case of joins
'massoperations' =>[
[
'route' => route('admin.datagrid.delete'),
'method' => 'DELETE',
'label' => 'Delete',
'type' => 'button',
],
[
'route' => route('admin.datagrid.index'),
'method' => 'POST',
'label' => 'View Grid',
'type' => 'select',
'options' =>[
1 => 'Edit',
2 => 'Set',
3 => 'Change Status'
]
],
'massoperations' => [
// [
// 'route' => route('admin.datagrid.delete'),
// 'method' => 'DELETE',
// 'label' => 'Delete',
// 'type' => 'button',
// ],
// [
// 'route' => route('admin.datagrid.index'),
// 'method' => 'POST',
// 'label' => 'View Grid',
// 'type' => 'select',
// 'options' =>[
// 1 => 'Edit',
// 2 => 'Set',
// 3 => 'Change Status'
// ]
// ],
],
'actions' => [
[
'type' => 'Edit',

View File

@ -4,10 +4,8 @@ namespace Webkul\Admin\Listeners;
use Webkul\Product\Repositories\ProductRepository;
use Webkul\Product\Repositories\ProductGridRepository;
use Webkul\Product\Helpers\Price;
/**
* Products Event handler
*
@ -15,7 +13,6 @@ use Webkul\Product\Helpers\Price;
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class Product {
/**
* Product Repository Object
*/
@ -28,7 +25,6 @@ class Product {
*/
Protected $price;
/**
* Product Grid Repository Object
*/
@ -43,87 +39,19 @@ class Product {
$this->price = $price;
}
/**
* Prepare the data from the product created
*
* @return array $data
*/
public function prepareData($product) {
$gridObject = [];
$variantObjects = [];
$gridObject = [
'product_id' => $product->id,
'sku' => $product->sku,
'type' => $product->type,
'attribute_family_name' => $product->attribute_family->name,
];
if($this->productGrid->findOneByField('product_id', $product->id)) {
$gridObject['name'] = $product->name;
$gridObject['status'] = $product->status;
if($product->type == 'configurable') {
$gridObject['quantity'] = 0;
$gridObject['price'] = 0;
$variants = $product->variants;
if(count($variants)) {
foreach($variants as $variant) {
$variantObject = [
'product_id' => $variant->id,
'sku' => $variant->sku,
'type' => $variant->type,
'attribute_family_name' => $variant->toArray()['attribute_family']['name'],
'name' => $variant->name,
'status' => $variant->status,
];
$qty = 0;
//inventories and inventory sources relation for the variants return empty or null collection objects only
foreach($variant->inventories()->get() as $inventory_source) {
$qty = $qty + $inventory_source->qty;
}
$variantObject['price'] = $variant->price;
$variantObject['quantity'] = $qty;
array_push($variantObjects, $variantObject);
$qty = 0;
}
}
} else {
$qty = 0;
foreach($product->inventories()->get() as $inventory_source) {
$qty = $qty + $inventory_source->qty;
}
$gridObject['price'] = $product->price;
$gridObject['quantity'] = $qty;
$qty = 0;
}
}
return [
'parent' => $gridObject,
'variants' => $variantObjects
];
}
/**
* Creates a new entry in the product grid whenever a new product is created.
*
* @return boolean
*/
public function afterProductCreated($product) {
$data = $this->prepareData($product);
$result = $this->productCreated($product);
$result = $this->saveProduct($product, $data);
return $result;
if($result) {
return true;
} else {
return false;
}
}
/**
@ -131,38 +59,41 @@ class Product {
*
* @return boolean
*/
public function saveProduct($product, $data) {
public function productCreated($product) {
$gridObject = [
'product_id' => $product->id,
'sku' => $product->sku,
'type' => $product->type,
'attribute_family_name' => 'default',
'name' => $product->name,
'quantity' => 0,
'status' => $product->status,
'price' => $product->price
];
$productGridObject = $this->productGrid->findOneByField('product_id', $product->id);
// dd($product, $data, $productGridObject);
if(!is_null($productGridObject)) {
if($product->type == 'simple') {
$r = $productGridObject->update($data['parent']);
} else {
$productGridObject->update($data['parent']);
$variants = [];
if(count($data['variants'])) {
foreach($data['variants'] as $variant) {
$variantObject = $this->productGrid->findOneByField('product_id', $variant['product_id']);
$this->productGrid->create($gridObject);
if(!is_null($variantObject)) {
$variantObject->update($variant);
} else {
$this->productGrid->create($variant);
}
}
}
}
} else {
$this->productGrid->create($data['parent']);
if($product->type == 'configurable') {
$variants = $product->variants()->get();
//no need for these lines
if(count($data['variants'])) {
foreach($data['variants'] as $variant) {
$this->productGrid->create($variant);
}
foreach($variants as $variant) {
$variantObj = [
'product_id' => $variant->id,
'sku' => $variant->sku,
'type' => $variant->type,
'attibute_family_name' => 'default',
'name' => $variant->name,
'quantity' => 0,
'status' => $variant->status,
'price' => $variant->price,
];
$this->productGrid->create($variantObj);
}
}
return true;
}
@ -171,7 +102,114 @@ class Product {
*
* @return boolean
*/
public function beforeProductUpdate($productId) {
// public function beforeProductUpdate($productId) {
// return true;
// }
/**
* Event handle for after.product.update
*
* @return boolean
*/
public function afterProductUpdate($product) {
$result = $this->productUpdated($product);
return $result;
}
/**
* This will be invoked from afterProductUpdate
*
* @return boolean
*/
public function productUpdated($product) {
$productGridObject = $this->productGrid->findOneByField('product_id', $product->id);
if(!$productGridObject) {
return false;
}
$gridObject = [
'product_id' => $product->id,
'sku' => $product->sku,
'type' => $product->type,
'attribute_family_name' => 'default',
'name' => $product->name,
'status' => $product->status,
];
if($product->type == 'configurable') {
$gridObject['quantity'] = 0;
$gridObject['price'] = 0;
} else {
$qty = 0;
//inventories and inventory sources relation for the variants return empty or null collection objects only
foreach($product->inventories()->get() as $inventory_source) {
$qty = $qty + $inventory_source->qty;
}
$gridObject['quantity'] = $qty;
$gridObject['price'] = $product->price;
}
$this->productGrid->update($gridObject, $productGridObject->id);
if ($product->type == 'configurable') {
$variants = $product->variants()->get();
foreach($variants as $variant) {
$variantObj = [
'product_id' => $variant->id,
'sku' => $variant->sku,
'type' => $variant->type,
'attibute_family_name' => 'name',
'name' => $variant->name,
'status' => $variant->status,
'price' => $variant->price,
];
$qty = 0;
//inventories and inventory sources relation for the variants return empty or null collection objects only
foreach($variant->inventories()->get() as $inventory_source) {
$qty = $qty + $inventory_source->qty;
}
$variantObj['quantity'] = $qty;
$qty = 0;
$productGridVariant = $this->productGrid->findOneByField('product_id', $variant->id);
if(isset($productGridVariant)) {
$this->productGrid->update($variantObj, $productGridVariant->id);
} else {
$variantObj = [
'product_id' => $variant->id,
'sku' => $variant->sku,
'type' => $variant->type,
'attibute_family_name' => 'default',
'name' => $variant->name,
'status' => $variant->status,
'price' => $variant->price,
];
$qty = 0;
//inventories and inventory sources relation for the variants return empty or null collection objects only
foreach($variant->inventories()->get() as $inventory_source) {
$qty = $qty + $inventory_source->qty;
}
$variantObj['quantity'] = $qty;
$qty = 0;
$this->productGrid->create($variantObj);
}
}
}
return true;
}

View File

@ -448,6 +448,57 @@ return [
'delete-success' => 'Cannot Delete The Last Slider Item',
'delete-fail' => 'Slider Item Successfully Deleted'
],
'tax-categories' => [
'title' => 'Tax Categories',
'add-title' => 'Create Tax Category',
'edit-title' => 'Edit Tax Category',
'save-btn-title' => 'Save Tax Category',
'general' => 'Tax Category',
'select-channel' => 'Select Channel',
'name' => 'Name',
'code' => 'Code',
'description' => 'Description',
'select-taxrates' => 'Select Tax Rates',
'edit' => [
'title' => 'Edit Tax Category',
'edit-button-title' => 'Edit Tax Category'
],
'create-success' => 'New Tax Category Created',
'create-error' => 'Error, While Creating Tax Category',
'update-success' => 'Successfully Updated Tax Category',
'update-error' => 'Error While Updating Tax Category',
'atleast-one' => 'Cannot Delete The Last Tax Category',
'delete' => 'Tax Category Successfully Deleted'
],
'tax-rates' => [
'title' => 'Tax Rates',
'add-title' => 'Create Tax Rate',
'edit-title' => 'Edit Tax Rate',
'save-btn-title' => 'Create Tax Rate',
'general' => 'Tax Rate',
'identifier' => 'Identifier',
'is_zip' => 'Enable Zip Range',
'zip_from' => 'Zip From',
'zip_to' => 'Zip To',
'state' => 'State',
'select-state' => 'Select a region, state or province.',
'country' => 'Country',
'tax_rate' => 'Rate',
'edit' => [
'title' => 'Edit Tax Rate',
'edit-button-title' => 'Edit Rate'
],
'zip_code' => 'Zip Code',
'is_zip' => 'Enable Zip Range',
'create-success' => 'Tax Rate Created Successfully',
'create-error' => 'Cannot Create Tax Rate',
'update-success' => 'Tax Rate Updated Successfully',
'update-error' => 'Error! Tax Rate Cannot Be Updated',
'delete' => 'Tax Rate Deleted Successfully',
'atleast-one' => 'Cannot Delete Last Tax Rate'
],
],
'customers' => [

View File

@ -1,7 +1,7 @@
@extends('admin::layouts.content')
@section('page_title')
{{ __('admin::app.configuration.tax-categories.add-title') }}
{{ __('admin::app.settings.tax-categories.add-title') }}
@stop
@section('content')
@ -9,12 +9,12 @@
<form method="POST" action="{{ route('admin.tax-categories.create') }}" @submit.prevent="onSubmit">
<div class="page-header">
<div class="page-title">
<h1>{{ __('admin::app.configuration.tax-categories.add-title') }}</h1>
<h1>{{ __('admin::app.settings.tax-categories.add-title') }}</h1>
</div>
<div class="page-action">
<button type="submit" class="btn btn-lg btn-primary">
{{ __('admin::app.configuration.tax-categories.save-btn-title') }}
{{ __('admin::app.settings.tax-categories.save-btn-title') }}
</button>
</div>
</div>
@ -62,7 +62,7 @@
<span class="control-error" v-if="errors.has('description')">@{{ errors.first('description') }}</span>
</div>
<div class="control-group" :class="[errors.has('taxrates') ? 'has-error' : '']">
<div class="control-group" :class="[errors.has('taxrates[]') ? 'has-error' : '']">
<label for="taxrates" class="required">{{ __('admin::app.configuration.tax-categories.select-taxrates') }}</label>
<select multiple="multiple" v-validate="'required'" class="control" id="taxrates" name="taxrates[]" data-vv-as="&quot;{{ __('admin::app.configuration.tax-categories.select-taxrates') }}&quot;" value="{{ old('taxrates') }}">
@ -71,7 +71,7 @@
@endforeach
</select>
<span class="control-error" v-if="errors.first('taxrates')">@{{ errors.first('taxrates') }}</span>
<span class="control-error" v-if="errors.first('taxrates[]')">@{{ errors.first('taxrates[]') }}</span>
</div>
</div>

View File

@ -1,7 +1,7 @@
@extends('admin::layouts.content')
@section('page_title')
{{ __('admin::app.configuration.tax-categories.title') }}
{{ __('admin::app.settings.tax-categories.title') }}
@stop
@section('content')
@ -9,12 +9,12 @@
<form method="POST" action="{{ route('admin.tax-categories.update', $taxCategory->id) }}" @submit.prevent="onSubmit">
<div class="page-header">
<div class="page-title">
<h1>{{ __('admin::app.configuration.tax-categories.edit.title') }}</h1>
<h1>{{ __('admin::app.settings.tax-categories.edit.title') }}</h1>
</div>
<div class="page-action">
<button type="submit" class="btn btn-lg btn-primary">
{{ __('admin::app.configuration.tax-categories.save-btn-title') }}
{{ __('admin::app.settings.tax-categories.save-btn-title') }}
</button>
</div>
</div>
@ -23,72 +23,49 @@
<div class="form-container">
@csrf()
@method('PUT')
<accordian :title="'{{ __('admin::app.configuration.tax-categories.general') }}'" :active="true">
<div slot="body">
<div class="control-group" :class="[errors.has('channel') ? 'has-error' : '']">
<label for="channel" class="required">{{ __('admin::app.settings.tax-categories.select-channel') }}</label>
<div class="control-group" :class="[errors.has('channel') ? 'has-error' : '']">
<label for="channel" class="required">{{ __('admin::app.configuration.tax-categories.select-channel') }}</label>
<select class="control" name="channel_id">
@foreach(core()->getAllChannels() as $channelModel)
<select class="control" name="channel">
@foreach(core()->getAllChannels() as $channelModel)
<option @if($taxCategory->channel_id == $channelModel->id) selected @endif value="{{ $channelModel->id }}">
{{ $channelModel->name }}
</option>
<option @if($taxCategory->channel_id == $channelModel->id) selected @endif value="{{ $channelModel->id }}">
{{ $channelModel->name }}
</option>
@endforeach
</select>
@endforeach
</select>
<span class="control-error" v-if="errors.has('channel')">@{{ errors.first('channel') }}</span>
</div>
<span class="control-error" v-if="errors.has('channel')">@{{ errors.first('channel') }}</span>
</div>
<div class="control-group" :class="[errors.has('code') ? 'has-error' : '']">
<label for="code" class="required">{{ __('admin::app.settings.tax-categories.code') }}</label>
<div class="control-group" :class="[errors.has('code') ? 'has-error' : '']">
<label for="code" class="required">{{ __('admin::app.configuration.tax-categories.code') }}</label>
<input v-validate="'required'" class="control" id="code" name="code" data-vv-as="&quot;{{ __('admin::app.configuration.tax-categories.code') }}&quot;" value="{{ $taxCategory->code }}"/>
<input v-validate="'required'" class="control" id="code" name="code" data-vv-as="&quot;{{ __('admin::app.configuration.tax-categories.code') }}&quot;" value="{{ $taxCategory->code }}"/>
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
<label for="name" class="required">{{ __('admin::app.settings.tax-categories.name') }}</label>
<input v-validate="'required'" class="control" id="name" name="name" data-vv-as="&quot;{{ __('admin::app.configuration.tax-categories.name') }}&quot;" value="{{ $taxCategory->name }}"/>
<span class="control-error" v-if="errors.has('code')">@{{ errors.first('code') }}</span>
</div>
<div class="control-group" :class="[errors.has('description') ? 'has-error' : '']">
<label for="description" class="required">{{ __('admin::app.settings.tax-categories.description') }}</label>
<textarea v-validate="'required'" class="control" id="description" name="description" data-vv-as="&quot;{{ __('admin::app.configuration.tax-categories.description') }}&quot;">
{{ $taxCategory->description }}
</textarea>
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
<label for="name" class="required">{{ __('admin::app.configuration.tax-categories.name') }}</label>
<div class="control-group" :class="[errors.has('taxrates[]') ? 'has-error' : '']">
<label for="taxrates" class="required">{{ __('admin::app.settings.tax-categories.select-taxrates') }}</label>
<input v-validate="'required'" class="control" id="name" name="name" data-vv-as="&quot;{{ __('admin::app.configuration.tax-categories.name') }}&quot;" value="{{ $taxCategory->name }}"/>
<span class="control-error" v-if="errors.has('name')">@{{ errors.first('name') }}</span>
</div>
<div class="control-group" :class="[errors.has('description') ? 'has-error' : '']">
<label for="description" class="required">{{ __('admin::app.configuration.tax-categories.description') }}</label>
<textarea v-validate="'required'" class="control" id="description" name="description" data-vv-as="&quot;{{ __('admin::app.configuration.tax-categories.description') }}&quot;">
{{ $taxCategory->description }}
</textarea>
<span class="control-error" v-if="errors.has('description')">@{{ errors.first('description') }}</span>
</div>
<div class="control-group" :class="[errors.has('taxrates') ? 'has-error' : '']">
<label for="taxrates" class="required">{{ __('admin::app.configuration.tax-categories.select-taxrates') }}</label>
@inject('taxRates', 'Webkul\Tax\Repositories\TaxRateRepository')
<select multiple="multiple" class="control" id="taxrates" name="taxrates[]" data-vv-as="&quot;{{ __('admin::app.configuration.tax-categories.taxrates') }}&quot;" v-validate="'required'">
@foreach($taxRates->all() as $taxRate)
<option value="{{ $taxRate->id }}" {{ is_numeric($taxCategory->pluck('id')->search($taxRate->id)) ? 'selected' : '' }}>
{{ $taxRate->identifier }}
</option>
@endforeach
</select>
<span class="control-error" v-if="errors.has('taxrates')">@{{ errors.first('taxrates[]') }}</span>
</div>
</div>
</accordian>
@inject('taxRates', 'Webkul\Tax\Repositories\TaxRateRepository')
<select multiple="multiple" class="control" id="taxrates" name="taxrates[]" data-vv-as="&quot;{{ __('admin::app.settings.tax-categories.select-taxrates') }}&quot;" v-validate="'required'">
@foreach($taxRates->all() as $taxRate)
<option value="{{ $taxRate->id }}" {{ is_numeric($taxCategory->tax_rates->pluck('id')->search($taxRate->id)) ? 'selected' : '' }}>{{ $taxRate->identifier }}</option>
@endforeach
</select>
<span class="control-error" v-if="errors.has('taxrates[]')">@{{ errors.first('taxrates[]') }}</span>
</div>
</div>
</div>
</form>

View File

@ -1,19 +1,19 @@
@extends('admin::layouts.content')
@section('page_title')
{{ __('admin::app.configuration.tax-categories.title') }}
{{ __('admin::app.settings.tax-categories.title') }}
@stop
@section('content')
<div class="content">
<div class="page-header">
<div class="page-title">
<h1>{{ __('admin::app.configuration.tax-categories.title') }}</h1>
<h1>{{ __('admin::app.settings.tax-categories.title') }}</h1>
</div>
<div class="page-action">
<a href="{{ route('admin.tax-categories.show') }}" class="btn btn-lg btn-primary">
{{ __('admin::app.configuration.tax-categories.add-title') }}
{{ __('admin::app.settings.tax-categories.add-title') }}
</a>
</div>
</div>

View File

@ -1,7 +1,7 @@
@extends('admin::layouts.content')
@section('page_title')
{{ __('admin::app.configuration.tax-rates.add-title') }}
{{ __('admin::app.settings.tax-rates.add-title') }}
@stop
@section('content')
@ -9,12 +9,12 @@
<form method="POST" action="{{ route('admin.tax-rates.create') }}" @submit.prevent="onSubmit">
<div class="page-header">
<div class="page-title">
<h1>{{ __('admin::app.configuration.tax-rates.add-title') }}</h1>
<h1>{{ __('admin::app.settings.tax-rates.add-title') }}</h1>
</div>
<div class="page-action">
<button type="submit" class="btn btn-lg btn-primary">
{{ __('admin::app.configuration.tax-rates.save-btn-title') }}
{{ __('admin::app.settings.tax-rates.save-btn-title') }}
</button>
</div>
</div>
@ -47,7 +47,7 @@
<span class="checkbox">
<input type="checkbox" id="is_zip" name="is_zip" v-model="is_zip">
<label class="checkbox-view" for="is_zip"></label>
{{ __('admin::app.configuration.tax-rates.is_zip') }}
{{ __('admin::app.settings.tax-rates.is_zip') }}
</span>
</div>

View File

@ -1,7 +1,7 @@
@extends('admin::layouts.content')
@section('page_title')
{{ __('admin::app.configuration.tax-rates.edit-title') }}
{{ __('admin::app.settings.tax-rates.edit-title') }}
@stop
@section('content')
@ -9,12 +9,12 @@
<form method="POST" action="{{ route('admin.tax-rates.update', $taxRate->id) }}" @submit.prevent="onSubmit">
<div class="page-header">
<div class="page-title">
<h1>{{ __('admin::app.configuration.tax-rates.edit.title') }}</h1>
<h1>{{ __('admin::app.settings.tax-rates.edit.title') }}</h1>
</div>
<div class="page-action">
<button type="submit" class="btn btn-lg btn-primary">
{{ __('admin::app.configuration.tax-rates.save-btn-title') }}
{{ __('admin::app.settings.tax-rates.edit-title') }}
</button>
</div>
</div>
@ -22,7 +22,7 @@
<div class="page-content">
<div class="form-container">
@method('PUT')
@csrf()
<div class="control-group" :class="[errors.has('identifier') ? 'has-error' : '']">

View File

@ -1,19 +1,19 @@
@extends('admin::layouts.content')
@section('page_title')
{{ __('admin::app.configuration.tax-rates.title') }}
{{ __('admin::app.settings.tax-rates.title') }}
@stop
@section('content')
<div class="content">
<div class="page-header">
<div class="page-title">
<h1>{{ __('admin::app.configuration.tax-rates.title') }}</h1>
<h1>{{ __('admin::app.settings.tax-rates.title') }}</h1>
</div>
<div class="page-action">
<a href="{{ route('admin.tax-rates.show') }}" class="btn btn-lg btn-primary">
{{ __('admin::app.configuration.tax-rates.add-title') }}
{{ __('admin::app.settings.tax-rates.add-title') }}
</a>
</div>
</div>

View File

@ -4,7 +4,6 @@
{{ __('admin::app.users.users.edit-user-title') }}
@stop
@section('content')
<div class="content">
<form method="POST" action="{{ route('admin.users.update', $user->id) }}" @submit.prevent="onSubmit">

View File

@ -325,7 +325,9 @@ class Cart {
/**
* Update the cartItem on cart checkout page and if already added item is added again
*
* @param $id product_id of cartItem instance
* @param $data new requested quantities by customer
* @param $itemId is id from cartItem instance
* @return boolean
*/
public function updateItem($id, $data, $itemId)
@ -371,7 +373,6 @@ class Cart {
return false;
}
}
/**
@ -388,7 +389,10 @@ class Cart {
if($cart->items()->get()->count() == 0) {
$this->cart->delete($cart->id);
$this->deActivateCart();
// $this->deActivateCart();
if(session()->has('cart')) {
session()->forget('cart');
}
}
session()->flash('success', trans('shop::app.checkout.cart.item.success-remove'));

View File

@ -15,7 +15,7 @@ class CreateCartItemInventoriesTable extends Migration
{
Schema::create('cart_item_inventories', function (Blueprint $table) {
$table->increments('id');
$table->integer('qty')->default(0);
$table->integer('qty')->unsigned()->default(0);
$table->integer('inventory_source_id')->unsigned()->nullable();
$table->integer('cart_item_id')->unsigned()->nullable();
$table->timestamps();

View File

@ -19,10 +19,16 @@ class Cart extends Model
protected $with = ['items', 'items.child', 'shipping_address', 'billing_address', 'selected_shipping_rate', 'payment'];
/**
* To get relevant associated items with the cart instance
*/
public function items() {
return $this->hasMany(CartItem::class)->whereNull('parent_id');
}
/**
* To get all the associated items with the cart instance even the parent and child items of configurable products
*/
public function all_items() {
return $this->hasMany(CartItem::class);
}

View File

@ -0,0 +1,32 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class ChangeContentColumnInSlidersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('sliders', function (Blueprint $table) {
$table->text('content')->nullable()->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('sliders', function (Blueprint $table) {
$table->string('content')->change();
});
}
}

View File

@ -0,0 +1,36 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddIsVerifiedColumnInCustomersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('customers', function (Blueprint $table) {
$table->boolean('is_verified')->default(0)->after('subscribed_to_news_letter');
$table->string('token')->nullable()->after('is_verified');
$table->dropColumn('gender');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('customers', function (Blueprint $table) {
$table->dropColumn('is_verified');
$table->dropColumn('token');
$table->enum('gender', ['Male', 'Female'])->after('last_name');
});
}
}

View File

@ -0,0 +1,32 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class ChangeGenderColumnInCustomersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('customers', function (Blueprint $table) {
$table->string('gender')->length(50)->nullable()->after('last_name');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('customers', function (Blueprint $table) {
$table->dropColumn('gender');
});
}
}

View File

@ -73,6 +73,7 @@ class AddressController extends Controller
$this->validate(request(), [
'address1' => 'string|required',
'address2' => 'string',
'country' => 'string|required',
'state' => 'string|required',
'city' => 'string|required',

View File

@ -8,6 +8,7 @@ use Webkul\Customer\Repositories\CustomerRepository;
use Webkul\Product\Repositories\ProductReviewRepository as ProductReview;
use Webkul\Customer\Models\Customer;
use Auth;
use Hash;
/**
* Customer controlller for the customer basically for the tasks of customers which will be done after customer authentication.
@ -94,41 +95,57 @@ class CustomerController extends Controller
$id = auth()->guard('customer')->user()->id;
$this->validate(request(), [
'first_name' => 'string',
'last_name' => 'string',
'gender' => 'required',
'date_of_birth' => 'date',
'email' => 'email|unique:customers,email,'.$id,
'password' => 'confirmed|required_if:oldpassword,!=,null'
]);
$data = collect(request()->input())->except('_token')->toArray();
if($data['date_of_birth'] == "") {
unset($data['date_of_birth']);
}
if($data['oldpassword'] == null) {
$data = collect(request()->input())->except(['_token','password','password_confirmation','oldpassword'])->toArray();
if($data['date_of_birth'] == "") {
unset($data['date_of_birth']);
}
if($this->customer->update($data, $id)) {
Session()->flash('success','Profile Updated Successfully');
Session()->flash('success', trans('shop::app.customer.account.profile.edit-success'));
return redirect()->back();
} else {
Session()->flash('success','Profile Updated Successfully');
Session()->flash('success', trans('shop::app.customer.account.profile.edit-fail'));
return redirect()->back();
}
} else {
$data = collect(request()->input())->except(['_token','oldpassword'])->toArray();
if(Hash::check($data['oldpassword'], auth()->guard('customer')->user()->password)) {
$data = collect(request()->input())->except(['_token','oldpassword'])->toArray();
$data['password'] = bcrypt($data['password']);
$data['password'] = bcrypt($data['password']);
if($data['date_of_birth'] == "") {
unset($data['date_of_birth']);
}
} else {
session()->flash('warning', trans('shop::app.customer.account.profile.unmatch'));
return redirect()->back();
}
if($this->customer->update($data, $id)) {
Session()->flash('success','Profile Updated Successfully');
Session()->flash('success', trans('shop::app.customer.account.profile.edit-success'));
return redirect()->back();
} else {
Session()->flash('success','Profile Updated Successfully');
Session()->flash('success', trans('shop::app.customer.account.profile.edit-fail'));
return redirect()->back();
}

View File

@ -4,8 +4,11 @@ namespace Webkul\Customer\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Mail;
use Webkul\Customer\Mail\VerificationEmail;
use Illuminate\Routing\Controller;
use Webkul\Customer\Repositories\CustomerRepository;
use Cookie;
/**
* Registration controller
@ -23,9 +26,10 @@ class RegistrationController extends Controller
protected $_config;
protected $customer;
public function __construct(CustomerRepository $customer)
{
/**
* @param CustomerRepository object $customer
*/
public function __construct(CustomerRepository $customer) {
$this->_config = request('_config');
$this->customer = $customer;
}
@ -35,8 +39,7 @@ class RegistrationController extends Controller
*
* @return view
*/
public function show()
{
public function show() {
return view($this->_config['view']);
}
@ -45,8 +48,7 @@ class RegistrationController extends Controller
*
* @return Mixed
*/
public function create(Request $request)
{
public function create(Request $request) {
$request->validate([
'first_name' => 'string|required',
'last_name' => 'string|required',
@ -61,18 +63,76 @@ class RegistrationController extends Controller
$data['channel_id'] = core()->getCurrentChannel()->id;
if ($this->customer->create($data)) {
$data['is_verified'] = 0;
session()->flash('success', 'Account Created Successfully');
$verificationData['email'] = $data['email'];
$verificationData['token'] = md5(uniqid(rand(), true));
$data['token'] = $verificationData['token'];
$created = $this->customer->create($data);
return redirect()->back();
if ($created) {
try {
session()->flash('success', trans('shop::app.customer.signup-form.success'));
// return redirect()->route($this->_config['redirect'])->with('message', 'Account Created Successfully, Try To Log In');
Mail::send(new VerificationEmail($verificationData));
} catch(\Exception $e) {
session()->flash('info', trans('shop::app.customer.signup-form.success-verify-email-not-sent'));
return redirect()->route($this->_config['redirect']);
}
return redirect()->route($this->_config['redirect']);
} else {
session()->flash('error', 'Cannot Create Your Account');
session()->flash('error', trans('shop::app.customer.signup-form.failed'));
return redirect()->back();
}
}
}
/**
* Method to verify account
*
*/
public function verifyAccount($token) {
$customer = $this->customer->findOneByField('token', $token);
if($customer) {
$customer->update(['is_verified' => 1, 'token' => 'NULL']);
session()->flash('success', trans('shop::app.customer.signup-form.verified'));
} else {
session()->flash('warning', trans('shop::app.customer.signup-form.verify-failed'));
}
return redirect()->route('customer.session.index');
}
public function resendVerificationEmail($email) {
$verificationData['email'] = $email;
$verificationData['token'] = md5(uniqid(rand(), true));
$customer = $this->customer->findOneByField('email', $email);
$this->customer->update(['token' => $verificationData['token']], $customer->id);
try {
Mail::send(new VerificationEmail($verificationData));
if(Cookie::has('enable-resend')) {
\Cookie::queue(\Cookie::forget('enable-resend'));
}
if(Cookie::has('email-for-resend')) {
\Cookie::queue(\Cookie::forget('email-for-resend'));
}
} catch(\Exception $e) {
session()->flash('success', trans('shop::app.customer.signup-form.verification-not-sent'));
return redirect()->back();
}
session()->flash('success', trans('shop::app.customer.signup-form.verification-sent'));
return redirect()->back();
}
}

View File

@ -62,7 +62,6 @@ class ResetPasswordController extends Controller
*/
public function store()
{
//dd(request()->input());
$this->validate(request(), [
'token' => 'required',
'email' => 'required|email',
@ -74,7 +73,7 @@ class ResetPasswordController extends Controller
$this->resetPassword($customer, $password);
}
);
// dd($response);
if($response == Password::PASSWORD_RESET) {
return redirect()->route($this->_config['redirect']);
}

View File

@ -8,6 +8,7 @@ use Illuminate\Support\Facades\Event;
use Webkul\Customer\Models\Customer;
use Webkul\Customer\Http\Listeners\CustomerEventsHandler;
use Cart;
use Cookie;
/**
* Session controller for the user customer
@ -38,7 +39,7 @@ class SessionController extends Controller
public function show()
{
if(auth()->guard('customer')->check()) {
return redirect()->route('customer.account.index');
return redirect()->route('customer.session.index');
} else {
return view($this->_config['view']);
}
@ -52,8 +53,21 @@ class SessionController extends Controller
]);
if (!auth()->guard('customer')->attempt(request(['email', 'password']))) {
session()->flash('error', 'Please check your credentials and try again.');
return back();
session()->flash('error', trans('shop::app.customer.login-form.invalid-creds'));
return redirect()->back();
}
if(auth()->guard('customer')->user()->is_verified == 0) {
session()->flash('info', trans('shop::app.customer.login-form.verify-first'));
Cookie::queue(Cookie::make('enable-resend', 'true', 1));
Cookie::queue(Cookie::make('email-for-resend', $request->input('email'), 1));
auth()->guard('customer')->logout();
return redirect()->back();
}
//Event passed to prepare cart after login

View File

@ -55,7 +55,7 @@ class WishlistController extends Controller
'channel_id' => core()->getCurrentChannel()->id,
'customer_id' => auth()->guard('customer')->user()->id]
);
// dd($wishlistItems->count());
return view($this->_config['view'])->with('items', $wishlistItems);
}
@ -75,6 +75,12 @@ class WishlistController extends Controller
$checked = $this->wishlist->findWhere(['channel_id' => core()->getCurrentChannel()->id, 'product_id' => $itemId, 'customer_id' => auth()->guard('customer')->user()->id]);
//accidental case if some one adds id of the product in the anchor tag amd gives id of a variant.
if($product->parent_id != null) {
$product = $this->product->findOneByField('id', $product->parent_id);
$data['product_id'] = $product->parent_id;
}
if($checked->isEmpty()) {
if($this->wishlist->create($data)) {
session()->flash('success', trans('customer::app.wishlist.success'));
@ -143,7 +149,7 @@ class WishlistController extends Controller
return redirect()->back();
}
session()->flash('warning', trans('shop::app.checkout.cart.add-config-warning'));
session()->flash('info', trans('shop::app.checkout.cart.add-config-warning'));
return redirect()->route('shop.products.index', $wishlistItem->product->url_key);
}

View File

@ -0,0 +1,37 @@
<?php
namespace Webkul\Customer\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
/**
* Verification Mail class
*
* @author Rahul Shukla <rahulshukla.symfony517@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class VerificationEmail extends Mailable
{
use Queueable, SerializesModels;
public $verificationData;
public function __construct($verificationData) {
$this->verificationData = $verificationData;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->to($this->verificationData['email'])
->subject('Verification email')
->view('shop::emails.customer.verification-email')->with('data', ['email' => $this->verificationData['email'], 'token' => $this->verificationData['token']]);
}
}

View File

@ -16,7 +16,7 @@ class Customer extends Authenticatable
protected $table = 'customers';
protected $fillable = ['first_name', 'channel_id', 'last_name', 'gender', 'date_of_birth', 'email', 'password', 'customer_group_id', 'subscribed_to_news_letter'];
protected $fillable = ['first_name', 'channel_id', 'last_name', 'gender', 'date_of_birth', 'email', 'password', 'customer_group_id', 'subscribed_to_news_letter', 'is_verified', 'token'];
protected $hidden = ['password', 'remember_token'];

View File

@ -0,0 +1,36 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class RemoveCostColumnFromDatagrid extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
if (Schema::hasTable('product_grid')) {
Schema::table('products_grid', function (Blueprint $table) {
$table->dropColumn('cost');
});
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
if (Schema::hasTable('product_grid')) {
Schema::table('products_grid', function (Blueprint $table) {
$table->string('cost');
});
}
}
}

View File

@ -185,7 +185,7 @@ class ProductController extends Controller
$product = $this->product->update(request()->all(), $id);
//after update of product
Event::fire('product.save.after', $product);
Event::fire('product.update.after', $product);
session()->flash('success', 'Product updated successfully.');
@ -212,6 +212,9 @@ class ProductController extends Controller
return redirect()->back();
}
/*
* To be manually invoked when data is seeded into products
*/
public function sync() {
Event::fire('products.datagrid.create', true);
}

View File

@ -19,7 +19,6 @@ use Webkul\Core\Repositories\SubscribersListRepository as Subscription;
*/
class SubscriptionController extends Controller
{
/**
* User object
*
@ -48,17 +47,13 @@ class SubscriptionController extends Controller
*/
public function __construct(Customer $customer, Subscription $subscription)
{
$this->user = auth()->guard('customer')->user();
$this->customer = $customer;
$this->subscription = $subscription;
$this->_config = request('_config');
}
/**
* Subscribes Customers and Guests to subscription mailing list and checks if already subscribed
* Subscribes email to the email subscription list
*/
public function subscribe()
{
@ -70,44 +65,27 @@ class SubscriptionController extends Controller
$unique = 0;
if(auth()->guard('customer')->check()) {
$unique = function() use($email) {
$count = $this->customer->findWhere(['email' => $email]);
$alreadySubscribed = $this->subscription->findWhere(['email' => $email]);
if($count->count() > 0 && $count->first()->subscribed_to_news_letter == 1) {
return 0;
} else {
return 1;
}
};
} else {
$alreadySubscribed = $this->subscription->findWhere(['email' => $email]);
$unique = function() use($alreadySubscribed){
if($alreadySubscribed->count() > 0) {
return 0;
} else {
return 1;
}
};
}
$unique = function() use($alreadySubscribed){
if($alreadySubscribed->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]);
}
$result = $this->subscription->create([
'email' => $email,
'channel_id' => core()->getCurrentChannel()->id,
'is_subscribed' => 1,
'token' => $token
]);
if(!$result) {
session()->flash('error', trans('shop::app.subscription.not-subscribed'));
@ -121,12 +99,8 @@ class SubscriptionController extends Controller
Mail::send(new SubscriptionEmail($subscriptionData));
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();
@ -138,6 +112,14 @@ class SubscriptionController extends Controller
* @var string $token
*/
public function unsubscribe($token) {
dd('unsubscribing');
$subscriber = $this->subscription->findOneByField('token', $token);
if($subscriber->count() > 0 && $subscriber->is_subscribed == 1 &&$subscriber->update(['is_subscribed' => 0])) {
session()->flash('info', trans('shop::app.subscription.unsubscribed'));
} else {
session()->flash('info', trans('shop::app.subscription.already-unsub'));
}
return redirect()->route('shop.home.index');
}
}
}

View File

@ -12,7 +12,7 @@ Route::group(['middleware' => ['web', 'theme', 'locale', 'currency']], function
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');
Route::get('/unsubscribe/{token}', 'Webkul\Shop\Http\Controllers\SubscriptionController@unsubscribe')->name('shop.unsubscribe');
//Store front header nav-menu fetch
Route::get('/categories/{slug}', 'Webkul\Shop\Http\Controllers\CategoryController@index')->defaults('_config', [
@ -125,7 +125,7 @@ Route::group(['middleware' => ['web', 'theme', 'locale', 'currency']], function
// Reset Password Form Store
Route::post('/reset-password', 'Webkul\Customer\Http\Controllers\ResetPasswordController@store')->defaults('_config', [
'redirect' => 'customer.session.index'
'redirect' => 'customer.profile.index'
])->name('customer.reset-password.store');
// Login Routes
@ -150,6 +150,12 @@ Route::group(['middleware' => ['web', 'theme', 'locale', 'currency']], function
'redirect' => 'customer.session.index',
])->name('customer.register.create');
//verify account
Route::get('/verify-account/{token}', 'Webkul\Customer\Http\Controllers\RegistrationController@verifyAccount')->name('customer.verify');
//resend verification email
Route::get('/resend/verification/{email}', 'Webkul\Customer\Http\Controllers\RegistrationController@resendVerificationEmail')->name('customer.resend.verification-email');
// Auth Routes
Route::group(['middleware' => ['customer']], function () {

View File

@ -6,7 +6,6 @@ use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
/**
* Subscriber Mail class
*
@ -16,13 +15,10 @@ use Illuminate\Contracts\Queue\ShouldQueue;
class SubscriptionEmail extends Mailable
{
use Queueable, SerializesModels;
public $subscriptionData;
public function __construct($subscriptionData) {
$this->subscriptionData = $subscriptionData;
}
/**
* Build the message.
*
@ -34,4 +30,4 @@ class SubscriptionEmail extends Mailable
->subject('subscription email')
->view('shop::emails.customer.subscription-email')->with('data', ['content' => 'You Are Subscribed', 'token' => $this->subscriptionData['token']]);
}
}
}

View File

@ -198,6 +198,15 @@ input {
}
}
/* Verify Email */
.verify-account {
width: 100%;
height: 30px;
background-color: $border-color;
line-height: 30px;
text-align: center;
}
/* Show the indicator (dot/circle) when checked */
.radio-container input:checked ~ .checkmark:after {
display: block;
@ -918,7 +927,7 @@ section.slider-block {
}
.dropdown-content .item-details{
height: 75px;
max-height: 125px;
}
.item-details .item-name {
@ -927,6 +936,12 @@ section.slider-block {
margin-bottom: 8px;
}
.item-details .item-options {
font-size: 16px;
font-weight: bold;
margin-bottom: 8px;
}
.item-details .item-price {
margin-bottom: 8px;
}
@ -1643,6 +1658,7 @@ section.product-detail {
width: 100%;
max-height: 480px;
height: 100%;
box-shadow: 1px 1px 2px $border-color;
img {
width: 100%;
@ -1680,11 +1696,12 @@ section.product-detail {
display: none;
flex-direction: row;
margin-top: 10px;
width: 79.5%;
float: right;
justify-content: space-between;
.addtocart {
border-radius: 0px;
width: 49%;
background: black;
white-space: nowrap;
@ -1692,9 +1709,7 @@ section.product-detail {
}
.buynow {
border-radius: 0px;
width: 49%;
float:right;
white-space: nowrap;
text-transform: uppercase;
}

View File

@ -8,7 +8,9 @@ return [
'home' => [
'page-title' => 'Bagisto - Home',
'featured-products' => 'Featured Products',
'new-products' => 'New Products'
'new-products' => 'New Products',
'verify-email' => 'Verify Your Email Account',
'resend-verify-email' => 'Resend Verification Email'
],
'header' => [
@ -35,7 +37,9 @@ return [
'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'
'already' => 'You Are Already Subscribed To Our Subscription List',
'unsubscribed' => 'You Are Unsubscribed From Bagisto Subscription Mails',
'already-unsub' => 'You Are Already Unsubscribed'
],
'search' => [
@ -73,7 +77,17 @@ return [
'agree' => 'Agree',
'terms' => 'Terms',
'conditions' => 'Conditions',
'using' => 'by using this website'
'using' => 'by using this website',
'agreement' => 'Agreement',
'success' => 'Account Created Successfully, An Email Has Been Sent To Your For Account Verification',
'success-verify-email-not-sent' => 'Account Created Successfully, But Verification Email Is Not Sent',
'failed' => 'Error! Cannot Create Your Account, Try Again Later',
'already-verified' => 'Your Account is already verified Or Please Try Sending A New Verification Email Again',
'verification-not-sent' => 'Error! Problem In Sending Verification Email, Try Again Later',
'verification-sent' => 'Verification Email Sent',
'verified' => 'Your Account Has Been Verified, Try To Login Now',
'verify-failed' => 'We Cannot Verify Your Mail Account',
'dont-have-account' => 'You Do Not Have Account With Us',
],
'login-text' => [
@ -89,7 +103,10 @@ return [
'forgot_pass' => 'Forgot Password?',
'button_title' => 'Sign In',
'remember' => 'Remember Me',
'footer' => '© Copyright 2018 Webkul Software, All rights reserved'
'footer' => '© Copyright 2018 Webkul Software, All rights reserved',
'invalid-creds' => 'Please Check Your Credentials And Try Again',
'verify-first' => 'Verify Your Email Account First',
'resend-verification' => 'Resend Verification Mail Again'
],
'forgot-password' => [
@ -119,6 +136,10 @@ return [
'edit' => 'Edit',
],
'edit-success' => 'Profile Updated Successfully',
'edit-fail' => 'Error! Profile Cannot Be Updated, Please Try Again Later',
'unmatch' => 'The Old Password Does Not Match',
'fname' => 'First Name',
'lname' => 'Last Name',
'gender' => 'Gender',
@ -362,6 +383,7 @@ return [
'continue' => 'Continue',
'shipping-method' => 'Shipping Method',
'payment-information' => 'Payment Information',
'payment-method' => 'Payment Method',
'summary' => 'Summary of Order',
'price' => 'Price',
'quantity' => 'Quantity',

View File

@ -5,28 +5,20 @@
@stop
@section('content-wrapper')
@inject ('productImageHelper', 'Webkul\Product\Helpers\ProductImage')
<section class="cart">
@if ($cart)
<div class="title">
{{ __('shop::app.checkout.cart.title') }}
</div>
<div class="cart-content">
<div class="left-side">
<form action="{{ route('shop.checkout.cart.update') }}" method="POST" @submit.prevent="onSubmit">
<div class="cart-item-list" style="margin-top: 0">
@csrf
@foreach($cart->items as $item)
<?php
if($item->type == "configurable")
$productBaseImage = $productImageHelper->getProductBaseImage($item->child->product);
@ -64,7 +56,7 @@
<div class="wrap">
<label for="qty[{{$item->id}}]">{{ __('shop::app.checkout.cart.quantity.quantity') }}</label>
<input 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 }}" data-vv-as="&quot;{{ __('shop::app.checkout.cart.quantity.quantity') }}&quot;">
</div>
<span class="control-error" v-if="errors.has('qty[{{$item->id}}]')">@{{ errors.first('qty[{!!$item->id!!}]') }}</span>
@ -73,13 +65,15 @@
<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>
<span class="towishlist">
@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>
@else
<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
</span>
@auth('customer')
<span class="towishlist">
@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>
@else
<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
</span>
@endauth
</div>
@if (!cart()->isItemHaveQuantity($item))

View File

@ -21,54 +21,43 @@
<div class="dropdown-cart">
<div class="dropdown-header">
<p class="heading">
{{ __('shop::app.checkout.cart.cart-subtotal') }} -
{{ __('shop::app.checkout.cart.cart-subtotal') }} -
{{ core()->currency($cart->sub_total) }}
</p>
</div>
<div class="dropdown-content">
@foreach($items as $item)
@if($item->type == "configurable")
{{-- @if($item->type == "configurable") --}}
<div class="item">
<div class="item-image" >
@php
$images = $productImageHelper->getProductBaseImage($item->child->product);
@endphp
<?php
if($item->type == "configurable")
$images = $productImageHelper->getProductBaseImage($item->child->product);
else
$images = $productImageHelper->getProductBaseImage($item->product);
?>
<img src="{{ $images['small_image_url'] }}" />
</div>
<div class="item-details">
{{-- @if($item->type == "configurable")
<div class="item-name">{{ $item->child->name }}</div>
@else --}}
<div class="item-name">{{ $item->name }}</div>
{{-- @endif --}}
<div class="item-name">{{ $item->child->name }}</div>
@if($item->type == "configurable")
<div class="item-options">
{{ trim(Cart::getProductAttributeOptionDetails($item->child->product)['html']) }}
</div>
@endif
<div class="item-price">{{ core()->currency($item->total) }}</div>
<div class="item-qty">Quantity - {{ $item->quantity }}</div>
</div>
</div>
@else
<div class="item">
<div class="item-image" >
@php
$images = $productImageHelper->getProductBaseImage($item->product);
@endphp
<img src="{{ $images['small_image_url'] }}" />
</div>
<div class="item-details">
<div class="item-name">{{ $item->name }}</div>
<div class="item-price">{{ core()->currency($item->total) }}</div>
<div class="item-qty">Quantity - {{ $item->quantity }}</div>
</div>
</div>
@endif
@endforeach
</div>

View File

@ -17,7 +17,7 @@
{{ __('shop::app.checkout.onepage.first-name') }}
</label>
<input type="text" v-validate="'required'" class="control" id="billing[first_name]" name="billing[first_name]" v-model="address.billing.first_name"/>
<input type="text" v-validate="'required'" class="control" id="billing[first_name]" name="billing[first_name]" v-model="address.billing.first_name" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.first-name') }}&quot;"/>
<span class="control-error" v-if="errors.has('address-form.billing[first_name]')">
@{{ errors.first('address-form.billing[first_name]') }}
@ -29,7 +29,7 @@
{{ __('shop::app.checkout.onepage.last-name') }}
</label>
<input type="text" v-validate="'required'" class="control" id="billing[last_name]" name="billing[last_name]" v-model="address.billing.last_name"/>
<input type="text" v-validate="'required'" class="control" id="billing[last_name]" name="billing[last_name]" v-model="address.billing.last_name" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.last-name') }}&quot;"/>
<span class="control-error" v-if="errors.has('address-form.billing[last_name]')">
@{{ errors.first('address-form.billing[last_name]') }}
@ -41,7 +41,7 @@
{{ __('shop::app.checkout.onepage.email') }}
</label>
<input type="text" v-validate="'required'" class="control" id="billing[email]" name="billing[email]" v-model="address.billing.email"/>
<input type="text" v-validate="'required'" class="control" id="billing[email]" name="billing[email]" v-model="address.billing.email" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.email') }}&quot;"/>
<span class="control-error" v-if="errors.has('address-form.billing[email]')">
@{{ errors.first('address-form.billing[email]') }}
@ -53,7 +53,7 @@
{{ __('shop::app.checkout.onepage.address1') }}
</label>
<input type="text" v-validate="'required'" class="control" id="billing[address1]" name="billing[address1]" v-model="address.billing.address1"/>
<input type="text" v-validate="'required'" class="control" id="billing[address1]" name="billing[address1]" v-model="address.billing.address1" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.address1') }}&quot;"/>
<span class="control-error" v-if="errors.has('address-form.billing[address1]')">
@{{ errors.first('address-form.billing[address1]') }}
@ -73,7 +73,7 @@
{{ __('shop::app.checkout.onepage.city') }}
</label>
<input type="text" v-validate="'required'" class="control" id="billing[city]" name="billing[city]" v-model="address.billing.city"/>
<input type="text" v-validate="'required'" class="control" id="billing[city]" name="billing[city]" v-model="address.billing.city" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.city') }}&quot;"/>
<span class="control-error" v-if="errors.has('address-form.billing[city]')">
@{{ errors.first('address-form.billing[city]') }}
@ -86,9 +86,9 @@
</label>
<input type="text" v-validate="'required'" class="control" id="billing[state]" name="billing[state]" v-model="address.billing.state" v-if="!haveStates('billing')"/>
<input type="text" v-validate="'required'" class="control" id="billing[state]" name="billing[state]" v-model="address.billing.state" v-if="!haveStates('billing')" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.state') }}&quot;"/>
<select v-validate="'required'" class="control" id="billing[state]" name="billing[state]" v-model="address.billing.state" v-if="haveStates('billing')">
<select v-validate="'required'" class="control" id="billing[state]" name="billing[state]" v-model="address.billing.state" v-if="haveStates('billing')" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.state') }}&quot;">
<option value="">{{ __('shop::app.checkout.onepage.select-state') }}</option>
@ -108,7 +108,7 @@
{{ __('shop::app.checkout.onepage.postcode') }}
</label>
<input type="text" v-validate="'required'" class="control" id="billing[postcode]" name="billing[postcode]" v-model="address.billing.postcode"/>
<input type="text" v-validate="'required'" class="control" id="billing[postcode]" name="billing[postcode]" v-model="address.billing.postcode" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.postcode') }}&quot;"/>
<span class="control-error" v-if="errors.has('address-form.billing[postcode]')">
@{{ errors.first('address-form.billing[postcode]') }}
@ -120,7 +120,7 @@
{{ __('shop::app.checkout.onepage.country') }}
</label>
<select type="text" v-validate="'required'" class="control" id="billing[country]" name="billing[country]" v-model="address.billing.country">
<select type="text" v-validate="'required'" class="control" id="billing[country]" name="billing[country]" v-model="address.billing.country" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.country') }}&quot;">
<option value=""></option>
@foreach (core()->countries() as $country)
@ -140,7 +140,7 @@
{{ __('shop::app.checkout.onepage.phone') }}
</label>
<input type="text" v-validate="'required'" class="control" id="billing[phone]" name="billing[phone]" v-model="address.billing.phone"/>
<input type="text" v-validate="'required'" class="control" id="billing[phone]" name="billing[phone]" v-model="address.billing.phone" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.phone') }}&quot;"/>
<span class="control-error" v-if="errors.has('address-form.billing[phone]')">
@{{ errors.first('address-form.billing[phone]') }}
@ -168,7 +168,7 @@
{{ __('shop::app.checkout.onepage.first-name') }}
</label>
<input type="text" v-validate="'required'" class="control" id="shipping[first_name]" name="shipping[first_name]" v-model="address.shipping.first_name"/>
<input type="text" v-validate="'required'" class="control" id="shipping[first_name]" name="shipping[first_name]" v-model="address.shipping.first_name" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.first-name') }}&quot;"/>
<span class="control-error" v-if="errors.has('address-form.shipping[first_name]')">
@{{ errors.first('address-form.shipping[first_name]') }}
@ -180,7 +180,7 @@
{{ __('shop::app.checkout.onepage.last-name') }}
</label>
<input type="text" v-validate="'required'" class="control" id="shipping[last_name]" name="shipping[last_name]" v-model="address.shipping.last_name"/>
<input type="text" v-validate="'required'" class="control" id="shipping[last_name]" name="shipping[last_name]" v-model="address.shipping.last_name" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.last-name') }}&quot;"/>
<span class="control-error" v-if="errors.has('address-form.shipping[last_name]')">
@{{ errors.first('address-form.shipping[last_name]') }}
@ -192,7 +192,7 @@
{{ __('shop::app.checkout.onepage.email') }}
</label>
<input type="text" v-validate="'required'" class="control" id="shipping[email]" name="shipping[email]" v-model="address.shipping.email"/>
<input type="text" v-validate="'required'" class="control" id="shipping[email]" name="shipping[email]" v-model="address.shipping.email" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.email') }}&quot;"/>
<span class="control-error" v-if="errors.has('address-form.shipping[email]')">
@{{ errors.first('address-form.shipping[email]') }}
@ -204,7 +204,7 @@
{{ __('shop::app.checkout.onepage.address1') }}
</label>
<input type="text" v-validate="'required'" class="control" id="shipping[address1]" name="shipping[address1]" v-model="address.shipping.address1"/>
<input type="text" v-validate="'required'" class="control" id="shipping[address1]" name="shipping[address1]" v-model="address.shipping.address1" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.address1') }}&quot;"/>
<span class="control-error" v-if="errors.has('address-form.shipping[address1]')">
@{{ errors.first('address-form.shipping[address1]') }}
@ -224,7 +224,7 @@
{{ __('shop::app.checkout.onepage.city') }}
</label>
<input type="text" v-validate="'required'" class="control" id="shipping[city]" name="shipping[city]" v-model="address.shipping.city"/>
<input type="text" v-validate="'required'" class="control" id="shipping[city]" name="shipping[city]" v-model="address.shipping.city" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.city') }}&quot;"/>
<span class="control-error" v-if="errors.has('address-form.shipping[city]')">
@{{ errors.first('address-form.shipping[city]') }}
@ -237,9 +237,9 @@
</label>
<input type="text" v-validate="'required'" class="control" id="shipping[state]" name="shipping[state]" v-model="address.shipping.state" v-if="!haveStates('shipping')"/>
<input type="text" v-validate="'required'" class="control" id="shipping[state]" name="shipping[state]" v-model="address.shipping.state" v-if="!haveStates('shipping')" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.state') }}&quot;"/>
<select v-validate="'required'" class="control" id="shipping[state]" name="shipping[state]" v-model="address.shipping.state" v-if="haveStates('shipping')">
<select v-validate="'required'" class="control" id="shipping[state]" name="shipping[state]" v-model="address.shipping.state" v-if="haveStates('shipping')" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.state') }}&quot;">
<option value="">{{ __('shop::app.checkout.onepage.select-state') }}</option>
@ -259,7 +259,7 @@
{{ __('shop::app.checkout.onepage.postcode') }}
</label>
<input type="text" v-validate="'required'" class="control" id="shipping[postcode]" name="shipping[postcode]" v-model="address.shipping.postcode"/>
<input type="text" v-validate="'required'" class="control" id="shipping[postcode]" name="shipping[postcode]" v-model="address.shipping.postcode" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.postcode') }}&quot;"/>
<span class="control-error" v-if="errors.has('address-form.shipping[postcode]')">
@{{ errors.first('address-form.shipping[postcode]') }}
@ -271,13 +271,11 @@
{{ __('shop::app.checkout.onepage.country') }}
</label>
<select type="text" v-validate="'required'" class="control" id="shipping[country]" name="shipping[country]" v-model="address.shipping.country">
<select type="text" v-validate="'required'" class="control" id="shipping[country]" name="shipping[country]" v-model="address.shipping.country" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.country') }}&quot;">
<option value=""></option>
@foreach (core()->countries() as $country)
<option value="{{ $country->code }}">{{ $country->name }}</option>
@endforeach
</select>
@ -291,7 +289,7 @@
{{ __('shop::app.checkout.onepage.phone') }}
</label>
<input type="text" v-validate="'required'" class="control" id="shipping[phone]" name="shipping[phone]" v-model="address.shipping.phone"/>
<input type="text" v-validate="'required'" class="control" id="shipping[phone]" name="shipping[phone]" v-model="address.shipping.phone" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.phone') }}&quot;"/>
<span class="control-error" v-if="errors.has('address-form.shipping[phone]')">
@{{ errors.first('address-form.shipping[phone]') }}

View File

@ -10,12 +10,12 @@
@foreach ($paymentMethods as $payment)
<span class="radio" >
<input v-validate="'required'" type="radio" id="{{ $payment['method'] }}" name="payment[method]" value="{{ $payment['method'] }}" v-model="payment.method" @change="methodSelected()">
<span class="radio">
<input v-validate="'required'" type="radio" id="{{ $payment['method'] }}" name="payment[method]" value="{{ $payment['method'] }}" v-model="payment.method" @change="methodSelected()" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.payment-method') }}&quot;">
<label class="radio-view" for="{{ $payment['method'] }}"></label>
{{ $payment['method_title'] }}
</span>
<span class="control-info">{{ $payment['description'] }}</span>
@endforeach

View File

@ -13,13 +13,13 @@
@foreach ($rateGroup['rates'] as $rate)
<span class="radio" >
<input v-validate="'required'" type="radio" id="{{ $rate->method }}" name="shipping_method" value="{{ $rate->method }}" v-model="selected_shipping_method" @change="methodSelected()">
<input v-validate="'required'" type="radio" id="{{ $rate->method }}" name="shipping_method" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.shipping-method') }}&quot;" value="{{ $rate->method }}" v-model="selected_shipping_method" @change="methodSelected()">
<label class="radio-view" for="{{ $rate->method }}"></label>
{{ $rate->method_title }}
<b>{{ core()->currency($rate->base_price) }}</b>
</span>
@endforeach
@endforeach
<span class="control-error" v-if="errors.has('shipping-form.shipping_method')">

View File

@ -9,13 +9,10 @@
{{ __('shop::app.customer.account.address.create.country') }}
</label>
<select type="text" v-validate="'required'" class="control" id="country" name="country" v-model="country">
<select type="text" v-validate="'required'" class="control" id="country" name="country" v-model="country" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.country') }}&quot;">
<option value=""></option>
@foreach (core()->countries() as $country)
<option value="{{ $country->code }}">{{ $country->name }}</option>
@endforeach
</select>
@ -29,9 +26,8 @@
{{ __('shop::app.customer.account.address.create.state') }}
</label>
<input type="text" v-validate="'required'" class="control" id="state" name="state" v-model="state" v-if="!haveStates()"/>
<select v-validate="'required'" class="control" id="state" name="state" v-model="state" v-if="haveStates()">
<input type="text" v-validate="'required'" class="control" id="state" name="state" v-model="state" v-if="!haveStates()" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.state') }}&quot;"/>
<select v-validate="'required'" class="control" id="state" name="state" v-model="state" v-if="haveStates()" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.state') }}&quot;">
<option value="">{{ __('shop::app.customer.account.address.create.select-state') }}</option>
@ -67,7 +63,7 @@
haveStates() {
if(this.countryStates[this.country] && this.countryStates[this.country].length)
return true;
return false;
},
}

View File

@ -16,7 +16,7 @@
<span class="account-heading">{{ __('shop::app.customer.account.address.create.title') }}</span>
<span></span>
</div>
<form method="post" action="{{ route('customer.address.create') }}" @submit.prevent="onSubmit">
<div class="account-table-content">
@ -24,7 +24,7 @@
<div class="control-group" :class="[errors.has('address1') ? 'has-error' : '']">
<label for="address1" class="required">{{ __('shop::app.customer.account.address.create.address1') }}</label>
<input type="text" class="control" name="address1" v-validate="'required'">
<input type="text" class="control" name="address1" v-validate="'required'" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.address1') }}&quot;">
<span class="control-error" v-if="errors.has('address1')">@{{ errors.first('address1') }}</span>
</div>
@ -38,29 +38,29 @@
<div class="control-group" :class="[errors.has('city') ? 'has-error' : '']">
<label for="city" class="required">{{ __('shop::app.customer.account.address.create.city') }}</label>
<input type="text" class="control" name="city" v-validate="'required'">
<input type="text" class="control" name="city" v-validate="'required'" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.city') }}&quot;">
<span class="control-error" v-if="errors.has('city')">@{{ errors.first('city') }}</span>
</div>
<div class="control-group" :class="[errors.has('postcode') ? 'has-error' : '']">
<label for="postcode" class="required">{{ __('shop::app.customer.account.address.create.postcode') }}</label>
<input type="text" class="control" name="postcode" v-validate="'required'">
<input type="text" class="control" name="postcode" v-validate="'required'" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.postcode') }}&quot;">
<span class="control-error" v-if="errors.has('postcode')">@{{ errors.first('postcode') }}</span>
</div>
<div class="control-group" :class="[errors.has('phone') ? 'has-error' : '']">
<label for="phone" class="required">{{ __('shop::app.customer.account.address.create.phone') }}</label>
<input type="text" class="control" name="phone" v-validate="'required'">
<input type="text" class="control" name="phone" v-validate="'required'" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.phone') }}&quot;">
<span class="control-error" v-if="errors.has('phone')">@{{ errors.first('phone') }}</span>
</div>
<div class="button-group">
<input class="btn btn-primary btn-lg" type="submit" value="{{ __('shop::app.customer.account.address.create.submit') }}">
<button class="btn btn-primary btn-lg" type="submit">
{{-- <button class="btn btn-primary btn-lg" type="submit">
{{ __('shop::app.customer.account.address.edit.submit') }}
</button>
</button> --}}
</div>
</div>
</form>

View File

@ -25,7 +25,7 @@
<div class="control-group" :class="[errors.has('address1') ? 'has-error' : '']">
<label for="first_name" class="required">{{ __('shop::app.customer.account.address.create.address1') }}</label>
<input type="text" class="control" name="address1" v-validate="'required'" value="{{ $address->address1 }}">
<input type="text" class="control" name="address1" v-validate="'required'" value="{{ $address->address1 }}" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.address1') }}&quot;">
<span class="control-error" v-if="errors.has('address1')">@{{ errors.first('address1') }}</span>
</div>
@ -39,19 +39,19 @@
<div class="control-group" :class="[errors.has('city') ? 'has-error' : '']">
<label for="city" class="required">{{ __('shop::app.customer.account.address.create.city') }}</label>
<input type="text" class="control" name="city" v-validate="'required|alpha_spaces'" value="{{ $address->city }}">
<input type="text" class="control" name="city" v-validate="'required|alpha_spaces'" value="{{ $address->city }}" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.city') }}&quot;">
<span class="control-error" v-if="errors.has('city')">@{{ errors.first('city') }}</span>
</div>
<div class="control-group" :class="[errors.has('postcode') ? 'has-error' : '']">
<label for="postcode" class="required">{{ __('shop::app.customer.account.address.create.postcode') }}</label>
<input type="text" class="control" name="postcode" v-validate="'required'" value="{{ $address->postcode }}">
<input type="text" class="control" name="postcode" v-validate="'required'" value="{{ $address->postcode }}" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.postcode') }}&quot;">
<span class="control-error" v-if="errors.has('postcode')">@{{ errors.first('postcode') }}</span>
</div>
<div class="control-group" :class="[errors.has('phone') ? 'has-error' : '']">
<label for="phone" class="required">{{ __('shop::app.customer.account.address.create.phone') }}</label>
<input type="text" class="control" name="phone" v-validate="'required'" value="{{ $address->phone }}">
<input type="text" class="control" name="phone" v-validate="'required'" value="{{ $address->phone }}" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.phone') }}&quot;">
<span class="control-error" v-if="errors.has('phone')">@{{ errors.first('phone') }}</span>
</div>

View File

@ -11,12 +11,13 @@
<div class="account-layout">
<div class="account-head">
<div class="account-head mb-10">
<span class="back-icon"><a href="{{ route('customer.account.index') }}"><i class="icon icon-menu-back"></i></a></span>
<span class="account-heading">
{{ __('shop::app.customer.account.order.index.title') }}
</span>
<span></span>
<div class="horizontal-rule"></div>
</div>
<div class="account-items-list">

View File

@ -26,19 +26,21 @@
<div class="control-group" :class="[errors.has('first_name') ? 'has-error' : '']">
<label for="first_name" class="required">{{ __('shop::app.customer.account.profile.fname') }}</label>
<input type="text" class="control" name="first_name" value="{{ old('first_name') ?? $customer->first_name }}" v-validate="'required'">
<input type="text" class="control" name="first_name" value="{{ old('first_name') ?? $customer->first_name }}" v-validate="'required'" data-vv-as="&quot;{{ __('shop::app.customer.account.profile.fname') }}&quot;">
<span class="control-error" v-if="errors.has('first_name')">@{{ errors.first('first_name') }}</span>
</div>
<div class="control-group" :class="[errors.has('last_name') ? 'has-error' : '']">
<label for="last_name" class="required">{{ __('shop::app.customer.account.profile.lname') }}</label>
<input type="text" class="control" name="last_name" value="{{ old('last_name') ?? $customer->last_name }}" v-validate="'required'">
<input type="text" class="control" name="last_name" value="{{ old('last_name') ?? $customer->last_name }}" v-validate="'required'" data-vv-as="&quot;{{ __('shop::app.customer.account.profile.lname') }}&quot;">
<span class="control-error" v-if="errors.has('last_name')">@{{ errors.first('last_name') }}</span>
</div>
<div class="control-group" :class="[errors.has('gender') ? 'has-error' : '']">
<label for="email" class="required">{{ __('shop::app.customer.account.profile.gender') }}</label>
<select name="gender" class="control" v-validate="'required'">
<select name="gender" class="control" v-validate="'required'" data-vv-as="&quot;{{ __('shop::app.customer.account.profile.gender') }}&quot;">
<option value="" @if($customer->gender == "") selected @endif></option>
<option value="Other" @if($customer->gender == "Other") selected @endif>Other</option>
<option value="Male" @if($customer->gender == "Male") selected @endif>Male</option>
<option value="Female" @if($customer->gender == "Female") selected @endif>Female</option>
</select>
@ -52,26 +54,26 @@
<div class="control-group" :class="[errors.has('email') ? 'has-error' : '']">
<label for="email" class="required">{{ __('shop::app.customer.account.profile.email') }}</label>
<input type="email" class="control" name="email" value="{{ old('email') ?? $customer->email }}" v-validate="'required'">
<input type="email" class="control" name="email" value="{{ old('email') ?? $customer->email }}" v-validate="'required'" data-vv-as="&quot;{{ __('shop::app.customer.account.profile.email') }}&quot;">
<span class="control-error" v-if="errors.has('email')">@{{ errors.first('email') }}</span>
</div>
<div class="control-group" :class="[errors.has('old_password') ? 'has-error' : '']">
<div class="control-group" :class="[errors.has('oldpassword') ? 'has-error' : '']">
<label for="password">{{ __('shop::app.customer.account.profile.opassword') }}</label>
<input type="oldpassword" class="control" name="oldpassword">
<input type="password" class="control" name="oldpassword" data-vv-as="&quot;{{ __('shop::app.customer.account.profile.opassword') }}&quot;" v-validate="'min:6'">
<span class="control-error" v-if="errors.has('oldpassword')">@{{ errors.first('oldpassword') }}</span>
</div>
<div class="control-group" :class="[errors.has('password') ? 'has-error' : '']">
<label for="password">{{ __('shop::app.customer.account.profile.password') }}</label>
<input type="password" class="control" name="password">
<input type="password" id="password" class="control" name="password" data-vv-as="&quot;{{ __('shop::app.customer.account.profile.password') }}&quot;" v-validate="'min:6'">
<span class="control-error" v-if="errors.has('password')">@{{ errors.first('password') }}</span>
</div>
<div class="control-group">
<div class="control-group" :class="[errors.has('password_confirmation') ? 'has-error' : '']">
<label for="password">{{ __('shop::app.customer.account.profile.cpassword') }}</label>
<input type="password" class="control" name="password_confirmation">
<span>@{{ errors.first('password') }}</span>
<input type="password" id="password_confirmation" class="control" name="password_confirmation" data-vv-as="&quot;{{ __('shop::app.customer.account.profile.cpassword') }}&quot;" v-validate="'min:6|confirmed:password'">
<span class="control-error" v-if="errors.has('password_confirmation')">@{{ errors.first('password_confirmation') }}</span>
</div>
<div class="button-group">

View File

@ -52,6 +52,16 @@
<td>{{ __('shop::app.customer.account.profile.email') }}</td>
<td>{{ $customer->email }}</td>
</tr>
{{-- @if($customer->subscribed_to_news_letter == 1)
<tr>
<td> {{ __('shop::app.footer.subscribe-newsletter') }}</td>
<td>
<a class="btn btn-sm btn-primary" href="{{ route('shop.unsubscribe', $customer->email) }}">{{ __('shop::app.subscription.unsubscribe') }} </a>
</td>
</tr>
@endif --}}
</tbody>
</table>
</div>

View File

@ -5,7 +5,6 @@
@section('content-wrapper')
<div class="auth-content">
<div class="sign-up-text">
{{ __('shop::app.customer.login-text.no_account') }} - <a href="{{ route('customer.register.index') }}">{{ __('shop::app.customer.login-text.title') }}</a>
</div>
@ -16,19 +15,27 @@
<div class="login-text">{{ __('shop::app.customer.login-form.title') }}</div>
<div class="control-group" :class="[errors.has('email') ? 'has-error' : '']">
<label for="email">{{ __('shop::app.customer.login-form.email') }}</label>
<input type="text" class="control" name="email" v-validate="'required|email'" value="{{ old('email') }}">
<label for="email" class="required">{{ __('shop::app.customer.login-form.email') }}</label>
<input type="text" class="control" name="email" v-validate="'required|email'" value="{{ old('email') }}" data-vv-as="&quot;{{ __('shop::app.customer.login-form.email') }}&quot;">
<span class="control-error" v-if="errors.has('email')">@{{ errors.first('email') }}</span>
</div>
<div class="control-group" :class="[errors.has('password') ? 'has-error' : '']">
<label for="password">{{ __('shop::app.customer.login-form.password') }}</label>
<input type="password" class="control" name="password" v-validate="'required|min:6'" value="{{ old('password') }}">
<label for="password" class="required">{{ __('shop::app.customer.login-form.password') }}</label>
<input type="password" class="control" name="password" v-validate="'required|min:6'" value="{{ old('password') }}" data-vv-as="&quot;{{ __('shop::app.customer.login-form.password') }}&quot;">
<span class="control-error" v-if="errors.has('password')">@{{ errors.first('password') }}</span>
</div>
<div class="forgot-password-link">
<a href="{{ route('customer.forgot-password.create') }}">{{ __('shop::app.customer.login-form.forgot_pass') }}</a>
<div class="mt-10">
@if(Cookie::has('enable-resend'))
@if(Cookie::get('enable-resend') == true)
<a href="{{ route('customer.resend.verification-email', Cookie::get('email-for-resend')) }}">{{ __('shop::app.customer.login-form.resend-verification') }}</a>
@endif
@endif
</div>
</div>
<input class="btn btn-primary btn-lg" type="submit" value="{{ __('shop::app.customer.login-form.button_title') }}">

View File

@ -18,32 +18,32 @@
<div class="login-text">{{ __('shop::app.customer.signup-form.title') }}</div>
<div class="control-group" :class="[errors.has('first_name') ? 'has-error' : '']">
<label for="first_name">{{ __('shop::app.customer.signup-form.firstname') }}</label>
<input type="text" class="control" name="first_name" v-validate="'required'" value="{{ old('first_name') }}">
<label for="first_name" class="required">{{ __('shop::app.customer.signup-form.firstname') }}</label>
<input type="text" class="control" name="first_name" v-validate="'required'" value="{{ old('first_name') }}" data-vv-as="&quot;{{ __('shop::app.customer.signup-form.firstname') }}&quot;">
<span class="control-error" v-if="errors.has('first_name')">@{{ errors.first('first_name') }}</span>
</div>
<div class="control-group" :class="[errors.has('last_name') ? 'has-error' : '']">
<label for="last_name">{{ __('shop::app.customer.signup-form.lastname') }}</label>
<input type="text" class="control" name="last_name" v-validate="'required'" value="{{ old('last_name') }}">
<label for="last_name" class="required">{{ __('shop::app.customer.signup-form.lastname') }}</label>
<input type="text" class="control" name="last_name" v-validate="'required'" value="{{ old('last_name') }}" data-vv-as="&quot;{{ __('shop::app.customer.signup-form.lastname') }}&quot;">
<span class="control-error" v-if="errors.has('last_name')">@{{ errors.first('last_name') }}</span>
</div>
<div class="control-group" :class="[errors.has('email') ? 'has-error' : '']">
<label for="email">{{ __('shop::app.customer.signup-form.email') }}</label>
<input type="email" class="control" name="email" v-validate="'required|email'" value="{{ old('email') }}">
<label for="email" class="required">{{ __('shop::app.customer.signup-form.email') }}</label>
<input type="email" class="control" name="email" v-validate="'required|email'" value="{{ old('email') }}" data-vv-as="&quot;{{ __('shop::app.customer.signup-form.email') }}&quot;">
<span class="control-error" v-if="errors.has('email')">@{{ errors.first('email') }}</span>
</div>
<div class="control-group" :class="[errors.has('password') ? 'has-error' : '']">
<label for="password">{{ __('shop::app.customer.signup-form.password') }}</label>
<input type="password" class="control" name="password" v-validate="'required|min:6'" ref="password" value="{{ old('password') }}">
<label for="password" class="required">{{ __('shop::app.customer.signup-form.password') }}</label>
<input type="password" class="control" name="password" v-validate="'required|min:6'" ref="password" value="{{ old('password') }}" data-vv-as="&quot;{{ __('shop::app.customer.signup-form.password') }}&quot;">
<span class="control-error" v-if="errors.has('password')">@{{ errors.first('password') }}</span>
</div>
<div class="control-group" :class="[errors.has('password_confirmation') ? 'has-error' : '']">
<label for="password_confirmation">{{ __('shop::app.customer.signup-form.confirm_pass') }}</label>
<input type="password" class="control" name="password_confirmation" v-validate="'required|min:6|confirmed:password'">
<label for="password_confirmation" class="required">{{ __('shop::app.customer.signup-form.confirm_pass') }}</label>
<input type="password" class="control" name="password_confirmation" v-validate="'required|min:6|confirmed:password'" data-vv-as="&quot;{{ __('shop::app.customer.signup-form.confirm_pass') }}&quot;">
<span class="control-error" v-if="errors.has('password_confirmation')">@{{ errors.first('password_confirmation') }}</span>
</div>
@ -59,7 +59,7 @@
</div> --}}
<div class="control-group" :class="[errors.has('agreement') ? 'has-error' : '']">
<input type="checkbox" id="checkbox2" name="agreement" v-validate="'required'">
<input type="checkbox" id="checkbox2" name="agreement" v-validate="'required'" data-vv-as="&quot;{{ __('shop::app.customer.signup-form.agreement') }}&quot;">
<span>{{ __('shop::app.customer.signup-form.agree') }}
<a href="">{{ __('shop::app.customer.signup-form.terms') }}</a> & <a href="">{{ __('shop::app.customer.signup-form.conditions') }}</a> {{ __('shop::app.customer.signup-form.using') }}.
</span>

View File

@ -1,18 +1,26 @@
@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>
<div style="text-align: center;">
<a href="{{ config('app.url') }}">
<img src="{{ bagisto_asset('images/logo.svg') }}">
</a>
</div>
<div style="font-size:16px; color:#242424; font-weight:600; margin-top: 60px; margin-bottom: 15px">
Welcome to Bagisto - Email Subscription
</div>
<div>
You Can Unsubscribe From The List By Clicking Link Below.
Thanks for putting me into your inbox. Its been a while since youve read Bagisto
email, and we dont want to overwhelm your inbox. If you still do not want to receive
the latest email marketing news then for sure click the button below.
</div>
<div style="margin-top: 40px; text-align: center">
<a href="{{ route('shop.unsubscribe', $data['token']) }}" style="font-size: 16px;
color: #FFFFFF; text-align: center; background: #0031F0; padding: 10px 100px;text-decoration: none;">Unsubscribe</a>
</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

@ -0,0 +1,25 @@
@component('shop::emails.layouts.master')
<div>
<div style="text-align: center;">
<a href="{{ config('app.url') }}">
<img src="{{ bagisto_asset('images/logo.svg') }}">
</a>
</div>
<div style="font-size:16px; color:#242424; font-weight:600; margin-top: 60px; margin-bottom: 15px">
Bagisto - Email Verification
</div>
<div>
This is the mail to verify that the email address you entered is yours.
Kindly click the 'Verify Your Account' button below to verify your account.
</div>
<div style="margin-top: 40px; text-align: center">
<a href="{{ route('customer.verify', $data['token']) }}" style="font-size: 16px;
color: #FFFFFF; text-align: center; background: #0031F0; padding: 10px 100px;text-decoration: none;">Verify Your Account</a>
</div>
</div>
@endcomponent

View File

@ -21,12 +21,10 @@
<div class="list-container">
<span class="list-heading">{{ __('shop::app.footer.subscribe-newsletter') }}</span>
<div class="form-container">
<form action="{{ route('shop.subscribe') }}" @submit.prevent="onSubmit">
<form action="{{ route('shop.subscribe') }}">
<div class="control-group" :class="[errors.has('email') ? 'has-error' : '']">
<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>
</form>

View File

@ -188,6 +188,13 @@
</div> --}}
</div>
@auth('customer')
@if(auth()->guard('customer')->user()->is_verified == 0)
<div class="verify-account">
<span>{{ __('shop::app.home.verify-email') }}</span>
</div>
@endif
@endauth
</div>
@push('scripts')

View File

@ -1,7 +1,5 @@
<div class="cart-fav-seg">
@include ('shop::products.add-to-cart', ['product' => $product])
@include('shop::products.wishlist')
</div>

View File

@ -39,9 +39,9 @@
<div class="quantity control-group" :class="[errors.has('quantity') ? 'has-error' : '']">
<label class="reqiured">{{ __('shop::app.products.quantity') }}</label>
<label class="required">{{ __('shop::app.products.quantity') }}</label>
<input name="quantity" class="control" value="1" v-validate="'required|numeric|min_value:1'" style="width: 60px;">
<input name="quantity" class="control" value="1" v-validate="'required|numeric|min_value:1'" style="width: 60px;" data-vv-as="&quot;{{ __('shop::app.products.quantity') }}&quot;">
<span class="control-error" v-if="errors.has('quantity')">@{{ errors.first('quantity') }}</span>
</div>

View File

@ -12,9 +12,9 @@
<input type="hidden" name="selected_configurable_option" :value="selectedProductId">
<div v-for='(attribute, index) in childAttributes' class="attribute control-group" :class="[errors.has('super_attribute[' + attribute.id + ']') ? 'has-error' : '']">
<label class="reqiured">@{{ attribute.label }}</label>
<label class="required">@{{ attribute.label }}</label>
<select v-validate="'required'" class="control" :name="['super_attribute[' + attribute.id + ']']" :disabled="attribute.disabled" @change="configure(attribute, $event.target.value)" :id="['attribute_' + attribute.id]" data-vv-as="attribute">
<select v-validate="'required'" class="control" :name="['super_attribute[' + attribute.id + ']']" :disabled="attribute.disabled" @change="configure(attribute, $event.target.value)" :id="['attribute_' + attribute.id]" :data-vv-as="'&quot;' + attribute.label + '&quot;'">
<option v-for='(option, index) in attribute.options' :value="option.id">@{{ option.label }}</option>
@ -98,23 +98,23 @@
}
//wishlist anchor href changer with options
@auth('customer')
var wishlistLink = $('#wishlist-changer').attr('data-href');
// @auth('customer')
// var wishlistLink = $('#wishlist-changer').attr('data-href');
if(this.selectedProductId != '') {
var splitted = wishlistLink.split("/");
// if(this.selectedProductId != '') {
// var splitted = wishlistLink.split("/");
var lastItem = splitted.pop();
// var lastItem = splitted.pop();
lastItem = this.selectedProductId;
// lastItem = this.selectedProductId;
var joined = splitted.join('/');
// var joined = splitted.join('/');
var newWishlistUrl = joined + '/' + lastItem;
// var newWishlistUrl = joined + '/' + lastItem;
$('#wishlist-changer').attr('data-href', newWishlistUrl);
}
@endauth
// $('#wishlist-changer').attr('data-href', newWishlistUrl);
// }
// @endauth
//buy now anchor href changer with options
var buyNowLink = $('.btn.buynow').attr('data-href');

View File

@ -34,19 +34,15 @@
</ul>
<div class="product-hero-image" id="product-hero-image">
<img :src="currentLargeImageUrl" id="pro-img"/>
{{-- Uncomment the line below for activating share links --}}
{{-- @include('shop::products.sharelinks') --}}
@auth('customer')
<button type="submit" class="add-to-wishlist" data-href="{{ route('customer.wishlist.add', $product->id) }}" id="wishlist-changer">
</button>
<a class="add-to-wishlist" href="{{ route('customer.wishlist.add', $product->id) }}">
</a>
@endauth
</div>
</div>
</script>

View File

@ -1,7 +1,5 @@
<div class="add-to-buttons">
@include ('shop::products.add-to-cart', ['product' => $product])
@include ('shop::products.buy-now')
</div>

View File

@ -92,21 +92,24 @@ class TaxCategoryController extends Controller
$data = request()->input();
$this->validate(request(), [
'channel_id' => 'required|numeric',
'code' => 'required|string|unique:tax_categories,id',
'name' => 'required|string|unique:tax_categories,name',
'description' => 'required|string'
'description' => 'required|string',
'taxrates' => 'array|required'
]);
if($currentTaxCategory = $this->taxCategory->create(request()->input())) {
$allTaxCategorys = $data['taxrates'];
if($taxCategory = $this->taxCategory->create(request()->input())) {
$allTaxCategories = $data['taxrates'];
$this->taxCategory->onlyAttach($currentTaxCategory->id, $allTaxCategorys);
//attach the categories in the tax map table
$this->taxCategory->attachOrDetach($taxCategory, $allTaxCategories);
session()->flash('success', 'New Tax Category Created');
session()->flash('success', trans('admin::app.settings.tax-categories.create-success'));
return redirect()->route($this->_config['redirect']);
} else {
session()->flash('error', 'Cannot create the tax category');
session()->flash('error', trans('admin::app.settings.tax-categories.create-error'));
}
return view($this->_config['view']);
@ -132,33 +135,27 @@ class TaxCategoryController extends Controller
*/
public function update($id) {
//return the tax category data with the mapping table data also,
//allow the user to change the tax rates associated with the
// category also.
$this->validate(request(), [
'channel' => 'required|numeric',
'code' => 'required|string|unique:tax_categories,id,'.$id,
'channel_id' => 'required|numeric',
'code' => 'required|string|unique:tax_categories,code,'.$id,
'name' => 'required|string|unique:tax_categories,name,'.$id,
'description' => 'required|string',
'taxrates' => 'array|required'
]);
$data['channel_id'] = request()->input('channel');
$data = request()->input();
$data['code'] = request()->input('code');
if($taxCategory = $this->taxCategory->update($data, $id)) {
$taxRates = $data['taxrates'];
$data['name'] = request()->input('name');
//attach the categories in the tax map table
$this->taxCategory->attachOrDetach($taxCategory, $taxRates);
$data['description'] = request()->input('description');
if($this->taxRate->update($data, $id)) {
$this->taxCategory->syncAndDetach($id, request()->input('taxrates'));
session()->flash('success', 'Tax Category is successfully edited.');
session()->flash('success', trans('admin::app.settings.tax-categories.update-success'));
return redirect()->route($this->_config['redirect']);
} else {
session()->flash('error', 'Tax Category Cannot be Updated Successfully.');
session()->flash('error', trans('admin::app.settings.tax-categories.update-error'));
return redirect()->back();
}
@ -173,11 +170,11 @@ class TaxCategoryController extends Controller
public function destroy($id)
{
if($this->taxCategory->count() == 1) {
session()->flash('error', 'At least one tax category is required.');
session()->flash('error', trans('admin::app.settings.tax-categories.atleast-one'));
} else {
$this->taxCategorye->delete($id);
$this->taxCategory->delete($id);
session()->flash('success', 'Tax category deleted successfully.');
session()->flash('success', trans('admin::app.settings.tax-categories.delete'));
}
return redirect()->back();

View File

@ -85,24 +85,22 @@ class TaxRateController extends Controller
]);
$data = request()->all();
if(isset($data['is_zip'])) {
$data['is_zip'] = 1;
unset($data['zip_code']);
}
if($this->taxRate->create($data)) {
session()->flash('success', 'Tax Rate Created Successfully');
session()->flash('success', trans('admin::app.settings.tax-rates.create-success'));
return redirect()->route($this->_config['redirect']);
} else {
session()->flash('error', 'Cannot Create Tax Rate');
session()->flash('error', trans('admin::app.settings.tax-rates.create-error'));
return redirect()->back();
}
Session()->flash('warning', 'System Cannot Identify the cause of this error, contact system administrator.');
return redirect()->back();
}
@ -139,11 +137,11 @@ class TaxRateController extends Controller
]);
if($this->taxRate->update(request()->input(), $id)) {
session()->flash('success', 'Tax Rate Updated Successfully');
session()->flash('success', trans('admin::app.settings.tax-rates.update-success'));
return redirect()->route($this->_config['redirect']);
} else {
session()->flash('error', 'Cannot Create Tax Rate');
session()->flash('error', trans('admin::app.settings.tax-rates.update-error'));
return redirect()->back();
}
@ -160,11 +158,11 @@ class TaxRateController extends Controller
public function destroy($id)
{
if($this->taxRate->count() == 1) {
session()->flash('error', 'At least one tax rate is required.');
session()->flash('error', trans('admin::app.settings.tax-rates.atleast-one'));
} else {
$this->taxRate->delete($id);
session()->flash('success', 'Tax rate deleted successfully.');
session()->flash('success', trans('admin::app.settings.tax-rates.delete'));
}
return redirect()->back();

View File

@ -22,61 +22,11 @@ class TaxCategoryRepository extends Repository
return 'Webkul\Tax\Models\TaxCategory';
}
/**
* @param array $data
* @return mixed
*/
public function create(array $data)
{
$taxCategory = $this->model->create($data);
public function attachOrDetach($taxCategory, $data) {
$taxRates = $taxCategory->tax_rates;
return $taxCategory;
$this->model->findOrFail($taxCategory->id)->tax_rates()->sync($data);
return true;
}
/**
* @param array $data
* @param $id
* @param string $attribute
*
* @return mixed
*/
public function update(array $data, $id, $attribute = "id")
{
$taxCategory = $this->find($id);
$taxCategory->update($data);
return $taxmap;
}
/**
* Method to attach
* associations
*
* @return mixed
*/
public function onlyAttach($id, $taxRates) {
foreach($taxRates as $key => $value) {
$this->model->findOrFail($id)->tax_rates()->attach($id, ['tax_category_id' => $id, 'tax_rate_id' => $value]);
}
}
/**
* Method to detach
* and attach the
* associations
*
* @return mixed
*/
public function syncAndDetach($id, $taxRates) {
$this->model->findOrFail($id)->tax_rates()->detach();
foreach($taxRates as $key => $value) {
$this->model->findOrFail($id)->tax_rates()->attach($id, ['tax_category_id' => $id, 'tax_rate_id' => $value]);
}
}
}

View File

@ -21,30 +21,4 @@ class TaxRateRepository extends Repository
{
return 'Webkul\Tax\Models\TaxRate';
}
/**
* @param array $data
* @return mixed
*/
public function create(array $data)
{
$taxRate = $this->model->create($data);
return $taxRate;
}
/**
* @param array $data
* @param $id
* @param string $attribute
* @return mixed
*/
public function update(array $data, $id, $attribute = "id")
{
$taxRate = $this->find($id);
$taxRate->update($data);
return $taxRate;
}
}

View File

@ -55,19 +55,15 @@ class DataGrid
* Pagination variable
* @var String
*/
protected $perpage;
/**
* Table
*
* @var String Classs name $table
*/
protected $table;
/**
* Join
*
@ -82,82 +78,63 @@ class DataGrid
* 'callback' => 'not supported yet'
* ]
*/
protected $join;
/**
* Collection Object of Column $columns
*
* @var Collection
*/
protected $columns;
/**
* array of columns
* to be filtered
* @var Array
*/
protected $filterable;
/**
* array of columns
* to be searched
*
* @var Array
*/
protected $searchable;
/**
* mass operations
*
* @var Array
*/
protected $massoperations;
/**
* Pagination $pagination
*
* @var Pagination
*/
protected $pagination;
/**
* Css $css
*
* @var Css
*/
protected $css;
/**
* Actions $action
* @var action
*/
protected $actions;
/**
* URL parse $parsed
* @var parse
*/
protected $parsed;
/*
public function __construct(
$name = null ,
@ -515,10 +492,12 @@ class DataGrid
{
$parsed = [];
$unparsed = url()->full();
if (count(explode('?', $unparsed))>1) {
if (count(explode('?', $unparsed)) > 1) {
$to_be_parsed = explode('?', $unparsed)[1];
parse_str($to_be_parsed, $parsed);
unset($parsed['page']);
return $parsed;
} else {
return $parsed;

View File

@ -8,13 +8,12 @@
@endif
@foreach ($results as $result)
<tr>
<td class="">
{{-- <td class="">
<span class="checkbox">
<input type="checkbox" class="indexers" id="{{ $result->id }}" name="checkbox[]">
<label class="checkbox-view" for="checkbox1"></label>
</span>
</td>
</td> --}}
@foreach ($columns as $column)
<td class="">{!! $column->render($result) !!}</td>
@endforeach

View File

@ -1,5 +1,5 @@
<thead>
<tr class="mass-action" style="display: none; height:63px;">
{{-- <tr class="mass-action" style="display: none; height:63px;">
<th colspan="{{ count($columns)+1 }}">
<div class="mass-action-wrapper">
@ -7,7 +7,6 @@
<span class="icon checkbox-dash-icon"></span>
</span>
{{-- Mass operation implementation --}}
@foreach($massoperations as $massoperation)
@if($massoperation['type'] == "button")
@ -68,14 +67,14 @@
@endforeach
</div>
</th>
</tr>
</tr> --}}
<tr class="table-grid-header">
<th>
{{-- <th>
<span class="checkbox">
<input type="checkbox" id="mastercheckbox">
<label class="checkbox-view" for="checkbox"></label>
</span>
</th>
</th> --}}
@foreach ($columns as $column)
@if($column->sortable == "true")
<th class="grid_head sortable"