Subiendo proyecto completo sin restricciones de git ignore
This commit is contained in:
73
temp/Th5EMmj3vu/addons/pos_system/Utility/PosUtility.php
Normal file
73
temp/Th5EMmj3vu/addons/pos_system/Utility/PosUtility.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace App\Utility;
|
||||
|
||||
use App\Models\ProductStock;
|
||||
use App\Models\Address;
|
||||
use App\Models\Country;
|
||||
use App\Models\State;
|
||||
use App\Models\City;
|
||||
|
||||
class PosUtility
|
||||
{
|
||||
public static function product_search($request_data): object
|
||||
{
|
||||
$product_query = ProductStock::query()->join('products', 'product_stocks.product_id', '=', 'products.id');
|
||||
|
||||
if (auth()->user()->user_type == 'seller') {
|
||||
$product_query->where('products.user_id', auth()->user()->id);
|
||||
} else {
|
||||
$product_query->where('products.added_by', 'admin');
|
||||
}
|
||||
$products = $product_query->where('products.auction_product', 0)
|
||||
->where('products.wholesale_product', 0)
|
||||
->where('products.published', 1)
|
||||
->where('products.approved', 1)
|
||||
->select('products.*', 'product_stocks.id as stock_id', 'product_stocks.variant', 'product_stocks.price as stock_price', 'product_stocks.qty as stock_qty', 'product_stocks.image as stock_image')
|
||||
->orderBy('products.created_at', 'desc');
|
||||
|
||||
if ($request_data['category'] != null) {
|
||||
$arr = explode('-', $request_data['category']);
|
||||
if ($arr[0] == 'category') {
|
||||
$category_ids = CategoryUtility::children_ids($arr[1]);
|
||||
$category_ids[] = $arr[1];
|
||||
$products = $products->whereIn('products.category_id', $category_ids);
|
||||
}
|
||||
}
|
||||
|
||||
if ($request_data['brand'] != null) {
|
||||
$products = $products->where('products.brand_id', $request_data['brand']);
|
||||
}
|
||||
|
||||
if ($request_data['keyword'] != null) {
|
||||
$products = $products->where('products.name', 'like', '%' . $request_data['keyword'] . '%')->orWhere('products.barcode', $request_data['keyword']);
|
||||
}
|
||||
|
||||
return $products->paginate(16);
|
||||
}
|
||||
|
||||
public static function get_shipping_address($request) : array {
|
||||
if ($request->address_id != null) {
|
||||
$address = Address::findOrFail($request->address_id);
|
||||
$data['name'] = $address->user->name;
|
||||
$data['email'] = $address->user->email;
|
||||
$data['address'] = $address->address;
|
||||
$data['country'] = $address->country->name;
|
||||
$data['state'] = $address->state->name;
|
||||
$data['city'] = $address->city->name;
|
||||
$data['postal_code'] = $address->postal_code;
|
||||
$data['phone'] = $address->phone;
|
||||
} else {
|
||||
$data['name'] = $request->name;
|
||||
$data['email'] = $request->email;
|
||||
$data['address'] = $request->address;
|
||||
$data['country'] = Country::find($request->country_id)->name;
|
||||
$data['state'] = State::find($request->state_id)->name;
|
||||
$data['city'] = City::find($request->city_id)->name;
|
||||
$data['postal_code'] = $request->postal_code;
|
||||
$data['phone'] = $request->phone;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
BIN
temp/Th5EMmj3vu/addons/pos_system/assets/pos_banner.png
Normal file
BIN
temp/Th5EMmj3vu/addons/pos_system/assets/pos_banner.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 63 KiB |
91
temp/Th5EMmj3vu/addons/pos_system/config.json
Normal file
91
temp/Th5EMmj3vu/addons/pos_system/config.json
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"name" : "Point of Sale",
|
||||
|
||||
"unique_identifier" : "pos_system",
|
||||
|
||||
"version" : "2.1",
|
||||
|
||||
"minimum_item_version" : "7.5.0",
|
||||
|
||||
"addon_banner" : "pos_banner.png",
|
||||
|
||||
"directory" :
|
||||
[
|
||||
{
|
||||
"name" : [
|
||||
"resources/views/backend/pos",
|
||||
"resources/views/seller/pos"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
"sql_file" : "",
|
||||
|
||||
"files" :
|
||||
[
|
||||
{
|
||||
"root_directory" : "addons/pos_system/views/backend/pos/cart.blade.php",
|
||||
"update_directory" : "resources/views/backend/pos/cart.blade.php"
|
||||
},
|
||||
{
|
||||
"root_directory" : "addons/pos_system/views/backend/pos/guest_shipping_address.blade.php",
|
||||
"update_directory" : "resources/views/backend/pos/guest_shipping_address.blade.php"
|
||||
},
|
||||
{
|
||||
"root_directory" : "addons/pos_system/views/backend/pos/index.blade.php",
|
||||
"update_directory" : "resources/views/backend/pos/index.blade.php"
|
||||
},
|
||||
{
|
||||
"root_directory" : "addons/pos_system/views/backend/pos/pos_activation.blade.php",
|
||||
"update_directory" : "resources/views/backend/pos/pos_activation.blade.php"
|
||||
},
|
||||
{
|
||||
"root_directory" : "addons/pos_system/views/backend/pos/shipping_address.blade.php",
|
||||
"update_directory" : "resources/views/backend/pos/shipping_address.blade.php"
|
||||
},
|
||||
{
|
||||
"root_directory" : "addons/pos_system/views/backend/pos/variants.blade.php",
|
||||
"update_directory" : "resources/views/backend/pos/variants.blade.php"
|
||||
},
|
||||
{
|
||||
"root_directory" : "addons/pos_system/views/backend/pos/order_summary.blade.php",
|
||||
"update_directory" : "resources/views/backend/pos/order_summary.blade.php"
|
||||
},
|
||||
{
|
||||
"root_directory" : "addons/pos_system/views/backend/pos/thermal_invoice.blade.php",
|
||||
"update_directory" : "resources/views/backend/pos/thermal_invoice.blade.php"
|
||||
},
|
||||
{
|
||||
"root_directory" : "addons/pos_system/views/seller/pos/guest_shipping_address.blade.php",
|
||||
"update_directory" : "resources/views/seller/pos/guest_shipping_address.blade.php"
|
||||
},
|
||||
{
|
||||
"root_directory" : "addons/pos_system/views/seller/pos/index.blade.php",
|
||||
"update_directory" : "resources/views/seller/pos/index.blade.php"
|
||||
},
|
||||
{
|
||||
"root_directory" : "addons/pos_system/views/seller/pos/pos_activation.blade.php",
|
||||
"update_directory" : "resources/views/seller/pos/pos_activation.blade.php"
|
||||
},
|
||||
{
|
||||
"root_directory" : "addons/pos_system/views/seller/pos/shipping_address.blade.php",
|
||||
"update_directory" : "resources/views/seller/pos/shipping_address.blade.php"
|
||||
},
|
||||
{
|
||||
"root_directory" : "addons/pos_system/controllers/PosController.php",
|
||||
"update_directory" : "app/Http/Controllers/PosController.php"
|
||||
},
|
||||
{
|
||||
"root_directory" : "addons/pos_system/controllers/Seller/PosController.php",
|
||||
"update_directory" : "app/Http/Controllers/Seller/PosController.php"
|
||||
},
|
||||
{
|
||||
"root_directory" : "addons/pos_system/Utility/PosUtility.php",
|
||||
"update_directory" : "app/Utility/PosUtility.php"
|
||||
},
|
||||
{
|
||||
"root_directory" : "addons/pos_system/assets/pos_banner.png",
|
||||
"update_directory" : "public/pos_banner.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
397
temp/Th5EMmj3vu/addons/pos_system/controllers/PosController.php
Normal file
397
temp/Th5EMmj3vu/addons/pos_system/controllers/PosController.php
Normal file
@@ -0,0 +1,397 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\OrderDetail;
|
||||
use App\Models\ProductStock;
|
||||
use App\Models\Product;
|
||||
use App\Models\Order;
|
||||
use App\Models\City;
|
||||
use App\Models\User;
|
||||
use App\Models\Address;
|
||||
use App\Models\Addon;
|
||||
use Session;
|
||||
use Auth;
|
||||
use Mail;
|
||||
use App\Mail\InvoiceEmailManager;
|
||||
use App\Http\Resources\PosProductCollection;
|
||||
use App\Models\Country;
|
||||
use App\Models\State;
|
||||
use App\Utility\CategoryUtility;
|
||||
use App\Utility\FontUtility;
|
||||
use App\Utility\PosUtility;
|
||||
use Mpdf\Mpdf;
|
||||
|
||||
class PosController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
// Staff Permission Check
|
||||
$this->middleware(['permission:pos_manager'])->only('admin_index');
|
||||
$this->middleware(['permission:pos_configuration'])->only('pos_activation');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$customers = User::where('user_type', 'customer')->where('email_verified_at', '!=', null)->orderBy('created_at', 'desc')->get();
|
||||
return view('backend.pos.index', compact('customers'));
|
||||
}
|
||||
|
||||
public function search(Request $request)
|
||||
{
|
||||
$products = PosUtility::product_search($request->only('category', 'brand', 'keyword'));
|
||||
|
||||
$stocks = new PosProductCollection($products);
|
||||
$stocks->appends(['keyword' => $request->keyword, 'category' => $request->category, 'brand' => $request->brand]);
|
||||
return $stocks;
|
||||
}
|
||||
|
||||
public function addToCart(Request $request)
|
||||
{
|
||||
$stock = ProductStock::find($request->stock_id);
|
||||
$product = $stock->product;
|
||||
|
||||
$data = array();
|
||||
$data['stock_id'] = $request->stock_id;
|
||||
$data['id'] = $product->id;
|
||||
$data['variant'] = $stock->variant;
|
||||
$data['quantity'] = $product->min_qty;
|
||||
|
||||
if ($stock->qty < $product->min_qty && $product->digital == 0) {
|
||||
return array('success' => 0, 'message' => translate("This product doesn't have enough stock for minimum purchase quantity ") . $product->min_qty, 'view' => view('backend.pos.cart')->render());
|
||||
}
|
||||
|
||||
$tax = 0;
|
||||
$price = $stock->price;
|
||||
|
||||
// discount calculation
|
||||
$discount_applicable = false;
|
||||
if ($product->discount_start_date == null) {
|
||||
$discount_applicable = true;
|
||||
} elseif (
|
||||
strtotime(date('d-m-Y H:i:s')) >= $product->discount_start_date &&
|
||||
strtotime(date('d-m-Y H:i:s')) <= $product->discount_end_date
|
||||
) {
|
||||
$discount_applicable = true;
|
||||
}
|
||||
if ($discount_applicable) {
|
||||
if ($product->discount_type == 'percent') {
|
||||
$price -= ($price * $product->discount) / 100;
|
||||
} elseif ($product->discount_type == 'amount') {
|
||||
$price -= $product->discount;
|
||||
}
|
||||
}
|
||||
|
||||
//tax calculation
|
||||
foreach ($product->taxes as $product_tax) {
|
||||
if ($product_tax->tax_type == 'percent') {
|
||||
$tax += ($price * $product_tax->tax) / 100;
|
||||
} elseif ($product_tax->tax_type == 'amount') {
|
||||
$tax += $product_tax->tax;
|
||||
}
|
||||
}
|
||||
|
||||
$data['price'] = $price;
|
||||
$data['tax'] = $tax;
|
||||
|
||||
if ($request->session()->has('pos.cart')) {
|
||||
$foundInCart = false;
|
||||
$cart = collect();
|
||||
|
||||
foreach ($request->session()->get('pos.cart') as $key => $cartItem) {
|
||||
|
||||
if ($cartItem['id'] == $product->id && $cartItem['stock_id'] == $stock->id) {
|
||||
$foundInCart = true;
|
||||
|
||||
if ($product->digital == 0) {
|
||||
$loop_product = Product::find($cartItem['id']);
|
||||
$product_stock = $loop_product->stocks->where('variant', $cartItem['variant'])->first();
|
||||
|
||||
if ($product->digital == 1 || $product_stock->qty >= ($cartItem['quantity'] + 1)) {
|
||||
$cartItem['quantity'] += 1;
|
||||
} else {
|
||||
return array('success' => 0, 'message' => translate("This product doesn't have more stock."), 'view' => view('backend.pos.cart')->render());
|
||||
}
|
||||
} else {
|
||||
return array('success' => 0, 'message' => translate("This product is alreday in the cart"), 'view' => view('backend.pos.cart')->render());
|
||||
}
|
||||
}
|
||||
$cart->push($cartItem);
|
||||
}
|
||||
|
||||
if (!$foundInCart) {
|
||||
$cart->push($data);
|
||||
}
|
||||
$request->session()->put('pos.cart', $cart);
|
||||
} else {
|
||||
$cart = collect([$data]);
|
||||
$request->session()->put('pos.cart', $cart);
|
||||
}
|
||||
|
||||
$request->session()->put('pos.cart', $cart);
|
||||
|
||||
return array('success' => 1, 'message' => '', 'view' => view('backend.pos.cart')->render());
|
||||
}
|
||||
|
||||
//updated the quantity for a cart item
|
||||
public function updateQuantity(Request $request)
|
||||
{
|
||||
$cart = $request->session()->get('pos.cart', collect([]));
|
||||
$cart = $cart->map(function ($object, $key) use ($request) {
|
||||
if ($key == $request->key) {
|
||||
$product = Product::find($object['id']);
|
||||
$product_stock = $product->stocks->where('id', $object['stock_id'])->first();
|
||||
|
||||
if ($product_stock->qty >= $request->quantity) {
|
||||
$object['quantity'] = $request->quantity;
|
||||
} else {
|
||||
return array('success' => 0, 'message' => translate("This product doesn't have more stock."), 'view' => view('backend.pos.cart')->render());
|
||||
}
|
||||
}
|
||||
return $object;
|
||||
});
|
||||
$request->session()->put('pos.cart', $cart);
|
||||
|
||||
return array('success' => 1, 'message' => '', 'view' => view('backend.pos.cart')->render());
|
||||
}
|
||||
|
||||
//removes from Cart
|
||||
public function removeFromCart(Request $request)
|
||||
{
|
||||
if (Session::has('pos.cart')) {
|
||||
$cart = Session::get('pos.cart', collect([]));
|
||||
$cart->forget($request->key);
|
||||
Session::put('pos.cart', $cart);
|
||||
|
||||
$request->session()->put('pos.cart', $cart);
|
||||
}
|
||||
|
||||
return view('backend.pos.cart');
|
||||
}
|
||||
|
||||
//Shipping Address for admin
|
||||
public function getShippingAddress(Request $request)
|
||||
{
|
||||
$user_id = $request->id;
|
||||
if ($user_id == '') {
|
||||
return view('backend.pos.guest_shipping_address');
|
||||
} else {
|
||||
return view('backend.pos.shipping_address', compact('user_id'));
|
||||
}
|
||||
}
|
||||
|
||||
public function set_shipping_address(Request $request)
|
||||
{
|
||||
$data = PosUtility::get_shipping_address($request);
|
||||
|
||||
$shipping_info = $data;
|
||||
$request->session()->put('pos.shipping_info', $shipping_info);
|
||||
}
|
||||
|
||||
//set Discount
|
||||
public function setDiscount(Request $request)
|
||||
{
|
||||
if ($request->discount >= 0) {
|
||||
Session::put('pos.discount', $request->discount);
|
||||
}
|
||||
return view('backend.pos.cart');
|
||||
}
|
||||
|
||||
//set Shipping Cost
|
||||
public function setShipping(Request $request)
|
||||
{
|
||||
if ($request->shipping != null) {
|
||||
Session::put('pos.shipping', $request->shipping);
|
||||
}
|
||||
return view('backend.pos.cart');
|
||||
}
|
||||
|
||||
//order summary
|
||||
public function get_order_summary(Request $request)
|
||||
{
|
||||
return view('backend.pos.order_summary');
|
||||
}
|
||||
|
||||
//order place
|
||||
public function order_store(Request $request)
|
||||
{
|
||||
if (Session::get('pos.shipping_info') == null || Session::get('pos.shipping_info')['name'] == null || Session::get('pos.shipping_info')['phone'] == null || Session::get('pos.shipping_info')['address'] == null) {
|
||||
return array('success' => 0, 'message' => translate("Please Add Shipping Information."));
|
||||
}
|
||||
|
||||
if (Session::has('pos.cart') && count(Session::get('pos.cart')) > 0) {
|
||||
$order = new Order;
|
||||
|
||||
if ($request->user_id == null) {
|
||||
$order->guest_id = mt_rand(100000, 999999);
|
||||
} else {
|
||||
$order->user_id = $request->user_id;
|
||||
}
|
||||
$order->shipping_address = json_encode(Session::get('pos.shipping_info'));
|
||||
|
||||
$order->payment_type = $request->payment_type;
|
||||
$order->delivery_viewed = '0';
|
||||
$order->payment_status_viewed = '0';
|
||||
$order->code = date('Ymd-His') . rand(10, 99);
|
||||
$order->date = strtotime('now');
|
||||
$order->payment_status = $request->payment_type != 'cash_on_delivery' ? 'paid' : 'unpaid';
|
||||
$order->payment_details = $request->payment_type;
|
||||
$order->order_from = 'pos';
|
||||
|
||||
if ($request->payment_type == 'offline_payment') {
|
||||
if ($request->offline_trx_id == null) {
|
||||
return array('success' => 0, 'message' => translate("Transaction ID can not be null."));
|
||||
}
|
||||
$data['name'] = $request->offline_payment_method;
|
||||
$data['amount'] = $request->offline_payment_amount;
|
||||
$data['trx_id'] = $request->offline_trx_id;
|
||||
$data['photo'] = $request->offline_payment_proof;
|
||||
$order->manual_payment_data = json_encode($data);
|
||||
$order->manual_payment = 1;
|
||||
}
|
||||
|
||||
if ($order->save()) {
|
||||
$subtotal = 0;
|
||||
$tax = 0;
|
||||
foreach (Session::get('pos.cart') as $key => $cartItem) {
|
||||
$product_stock = ProductStock::find($cartItem['stock_id']);
|
||||
$product = $product_stock->product;
|
||||
$product_variation = $product_stock->variant;
|
||||
|
||||
$subtotal += $cartItem['price'] * $cartItem['quantity'];
|
||||
$tax += $cartItem['tax'] * $cartItem['quantity'];
|
||||
|
||||
if ($product->digital == 0) {
|
||||
if ($cartItem['quantity'] > $product_stock->qty) {
|
||||
$order->delete();
|
||||
return array('success' => 0, 'message' => $product->name . ' (' . $product_variation . ') ' . translate(" just stock outs."));
|
||||
} else {
|
||||
$product_stock->qty -= $cartItem['quantity'];
|
||||
$product_stock->save();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$order_detail = new OrderDetail;
|
||||
$order_detail->order_id = $order->id;
|
||||
$order_detail->seller_id = $product->user_id;
|
||||
$order_detail->product_id = $product->id;
|
||||
$order_detail->payment_status = $request->payment_type != 'cash_on_delivery' ? 'paid' : 'unpaid';
|
||||
$order_detail->variation = $product_variation;
|
||||
$order_detail->price = $cartItem['price'] * $cartItem['quantity'];
|
||||
$order_detail->tax = $cartItem['tax'] * $cartItem['quantity'];
|
||||
$order_detail->quantity = $cartItem['quantity'];
|
||||
$order_detail->shipping_type = null;
|
||||
|
||||
if (Session::get('pos.shipping', 0) >= 0) {
|
||||
$order_detail->shipping_cost = Session::get('pos.shipping', 0) / count(Session::get('pos.cart'));
|
||||
} else {
|
||||
$order_detail->shipping_cost = 0;
|
||||
}
|
||||
|
||||
$order_detail->save();
|
||||
|
||||
$product->num_of_sale++;
|
||||
$product->save();
|
||||
}
|
||||
|
||||
$order->grand_total = $subtotal + $tax + Session::get('pos.shipping', 0);
|
||||
|
||||
if (Session::has('pos.discount')) {
|
||||
$order->grand_total -= Session::get('pos.discount');
|
||||
$order->coupon_discount = Session::get('pos.discount');
|
||||
}
|
||||
|
||||
$order->seller_id = $product->user_id;
|
||||
$order->save();
|
||||
|
||||
$array['view'] = 'emails.invoice';
|
||||
$array['subject'] = 'Your order has been placed - ' . $order->code;
|
||||
$array['from'] = env('MAIL_USERNAME');
|
||||
$array['order'] = $order;
|
||||
|
||||
$admin_products = array();
|
||||
$seller_products = array();
|
||||
|
||||
foreach ($order->orderDetails as $key => $orderDetail) {
|
||||
if ($orderDetail->product->added_by == 'admin') {
|
||||
array_push($admin_products, $orderDetail->product->id);
|
||||
} else {
|
||||
$product_ids = array();
|
||||
if (array_key_exists($orderDetail->product->user_id, $seller_products)) {
|
||||
$product_ids = $seller_products[$orderDetail->product->user_id];
|
||||
}
|
||||
array_push($product_ids, $orderDetail->product->id);
|
||||
$seller_products[$orderDetail->product->user_id] = $product_ids;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($seller_products as $key => $seller_product) {
|
||||
try {
|
||||
Mail::to(User::find($key)->email)->queue(new InvoiceEmailManager($array));
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
//sends email to customer with the invoice pdf attached
|
||||
if (env('MAIL_USERNAME') != null) {
|
||||
try {
|
||||
Mail::to($request->session()->get('pos.shipping_info')['email'])->queue(new InvoiceEmailManager($array));
|
||||
Mail::to(User::where('user_type', 'admin')->first()->email)->queue(new InvoiceEmailManager($array));
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->user_id != NULL && $order->payment_status == 'paid') {
|
||||
calculateCommissionAffilationClubPoint($order);
|
||||
}
|
||||
|
||||
Session::forget('pos.shipping_info');
|
||||
Session::forget('pos.shipping');
|
||||
Session::forget('pos.discount');
|
||||
Session::forget('pos.cart');
|
||||
return array('success' => 1, 'message' => translate('Order Completed Successfully.'));
|
||||
} else {
|
||||
return array('success' => 0, 'message' => translate('Please input customer information.'));
|
||||
}
|
||||
}
|
||||
return array('success' => 0, 'message' => translate("Please select a product."));
|
||||
}
|
||||
|
||||
public function configuration()
|
||||
{
|
||||
return view('backend.pos.pos_activation');
|
||||
}
|
||||
|
||||
public function invoice($id)
|
||||
{
|
||||
$order = Order::findOrFail($id);
|
||||
|
||||
$print_width = get_setting('print_width');
|
||||
if ($print_width == null) {
|
||||
flash(translate('Thermal printer size is not given in POS configuration'))->warning();
|
||||
return back();
|
||||
}
|
||||
|
||||
$pdf_style_data = FontUtility::get_font_family();
|
||||
|
||||
$html = view('backend.pos.thermal_invoice', compact('order', 'pdf_style_data'));
|
||||
|
||||
$mpdf = new Mpdf(['mode' => 'utf-8', 'format' => [$print_width, 1000]]);
|
||||
$mpdf->WriteHTML($html);
|
||||
// $mpdf->WriteHTML('<h1>Hello world!</h1>');
|
||||
$mpdf->page = 0;
|
||||
$mpdf->state = 0;
|
||||
unset($mpdf->pages[0]);
|
||||
// The $p needs to be passed by reference
|
||||
$p = 'P';
|
||||
// dd($mpdf->y);
|
||||
$mpdf->_setPageSize(array($print_width, $mpdf->y), $p);
|
||||
|
||||
$mpdf->addPage();
|
||||
$mpdf->WriteHTML($html);
|
||||
|
||||
$mpdf->Output('order-' . $order->code . '.pdf', 'I');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,403 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Seller;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\OrderDetail;
|
||||
use App\Models\ProductStock;
|
||||
use App\Models\Product;
|
||||
use App\Models\Order;
|
||||
use App\Models\City;
|
||||
use App\Models\User;
|
||||
use App\Models\Address;
|
||||
use App\Models\Addon;
|
||||
use Session;
|
||||
use Auth;
|
||||
use Mail;
|
||||
use App\Mail\InvoiceEmailManager;
|
||||
use App\Http\Resources\PosProductCollection;
|
||||
use App\Models\Country;
|
||||
use App\Models\State;
|
||||
use App\Utility\CategoryUtility;
|
||||
use App\Utility\FontUtility;
|
||||
use App\Utility\PosUtility;
|
||||
use Mpdf\Mpdf;
|
||||
|
||||
class PosController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$customers = User::where('user_type', 'customer')->where('email_verified_at', '!=', null)->orderBy('created_at', 'desc')->get();
|
||||
if (get_setting('pos_activation_for_seller') == 1) {
|
||||
return view('seller.pos.index', compact('customers'));
|
||||
}
|
||||
else {
|
||||
flash(translate('POS is disable for Sellers!!!'))->error();
|
||||
return back();
|
||||
}
|
||||
}
|
||||
|
||||
public function search(Request $request)
|
||||
{
|
||||
$products = PosUtility::product_search($request->only('category', 'brand', 'keyword'));
|
||||
|
||||
$stocks = new PosProductCollection($products);
|
||||
$stocks->appends(['keyword' => $request->keyword, 'category' => $request->category, 'brand' => $request->brand]);
|
||||
return $stocks;
|
||||
}
|
||||
|
||||
public function addToCart(Request $request)
|
||||
{
|
||||
$stock = ProductStock::find($request->stock_id);
|
||||
$product = $stock->product;
|
||||
|
||||
$data = array();
|
||||
$data['stock_id'] = $request->stock_id;
|
||||
$data['id'] = $product->id;
|
||||
$data['variant'] = $stock->variant;
|
||||
$data['quantity'] = $product->min_qty;
|
||||
|
||||
if($stock->qty < $product->min_qty && $product->digital == 0){
|
||||
return array('success' => 0, 'message' => translate("This product doesn't have enough stock for minimum purchase quantity ").$product->min_qty, 'view' => view('backend.pos.cart')->render());
|
||||
}
|
||||
|
||||
$tax = 0;
|
||||
$price = $stock->price;
|
||||
|
||||
// discount calculation
|
||||
$discount_applicable = false;
|
||||
if ($product->discount_start_date == null) {
|
||||
$discount_applicable = true;
|
||||
}
|
||||
elseif (strtotime(date('d-m-Y H:i:s')) >= $product->discount_start_date &&
|
||||
strtotime(date('d-m-Y H:i:s')) <= $product->discount_end_date) {
|
||||
$discount_applicable = true;
|
||||
}
|
||||
if ($discount_applicable) {
|
||||
if($product->discount_type == 'percent'){
|
||||
$price -= ($price*$product->discount)/100;
|
||||
}
|
||||
elseif($product->discount_type == 'amount'){
|
||||
$price -= $product->discount;
|
||||
}
|
||||
}
|
||||
|
||||
//tax calculation
|
||||
foreach ($product->taxes as $product_tax) {
|
||||
if($product_tax->tax_type == 'percent'){
|
||||
$tax += ($price * $product_tax->tax) / 100;
|
||||
}
|
||||
elseif($product_tax->tax_type == 'amount'){
|
||||
$tax += $product_tax->tax;
|
||||
}
|
||||
}
|
||||
|
||||
$data['price'] = $price;
|
||||
$data['tax'] = $tax;
|
||||
|
||||
if($request->session()->has('pos.cart')){
|
||||
$foundInCart = false;
|
||||
$cart = collect();
|
||||
|
||||
foreach ($request->session()->get('pos.cart') as $key => $cartItem){
|
||||
|
||||
if($cartItem['id'] == $product->id && $cartItem['stock_id'] == $stock->id){
|
||||
$foundInCart = true;
|
||||
|
||||
if($product->digital == 0){
|
||||
$loop_product = Product::find($cartItem['id']);
|
||||
$product_stock = $loop_product->stocks->where('variant', $cartItem['variant'])->first();
|
||||
|
||||
if($product->digital == 1 || $product_stock->qty >= ($cartItem['quantity'] + 1)){
|
||||
$cartItem['quantity'] += 1;
|
||||
}else{
|
||||
return array('success' => 0, 'message' => translate("This product doesn't have more stock."), 'view' => view('backend.pos.cart')->render());
|
||||
}
|
||||
}
|
||||
else{
|
||||
return array('success' => 0, 'message' => translate("This product is alreday in the cart"), 'view' => view('backend.pos.cart')->render());
|
||||
}
|
||||
|
||||
}
|
||||
$cart->push($cartItem);
|
||||
}
|
||||
|
||||
if (!$foundInCart) {
|
||||
$cart->push($data);
|
||||
}
|
||||
$request->session()->put('pos.cart', $cart);
|
||||
}
|
||||
else{
|
||||
$cart = collect([$data]);
|
||||
$request->session()->put('pos.cart', $cart);
|
||||
}
|
||||
|
||||
$request->session()->put('pos.cart', $cart);
|
||||
|
||||
return array('success' => 1, 'message' => '', 'view' => view('backend.pos.cart')->render());
|
||||
}
|
||||
|
||||
//updated the quantity for a cart item
|
||||
public function updateQuantity(Request $request)
|
||||
{
|
||||
$cart = $request->session()->get('pos.cart', collect([]));
|
||||
$cart = $cart->map(function ($object, $key) use ($request) {
|
||||
if($key == $request->key){
|
||||
$product = Product::find($object['id']);
|
||||
$product_stock = $product->stocks->where('id', $object['stock_id'])->first();
|
||||
|
||||
if($product_stock->qty >= $request->quantity){
|
||||
$object['quantity'] = $request->quantity;
|
||||
}else{
|
||||
return array('success' => 0, 'message' => translate("This product doesn't have more stock."), 'view' => view('backend.pos.cart')->render());
|
||||
}
|
||||
}
|
||||
return $object;
|
||||
});
|
||||
$request->session()->put('pos.cart', $cart);
|
||||
|
||||
return array('success' => 1, 'message' => '', 'view' => view('backend.pos.cart')->render());
|
||||
}
|
||||
|
||||
//removes from Cart
|
||||
public function removeFromCart(Request $request)
|
||||
{
|
||||
if(Session::has('pos.cart')){
|
||||
$cart = Session::get('pos.cart', collect([]));
|
||||
$cart->forget($request->key);
|
||||
Session::put('pos.cart', $cart);
|
||||
|
||||
$request->session()->put('pos.cart', $cart);
|
||||
}
|
||||
|
||||
return view('backend.pos.cart');
|
||||
}
|
||||
|
||||
//Shipping Address for seller
|
||||
public function getShippingAddressForSeller(Request $request)
|
||||
{
|
||||
$user_id = $request->id;
|
||||
return ($user_id == '') ?
|
||||
view('seller.pos.guest_shipping_address') :
|
||||
view('seller.pos.shipping_address', compact('user_id'));
|
||||
}
|
||||
|
||||
public function set_shipping_address(Request $request)
|
||||
{
|
||||
$data = PosUtility::get_shipping_address($request);
|
||||
|
||||
$shipping_info = $data;
|
||||
$request->session()->put('pos.shipping_info', $shipping_info);
|
||||
}
|
||||
|
||||
//set Discount
|
||||
public function setDiscount(Request $request){
|
||||
if($request->discount >= 0){
|
||||
Session::put('pos.discount', $request->discount);
|
||||
}
|
||||
return view('backend.pos.cart');
|
||||
}
|
||||
|
||||
//set Shipping Cost
|
||||
public function setShipping(Request $request){
|
||||
if($request->shipping != null){
|
||||
Session::put('pos.shipping', $request->shipping);
|
||||
}
|
||||
return view('backend.pos.cart');
|
||||
}
|
||||
|
||||
//order summary
|
||||
public function get_order_summary(Request $request){
|
||||
return view('backend.pos.order_summary');
|
||||
}
|
||||
|
||||
//order place
|
||||
public function order_store(Request $request){
|
||||
if(Session::get('pos.shipping_info') == null || Session::get('pos.shipping_info')['name'] == null || Session::get('pos.shipping_info')['phone'] == null || Session::get('pos.shipping_info')['address'] == null){
|
||||
return array('success' => 0, 'message' => translate("Please Add Shipping Information."));
|
||||
}
|
||||
|
||||
if(Session::has('pos.cart') && count(Session::get('pos.cart')) > 0){
|
||||
$order = new Order;
|
||||
|
||||
if ($request->user_id == null) {
|
||||
$order->guest_id = mt_rand(100000, 999999);
|
||||
}
|
||||
else {
|
||||
$order->user_id = $request->user_id;
|
||||
}
|
||||
|
||||
$order->shipping_address = json_encode(Session::get('pos.shipping_info'));
|
||||
|
||||
$order->payment_type = $request->payment_type;
|
||||
$order->delivery_viewed = '0';
|
||||
$order->payment_status_viewed = '0';
|
||||
$order->code = date('Ymd-His').rand(10,99);
|
||||
$order->date = strtotime('now');
|
||||
$order->payment_status = $request->payment_type != 'cash_on_delivery' ? 'paid' : 'unpaid';
|
||||
$order->payment_details = $request->payment_type;
|
||||
$order->order_from = 'pos';
|
||||
|
||||
if($request->payment_type == 'offline_payment'){
|
||||
if($request->offline_trx_id == null){
|
||||
return array('success' => 0, 'message' => translate("Transaction ID can not be null."));
|
||||
}
|
||||
$data['name'] = $request->offline_payment_method;
|
||||
$data['amount'] = $request->offline_payment_amount;
|
||||
$data['trx_id'] = $request->offline_trx_id;
|
||||
$data['photo'] = $request->offline_payment_proof;
|
||||
$order->manual_payment_data = json_encode($data);
|
||||
$order->manual_payment = 1;
|
||||
}
|
||||
|
||||
if($order->save()){
|
||||
$subtotal = 0;
|
||||
$tax = 0;
|
||||
foreach (Session::get('pos.cart') as $key => $cartItem){
|
||||
$product_stock = ProductStock::find($cartItem['stock_id']);
|
||||
$product = $product_stock->product;
|
||||
$product_variation = $product_stock->variant;
|
||||
|
||||
$subtotal += $cartItem['price']*$cartItem['quantity'];
|
||||
$tax += $cartItem['tax']*$cartItem['quantity'];
|
||||
|
||||
if($product->digital == 0){
|
||||
if($cartItem['quantity'] > $product_stock->qty){
|
||||
$order->delete();
|
||||
return array('success' => 0, 'message' => $product->name.' ('.$product_variation.') '.translate(" just stock outs."));
|
||||
}
|
||||
else {
|
||||
$product_stock->qty -= $cartItem['quantity'];
|
||||
$product_stock->save();
|
||||
}
|
||||
}
|
||||
|
||||
$order_detail = new OrderDetail;
|
||||
$order_detail->order_id =$order->id;
|
||||
$order_detail->seller_id = $product->user_id;
|
||||
$order_detail->product_id = $product->id;
|
||||
$order_detail->payment_status = $request->payment_type != 'cash_on_delivery' ? 'paid' : 'unpaid';
|
||||
$order_detail->variation = $product_variation;
|
||||
$order_detail->price = $cartItem['price'] * $cartItem['quantity'];
|
||||
$order_detail->tax = $cartItem['tax'] * $cartItem['quantity'];
|
||||
$order_detail->quantity = $cartItem['quantity'];
|
||||
$order_detail->shipping_type = null;
|
||||
|
||||
if (Session::get('pos.shipping', 0) >= 0){
|
||||
$order_detail->shipping_cost = Session::get('pos.shipping', 0)/count(Session::get('pos.cart'));
|
||||
}
|
||||
else {
|
||||
$order_detail->shipping_cost = 0;
|
||||
}
|
||||
|
||||
$order_detail->save();
|
||||
|
||||
$product->num_of_sale++;
|
||||
$product->save();
|
||||
}
|
||||
|
||||
$order->grand_total = $subtotal + $tax + Session::get('pos.shipping', 0);
|
||||
|
||||
if(Session::has('pos.discount')){
|
||||
$order->grand_total -= Session::get('pos.discount');
|
||||
$order->coupon_discount = Session::get('pos.discount');
|
||||
}
|
||||
|
||||
$order->seller_id = $product->user_id;
|
||||
$order->save();
|
||||
|
||||
$array['view'] = 'emails.invoice';
|
||||
$array['subject'] = 'Your order has been placed - '.$order->code;
|
||||
$array['from'] = env('MAIL_USERNAME');
|
||||
$array['order'] = $order;
|
||||
|
||||
$admin_products = array();
|
||||
$seller_products = array();
|
||||
|
||||
foreach ($order->orderDetails as $key => $orderDetail){
|
||||
if($orderDetail->product->added_by == 'admin'){
|
||||
array_push($admin_products, $orderDetail->product->id);
|
||||
}
|
||||
else{
|
||||
$product_ids = array();
|
||||
if(array_key_exists($orderDetail->product->user_id, $seller_products)){
|
||||
$product_ids = $seller_products[$orderDetail->product->user_id];
|
||||
}
|
||||
array_push($product_ids, $orderDetail->product->id);
|
||||
$seller_products[$orderDetail->product->user_id] = $product_ids;
|
||||
}
|
||||
}
|
||||
|
||||
foreach($seller_products as $key => $seller_product){
|
||||
try {
|
||||
Mail::to(User::find($key)->email)->queue(new InvoiceEmailManager($array));
|
||||
} catch (\Exception $e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//sends email to customer with the invoice pdf attached
|
||||
if(env('MAIL_USERNAME') != null){
|
||||
try {
|
||||
Mail::to($request->session()->get('pos.shipping_info')['email'])->queue(new InvoiceEmailManager($array));
|
||||
Mail::to(User::where('user_type', 'admin')->first()->email)->queue(new InvoiceEmailManager($array));
|
||||
} catch (\Exception $e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if($request->user_id != NULL && $order->payment_status == 'paid') {
|
||||
calculateCommissionAffilationClubPoint($order);
|
||||
}
|
||||
|
||||
Session::forget('pos.shipping_info');
|
||||
Session::forget('pos.shipping');
|
||||
Session::forget('pos.discount');
|
||||
Session::forget('pos.cart');
|
||||
return array('success' => 1, 'message' => translate('Order Completed Successfully.'));
|
||||
}
|
||||
else {
|
||||
return array('success' => 0, 'message' => translate('Please input customer information.'));
|
||||
}
|
||||
}
|
||||
return array('success' => 0, 'message' => translate("Please select a product."));
|
||||
}
|
||||
|
||||
public function configuration()
|
||||
{
|
||||
return view('seller.pos.pos_activation');
|
||||
}
|
||||
|
||||
public function invoice($id)
|
||||
{
|
||||
$order = Order::findOrFail($id);
|
||||
if(auth()->user()->id != $order->seller_id) {
|
||||
return back();
|
||||
}
|
||||
$print_width = get_setting('print_width_seller_pos');
|
||||
if ($print_width == null) {
|
||||
flash(translate('Print Size does not set for thermal printer from POS configuration'))->warning();
|
||||
return back();
|
||||
}
|
||||
|
||||
$pdf_style_data = FontUtility::get_font_family();
|
||||
|
||||
$html = view('backend.pos.thermal_invoice', compact('order', 'pdf_style_data'));
|
||||
|
||||
$mpdf = new Mpdf(['mode' => 'utf-8', 'format' => [$print_width, 1000]]);
|
||||
$mpdf->WriteHTML($html);
|
||||
// $mpdf->WriteHTML('<h1>Hello world!</h1>');
|
||||
$mpdf->page = 0;
|
||||
$mpdf->state = 0;
|
||||
unset($mpdf->pages[0]);
|
||||
// The $p needs to be passed by reference
|
||||
$p = 'P';
|
||||
// dd($mpdf->y);
|
||||
$mpdf->_setPageSize(array($print_width, $mpdf->y), $p);
|
||||
|
||||
$mpdf->addPage();
|
||||
$mpdf->WriteHTML($html);
|
||||
|
||||
$mpdf->Output('order-' . $order->code . '.pdf', 'I');
|
||||
}
|
||||
}
|
||||
Binary file not shown.
1
temp/Th5EMmj3vu/addons/pos_system/sql/1.1.sql
Normal file
1
temp/Th5EMmj3vu/addons/pos_system/sql/1.1.sql
Normal file
@@ -0,0 +1 @@
|
||||
COMMIT;
|
||||
1
temp/Th5EMmj3vu/addons/pos_system/sql/1.2.sql
Normal file
1
temp/Th5EMmj3vu/addons/pos_system/sql/1.2.sql
Normal file
@@ -0,0 +1 @@
|
||||
COMMIT;
|
||||
1
temp/Th5EMmj3vu/addons/pos_system/sql/1.3.sql
Normal file
1
temp/Th5EMmj3vu/addons/pos_system/sql/1.3.sql
Normal file
@@ -0,0 +1 @@
|
||||
COMMIT;
|
||||
1
temp/Th5EMmj3vu/addons/pos_system/sql/1.4.sql
Normal file
1
temp/Th5EMmj3vu/addons/pos_system/sql/1.4.sql
Normal file
@@ -0,0 +1 @@
|
||||
COMMIT;
|
||||
1
temp/Th5EMmj3vu/addons/pos_system/sql/1.5.sql
Normal file
1
temp/Th5EMmj3vu/addons/pos_system/sql/1.5.sql
Normal file
@@ -0,0 +1 @@
|
||||
COMMIT;
|
||||
1
temp/Th5EMmj3vu/addons/pos_system/sql/1.6.sql
Normal file
1
temp/Th5EMmj3vu/addons/pos_system/sql/1.6.sql
Normal file
@@ -0,0 +1 @@
|
||||
COMMIT;
|
||||
1
temp/Th5EMmj3vu/addons/pos_system/sql/1.7.sql
Normal file
1
temp/Th5EMmj3vu/addons/pos_system/sql/1.7.sql
Normal file
@@ -0,0 +1 @@
|
||||
COMMIT;
|
||||
1
temp/Th5EMmj3vu/addons/pos_system/sql/1.8.sql
Normal file
1
temp/Th5EMmj3vu/addons/pos_system/sql/1.8.sql
Normal file
@@ -0,0 +1 @@
|
||||
COMMIT;
|
||||
1
temp/Th5EMmj3vu/addons/pos_system/sql/1.9.sql
Normal file
1
temp/Th5EMmj3vu/addons/pos_system/sql/1.9.sql
Normal file
@@ -0,0 +1 @@
|
||||
COMMIT;
|
||||
1
temp/Th5EMmj3vu/addons/pos_system/sql/2.0.sql
Normal file
1
temp/Th5EMmj3vu/addons/pos_system/sql/2.0.sql
Normal file
@@ -0,0 +1 @@
|
||||
COMMIT;
|
||||
1
temp/Th5EMmj3vu/addons/pos_system/sql/2.1.sql
Normal file
1
temp/Th5EMmj3vu/addons/pos_system/sql/2.1.sql
Normal file
@@ -0,0 +1 @@
|
||||
COMMIT;
|
||||
1
temp/Th5EMmj3vu/addons/pos_system/sql/update.sql
Normal file
1
temp/Th5EMmj3vu/addons/pos_system/sql/update.sql
Normal file
@@ -0,0 +1 @@
|
||||
COMMIT;
|
||||
@@ -0,0 +1,79 @@
|
||||
<div class="aiz-pos-cart-list mb-4 mt-3 c-scrollbar-light">
|
||||
@php
|
||||
$subtotal = 0;
|
||||
$tax = 0;
|
||||
@endphp
|
||||
@if (Session::has('pos.cart'))
|
||||
<ul class="list-group list-group-flush">
|
||||
@forelse (Session::get('pos.cart') as $key => $cartItem)
|
||||
@php
|
||||
$subtotal += $cartItem['price']*$cartItem['quantity'];
|
||||
$tax += $cartItem['tax']*$cartItem['quantity'];
|
||||
$stock = \App\Models\ProductStock::find($cartItem['stock_id']);
|
||||
@endphp
|
||||
<li class="list-group-item py-0 pl-2">
|
||||
<div class="row gutters-5 align-items-center">
|
||||
<div class="col-auto w-60px">
|
||||
<div class="row no-gutters align-items-center flex-column aiz-plus-minus">
|
||||
<button class="btn col-auto btn-icon btn-sm fs-15" type="button" data-type="plus" data-field="qty-{{ $key }}">
|
||||
<i class="las la-plus"></i>
|
||||
</button>
|
||||
<input type="text" name="qty-{{ $key }}" id="qty-{{ $key }}" class="col border-0 text-center flex-grow-1 fs-16 input-number" placeholder="1" value="{{ $cartItem['quantity'] }}" min="{{ $stock->product->min_qty }}" max="{{ $stock->qty }}" onchange="updateQuantity({{ $key }})">
|
||||
<button class="btn col-auto btn-icon btn-sm fs-15" type="button" data-type="minus" data-field="qty-{{ $key }}">
|
||||
<i class="las la-minus"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="text-truncate-2">{{ $stock->product->name }}</div>
|
||||
<span class="span badge badge-inline fs-12 badge-soft-secondary">{{ $cartItem['variant'] }}</span>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="fs-12 opacity-60">{{ single_price($cartItem['price']) }} x {{ $cartItem['quantity'] }}</div>
|
||||
<div class="fs-15 fw-600">{{ single_price($cartItem['price']*$cartItem['quantity']) }}</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button type="button" class="btn btn-circle btn-icon btn-sm btn-soft-danger ml-2 mr-0" onclick="removeFromCart({{ $key }})">
|
||||
<i class="las la-trash-alt"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@empty
|
||||
<li class="list-group-item">
|
||||
<div class="text-center">
|
||||
<i class="las la-frown la-3x opacity-50"></i>
|
||||
<p>{{ translate('No Product Added') }}</p>
|
||||
</div>
|
||||
</li>
|
||||
@endforelse
|
||||
</ul>
|
||||
@else
|
||||
<div class="text-center">
|
||||
<i class="las la-frown la-3x opacity-50"></i>
|
||||
<p>{{ translate('No Product Added') }}</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
|
||||
<span>{{translate('Sub Total')}}</span>
|
||||
<span>{{ single_price($subtotal) }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
|
||||
<span>{{translate('Tax')}}</span>
|
||||
<span>{{ single_price($tax) }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
|
||||
<span>{{translate('Shipping')}}</span>
|
||||
<span>{{ single_price(Session::get('pos.shipping', 0)) }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
|
||||
<span>{{translate('Discount')}}</span>
|
||||
<span>{{ single_price(Session::get('pos.discount', 0)) }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between fw-600 fs-18 border-top pt-2">
|
||||
<span>{{translate('Total')}}</span>
|
||||
<span>{{ single_price($subtotal+$tax+Session::get('pos.shipping', 0) - Session::get('pos.discount', 0)) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,77 @@
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 control-label" for="name">{{translate('Name')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" placeholder="{{translate('Name')}}" id="name" name="name" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-2 control-label" for="email">{{translate('Email')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="email" placeholder="{{translate('Email')}}" id="email" name="email" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-2 control-label" for="address">{{translate('Address')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<textarea placeholder="{{translate('Address')}}" id="address" name="address" class="form-control" required></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-2 control-label">{{translate('Country')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<select class="form-control aiz-selectpicker" data-live-search="true" data-placeholder="{{ translate('Select your country') }}" name="country_id" required>
|
||||
<option value="">{{ translate('Select your country') }}</option>
|
||||
@foreach (\App\Models\Country::where('status', 1)->get() as $key => $country)
|
||||
<option value="{{ $country->id }}">{{ $country->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-sm-2 control-label"">
|
||||
<label>{{ translate('State')}}</label>
|
||||
</div>
|
||||
<div class="col-sm-10">
|
||||
<select class="form-control mb-3 aiz-selectpicker" data-live-search="true" name="state_id" required>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-sm-2">
|
||||
<label>{{ translate('City')}}</label>
|
||||
</div>
|
||||
<div class="col-sm-10">
|
||||
<select class="form-control mb-3 aiz-selectpicker" data-live-search="true" name="city_id" required>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-2 control-label" for="postal_code">{{translate('Postal code')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="number" min="0" placeholder="{{translate('Postal code')}}" id="postal_code" name="postal_code" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-2 control-label" for="phone">{{translate('Phone')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="number" min="0" placeholder="{{translate('Phone')}}" id="phone" name="phone" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,637 @@
|
||||
@extends('backend.layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
<section class="">
|
||||
<form class="" action="" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
<div class="row gutters-5">
|
||||
<div class="col-md">
|
||||
<div class="row gutters-5 mb-3">
|
||||
<div class="col-md-6 mb-2 mb-md-0">
|
||||
<div class="form-group mb-0">
|
||||
<input class="form-control form-control-lg" type="text" name="keyword" placeholder="{{ translate('Search by Product Name/Barcode') }}" onkeyup="filterProducts()">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 col-6">
|
||||
<select name="poscategory" class="form-control form-control-lg aiz-selectpicker" data-live-search="true" onchange="filterProducts()">
|
||||
<option value="">{{ translate('All Categories') }}</option>
|
||||
@foreach (\App\Models\Category::all() as $key => $category)
|
||||
<option value="category-{{ $category->id }}">{{ $category->getTranslation('name') }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3 col-6">
|
||||
<select name="brand" class="form-control form-control-lg aiz-selectpicker" data-live-search="true" onchange="filterProducts()">
|
||||
<option value="">{{ translate('All Brands') }}</option>
|
||||
@foreach (\App\Models\Brand::all() as $key => $brand)
|
||||
<option value="{{ $brand->id }}">{{ $brand->getTranslation('name') }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="aiz-pos-product-list c-scrollbar-light">
|
||||
<div class="d-flex flex-wrap justify-content-center" id="product-list">
|
||||
|
||||
</div>
|
||||
<div id="load-more" class="text-center">
|
||||
<div class="fs-14 d-inline-block fw-600 btn btn-soft-primary c-pointer" onclick="loadMoreProduct()">{{ translate('Loading..') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-auto w-md-350px w-lg-400px w-xl-500px">
|
||||
<div class="card mb-3">
|
||||
<div class="card-body">
|
||||
<div class="d-flex border-bottom pb-3">
|
||||
<div class="flex-grow-1">
|
||||
<select name="user_id" class="form-control aiz-selectpicker pos-customer" data-live-search="true" onchange="getShippingAddress()">
|
||||
<option value="">{{translate('Walk In Customer')}}</option>
|
||||
@foreach ($customers as $key => $customer)
|
||||
<option value="{{ $customer->id }}" data-contact="{{ $customer->email }}">
|
||||
{{ $customer->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<button type="button" class="btn btn-icon btn-soft-dark ml-3 mr-0" data-target="#new-customer" data-toggle="modal">
|
||||
<i class="las la-truck"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="" id="cart-details">
|
||||
<div class="aiz-pos-cart-list mb-4 mt-3 c-scrollbar-light">
|
||||
@php
|
||||
$subtotal = 0;
|
||||
$tax = 0;
|
||||
@endphp
|
||||
@if (Session::has('pos.cart'))
|
||||
<ul class="list-group list-group-flush">
|
||||
@forelse (Session::get('pos.cart') as $key => $cartItem)
|
||||
@php
|
||||
$subtotal += $cartItem['price']*$cartItem['quantity'];
|
||||
$tax += $cartItem['tax']*$cartItem['quantity'];
|
||||
$stock = \App\Models\ProductStock::find($cartItem['stock_id']);
|
||||
@endphp
|
||||
<li class="list-group-item py-0 pl-2">
|
||||
<div class="row gutters-5 align-items-center">
|
||||
<div class="col-auto w-60px">
|
||||
<div class="row no-gutters align-items-center flex-column aiz-plus-minus">
|
||||
<button class="btn col-auto btn-icon btn-sm fs-15" type="button" data-type="plus" data-field="qty-{{ $key }}" @if($stock->product->digital == 1) disabled @endif>
|
||||
<i class="las la-plus"></i>
|
||||
</button>
|
||||
<input type="text" name="qty-{{ $key }}" id="qty-{{ $key }}" class="col border-0 text-center flex-grow-1 fs-16 input-number" placeholder="1" value="{{ $cartItem['quantity'] }}" min="{{ $stock->product->min_qty }}" max="{{ $stock->qty }}" onchange="updateQuantity({{ $key }})">
|
||||
<button class="btn col-auto btn-icon btn-sm fs-15" type="button" data-type="minus" data-field="qty-{{ $key }}" @if($stock->product->digital == 1) disabled @endif>
|
||||
<i class="las la-minus"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="text-truncate-2">{{ $stock->product->name }}</div>
|
||||
<span class="span badge badge-inline fs-12 badge-soft-secondary">{{ $cartItem['variant'] }}</span>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="fs-12 opacity-60">{{ single_price($cartItem['price']) }} x {{ $cartItem['quantity'] }}</div>
|
||||
<div class="fs-15 fw-600">{{ single_price($cartItem['price']*$cartItem['quantity']) }}</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button type="button" class="btn btn-circle btn-icon btn-sm btn-soft-danger ml-2 mr-0" onclick="removeFromCart({{ $key }})">
|
||||
<i class="las la-trash-alt"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@empty
|
||||
<li class="list-group-item">
|
||||
<div class="text-center">
|
||||
<i class="las la-frown la-3x opacity-50"></i>
|
||||
<p>{{ translate('No Product Added') }}</p>
|
||||
</div>
|
||||
</li>
|
||||
@endforelse
|
||||
</ul>
|
||||
@else
|
||||
<div class="text-center">
|
||||
<i class="las la-frown la-3x opacity-50"></i>
|
||||
<p>{{ translate('No Product Added') }}</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
|
||||
<span>{{translate('Sub Total')}}</span>
|
||||
<span>{{ single_price($subtotal) }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
|
||||
<span>{{translate('Tax')}}</span>
|
||||
<span>{{ single_price($tax) }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
|
||||
<span>{{translate('Shipping')}}</span>
|
||||
<span>{{ single_price(Session::get('pos.shipping', 0)) }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
|
||||
<span>{{translate('Discount')}}</span>
|
||||
<span>{{ single_price(Session::get('pos.discount', 0)) }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between fw-600 fs-18 border-top pt-2">
|
||||
<span>{{translate('Total')}}</span>
|
||||
<span>{{ single_price($subtotal+$tax+Session::get('pos.shipping', 0) - Session::get('pos.discount', 0)) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pos-footer mar-btm">
|
||||
<div class="d-flex flex-column flex-md-row justify-content-between">
|
||||
<div class="d-flex">
|
||||
<div class="dropdown mr-3 ml-0 dropup">
|
||||
<button class="btn btn-outline-dark btn-styled dropdown-toggle" type="button" data-toggle="dropdown">
|
||||
{{translate('Shipping')}}
|
||||
</button>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-lg">
|
||||
<div class="input-group">
|
||||
<input type="number" min="0" placeholder="Amount" name="shipping" class="form-control" value="{{ Session::get('pos.shipping', 0) }}" required onchange="setShipping()">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">{{ translate('Flat') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown dropup">
|
||||
<button class="btn btn-outline-dark btn-styled dropdown-toggle" type="button" data-toggle="dropdown">
|
||||
{{translate('Discount')}}
|
||||
</button>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-lg">
|
||||
<div class="input-group">
|
||||
<input type="number" min="0" placeholder="Amount" name="discount" class="form-control" value="{{ Session::get('pos.discount', 0) }}" required onchange="setDiscount()">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">{{ translate('Flat') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-2 my-md-0">
|
||||
<button type="button" class="btn btn-primary btn-block" onclick="orderConfirmation()">{{ translate('Place Order') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
@endsection
|
||||
|
||||
@section('modal')
|
||||
<!-- Address Modal -->
|
||||
<div id="new-customer" class="modal fade" role="dialog">
|
||||
<div class="modal-dialog modal-dialog-centered modal-dialog-zoom" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bord-btm">
|
||||
<h4 class="modal-title h6">{{translate('Shipping Address')}}</h4>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span></button>
|
||||
</div>
|
||||
<form id="shipping_form">
|
||||
<div class="modal-body" id="shipping_address">
|
||||
|
||||
|
||||
</div>
|
||||
</form>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-styled btn-base-3" data-dismiss="modal" id="close-button">{{translate('Close')}}</button>
|
||||
<button type="button" class="btn btn-primary btn-styled btn-base-1" id="confirm-address" data-dismiss="modal">{{translate('Confirm')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- new address modal -->
|
||||
<div id="new-address-modal" class="modal fade" role="dialog">
|
||||
<div class="modal-dialog modal-dialog-centered modal-dialog-zoom" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bord-btm">
|
||||
<h4 class="modal-title h6">{{translate('Shipping Address')}}</h4>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span></button>
|
||||
</div>
|
||||
<form class="form-horizontal" action="{{ route('addresses.store') }}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
<div class="modal-body">
|
||||
<input type="hidden" name="customer_id" id="set_customer_id" value="">
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-2 control-label" for="address">{{translate('Address')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<textarea placeholder="{{translate('Address')}}" id="address" name="address" class="form-control" required></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-2 control-label">{{translate('Country')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<select class="form-control aiz-selectpicker" data-live-search="true" data-placeholder="{{ translate('Select your country') }}" name="country_id" required>
|
||||
<option value="">{{ translate('Select your country') }}</option>
|
||||
@foreach (\App\Models\Country::where('status', 1)->get() as $key => $country)
|
||||
<option value="{{ $country->id }}">{{ $country->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-sm-2 control-label"">
|
||||
<label>{{ translate('State')}}</label>
|
||||
</div>
|
||||
<div class="col-sm-10">
|
||||
<select class="form-control mb-3 aiz-selectpicker" data-live-search="true" name="state_id" required>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-sm-2">
|
||||
<label>{{ translate('City')}}</label>
|
||||
</div>
|
||||
<div class="col-sm-10">
|
||||
<select class="form-control mb-3 aiz-selectpicker" data-live-search="true" name="city_id" required>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-2 control-label" for="postal_code">{{translate('Postal code')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="number" min="0" placeholder="{{translate('Postal code')}}" id="postal_code" name="postal_code" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-2 control-label" for="phone">{{translate('Phone')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="number" min="0" placeholder="{{translate('Phone')}}" id="phone" name="phone" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-styled btn-base-3" data-dismiss="modal">{{translate('Close')}}</button>
|
||||
<button type="submit" class="btn btn-primary btn-styled btn-base-1">{{translate('Save')}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="order-confirm" class="modal fade">
|
||||
<div class="modal-dialog modal-dialog-centered modal-dialog-zoom modal-xl">
|
||||
<div class="modal-content" id="variants">
|
||||
<div class="modal-header bord-btm">
|
||||
<h4 class="modal-title h6">{{translate('Order Summary')}}</h4>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span></button>
|
||||
</div>
|
||||
<div class="modal-body" id="order-confirmation">
|
||||
<div class="p-4 text-center">
|
||||
<i class="las la-spinner la-spin la-3x"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary btn-base-3" data-dismiss="modal">{{translate('Close')}}</button>
|
||||
<button type="button" onclick="oflinePayment()" class="btn btn-base-1 btn-warning">{{translate('Offline Payment')}}</button>
|
||||
<button type="button" onclick="submitOrder('cash_on_delivery')" class="btn btn-base-1 btn-info">{{translate('Confirm with COD')}}</button>
|
||||
<button type="button" onclick="submitOrder('cash')" class="btn btn-base-1 btn-success">{{translate('Confirm with Cash')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Offline Payment Modal --}}
|
||||
<div id="offlin_payment" class="modal fade" role="dialog">
|
||||
<div class="modal-dialog modal-dialog-centered modal-dialog-zoom" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bord-btm">
|
||||
<h4 class="modal-title h6">{{translate('Offline Payment Info')}}</h4>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-3 control-label" for="offline_payment_method">{{translate('Payment Method')}}</label>
|
||||
<div class="col-sm-9">
|
||||
<input placeholder="{{translate('Name')}}" id="offline_payment_method" name="offline_payment_method" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-3 control-label" for="offline_payment_amount">{{translate('Amount')}}</label>
|
||||
<div class="col-sm-9">
|
||||
<input placeholder="{{translate('Amount')}}" id="offline_payment_amount" name="offline_payment_amount" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-sm-3 control-label" for="trx_id">{{translate('Transaction ID')}}</label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control mb-3" id="trx_id" name="trx_id" placeholder="{{ translate('Transaction ID') }}" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 col-form-label">{{ translate('Payment Proof') }}</label>
|
||||
<div class="col-md-9">
|
||||
<div class="input-group" data-toggle="aizuploader" data-type="image">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text bg-soft-secondary font-weight-medium">{{ translate('Browse')}}</div>
|
||||
</div>
|
||||
<div class="form-control file-amount">{{ translate('Choose image') }}</div>
|
||||
<input type="hidden" name="payment_proof" class="selected-files">
|
||||
</div>
|
||||
<div class="file-preview box sm">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary btn-base-3" data-dismiss="modal">{{translate('Close')}}</button>
|
||||
<button type="button" onclick="submitOrder('offline_payment')" class="btn btn-styled btn-base-1 btn-success">{{translate('Confirm')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
|
||||
@section('script')
|
||||
<script type="text/javascript">
|
||||
|
||||
var products = null;
|
||||
|
||||
$(document).ready(function(){
|
||||
$('body').addClass('side-menu-closed');
|
||||
$('#product-list').on('click','.add-plus:not(.c-not-allowed)',function(){
|
||||
var stock_id = $(this).data('stock-id');
|
||||
$.post('{{ route('pos.addToCart') }}',{_token:AIZ.data.csrf, stock_id:stock_id}, function(data){
|
||||
if(data.success == 1){
|
||||
updateCart(data.view);
|
||||
}else{
|
||||
AIZ.plugins.notify('danger', data.message);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
filterProducts();
|
||||
getShippingAddress();
|
||||
});
|
||||
|
||||
$("#confirm-address").click(function (){
|
||||
var data = new FormData($('#shipping_form')[0]);
|
||||
|
||||
$.ajax({
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': AIZ.data.csrf
|
||||
},
|
||||
method: "POST",
|
||||
url: "{{route('pos.set-shipping-address')}}",
|
||||
data: data,
|
||||
cache: false,
|
||||
contentType: false,
|
||||
processData: false,
|
||||
success: function (data, textStatus, jqXHR) {
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
function updateCart(data){
|
||||
$('#cart-details').html(data);
|
||||
AIZ.extra.plusMinus();
|
||||
}
|
||||
|
||||
function filterProducts(){
|
||||
var keyword = $('input[name=keyword]').val();
|
||||
var category = $('select[name=poscategory]').val();
|
||||
var brand = $('select[name=brand]').val();
|
||||
$.get('{{ route('pos.search_product') }}',{keyword:keyword, category:category, brand:brand}, function(data){
|
||||
products = data;
|
||||
$('#product-list').html(null);
|
||||
setProductList(data);
|
||||
});
|
||||
}
|
||||
|
||||
function loadMoreProduct(){
|
||||
if(products != null && products.links.next != null){
|
||||
$('#load-more').find('.btn').html('{{ translate('Loading..') }}');
|
||||
$.get(products.links.next,{}, function(data){
|
||||
products = data;
|
||||
setProductList(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function setProductList(data){
|
||||
for (var i = 0; i < data.data.length; i++) {
|
||||
|
||||
$('#product-list').append(
|
||||
`<div class="w-140px w-xl-180px w-xxl-210px mx-2">
|
||||
<div class="card bg-white c-pointer product-card hov-container">
|
||||
<div class="position-relative">
|
||||
${data.data[i].digital == 0
|
||||
?
|
||||
`<span class="absolute-top-left mt-1 ml-1 mr-0">
|
||||
${data.data[i].qty > 0
|
||||
? `<span class="badge badge-inline badge-success fs-13">{{ translate('In stock') }}`
|
||||
: `<span class="badge badge-inline badge-danger fs-13">{{ translate('Out of stock') }}` }
|
||||
: ${data.data[i].qty}</span>
|
||||
</span>`
|
||||
: ''
|
||||
}
|
||||
${data.data[i].variant != null
|
||||
? `<span class="badge badge-inline badge-warning absolute-bottom-left mb-1 ml-1 mr-0 fs-13 text-truncate">${data.data[i].variant}</span>`
|
||||
: '' }
|
||||
<img src="${data.data[i].thumbnail_image }" class="card-img-top img-fit h-120px h-xl-180px h-xxl-210px mw-100 mx-auto" >
|
||||
</div>
|
||||
<div class="card-body p-2 p-xl-3">
|
||||
<div class="text-truncate fw-600 fs-14 mb-2">${data.data[i].name}</div>
|
||||
<div class="">
|
||||
${data.data[i].price != data.data[i].base_price
|
||||
? `<del class="mr-2 ml-0">${data.data[i].base_price}</del><span>${data.data[i].price}</span>`
|
||||
: `<span>${data.data[i].base_price}</span>`
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="add-plus absolute-full rounded overflow-hidden hov-box ${(data.data[i].digital == 0 && data.data[i].qty <= 0) ? 'c-not-allowed' : '' }" data-stock-id="${data.data[i].stock_id}">
|
||||
<div class="absolute-full bg-dark opacity-50">
|
||||
</div>
|
||||
<i class="las la-plus absolute-center la-6x text-white"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
);
|
||||
}
|
||||
if (data.links.next != null) {
|
||||
$('#load-more').find('.btn').html('{{ translate('Load More.') }}');
|
||||
}
|
||||
else {
|
||||
$('#load-more').find('.btn').html('{{ translate('Nothing more found.') }}');
|
||||
}
|
||||
}
|
||||
|
||||
function removeFromCart(key){
|
||||
$.post('{{ route('pos.removeFromCart') }}', {_token:AIZ.data.csrf, key:key}, function(data){
|
||||
updateCart(data);
|
||||
});
|
||||
}
|
||||
|
||||
function addToCart(product_id, variant, quantity){
|
||||
$.post('{{ route('pos.addToCart') }}',{_token:AIZ.data.csrf, product_id:product_id, variant:variant, quantity, quantity}, function(data){
|
||||
$('#cart-details').html(data);
|
||||
$('#product-variation').modal('hide');
|
||||
});
|
||||
}
|
||||
|
||||
function updateQuantity(key){
|
||||
$.post('{{ route('pos.updateQuantity') }}',{_token:AIZ.data.csrf, key:key, quantity: $('#qty-'+key).val()}, function(data){
|
||||
if(data.success == 1){
|
||||
updateCart(data.view);
|
||||
}else{
|
||||
AIZ.plugins.notify('danger', data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function setDiscount(){
|
||||
var discount = $('input[name=discount]').val();
|
||||
$.post('{{ route('pos.setDiscount') }}',{_token:AIZ.data.csrf, discount:discount}, function(data){
|
||||
updateCart(data);
|
||||
});
|
||||
}
|
||||
|
||||
function setShipping(){
|
||||
var shipping = $('input[name=shipping]').val();
|
||||
$.post('{{ route('pos.setShipping') }}',{_token:AIZ.data.csrf, shipping:shipping}, function(data){
|
||||
updateCart(data);
|
||||
});
|
||||
}
|
||||
|
||||
function getShippingAddress(){
|
||||
$.post('{{ route('pos.getShippingAddress') }}',{_token:AIZ.data.csrf, id:$('select[name=user_id]').val()}, function(data){
|
||||
$('#shipping_address').html(data);
|
||||
});
|
||||
}
|
||||
|
||||
function add_new_address(){
|
||||
var customer_id = $('#customer_id').val();
|
||||
$('#set_customer_id').val(customer_id);
|
||||
$('#new-address-modal').modal('show');
|
||||
$("#close-button").click();
|
||||
}
|
||||
|
||||
function orderConfirmation(){
|
||||
$('#order-confirmation').html(`<div class="p-4 text-center"><i class="las la-spinner la-spin la-3x"></i></div>`);
|
||||
$('#order-confirm').modal('show');
|
||||
$.post('{{ route('pos.getOrderSummary') }}',{_token:AIZ.data.csrf}, function(data){
|
||||
$('#order-confirmation').html(data);
|
||||
});
|
||||
}
|
||||
|
||||
function oflinePayment(){
|
||||
$('#offlin_payment').modal('show');
|
||||
}
|
||||
|
||||
function submitOrder(payment_type){
|
||||
var user_id = $('select[name=user_id]').val();
|
||||
var shipping = $('input[name=shipping]:checked').val();
|
||||
var discount = $('input[name=discount]').val();
|
||||
var shipping_address = $('input[name=address_id]:checked').val();
|
||||
var offline_payment_method = $('input[name=offline_payment_method]').val();
|
||||
var offline_payment_amount = $('input[name=offline_payment_amount]').val();
|
||||
var offline_trx_id = $('input[name=trx_id]').val();
|
||||
var offline_payment_proof = $('input[name=payment_proof]').val();
|
||||
|
||||
$.post('{{ route('pos.order_place') }}',{
|
||||
_token : AIZ.data.csrf,
|
||||
user_id : user_id,
|
||||
shipping_address : shipping_address,
|
||||
payment_type : payment_type,
|
||||
shipping : shipping,
|
||||
discount : discount,
|
||||
offline_payment_method : offline_payment_method,
|
||||
offline_payment_amount : offline_payment_amount,
|
||||
offline_trx_id : offline_trx_id,
|
||||
offline_payment_proof : offline_payment_proof
|
||||
|
||||
}, function(data){
|
||||
if(data.success == 1){
|
||||
AIZ.plugins.notify('success', data.message );
|
||||
location.reload();
|
||||
}
|
||||
else{
|
||||
AIZ.plugins.notify('danger', data.message );
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//address
|
||||
$(document).on('change', '[name=country_id]', function() {
|
||||
var country_id = $(this).val();
|
||||
get_states(country_id);
|
||||
});
|
||||
|
||||
$(document).on('change', '[name=state_id]', function() {
|
||||
var state_id = $(this).val();
|
||||
get_city(state_id);
|
||||
});
|
||||
|
||||
function get_states(country_id) {
|
||||
$('[name="state"]').html("");
|
||||
$.ajax({
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
||||
},
|
||||
url: "{{route('get-state')}}",
|
||||
type: 'POST',
|
||||
data: {
|
||||
country_id : country_id
|
||||
},
|
||||
success: function (response) {
|
||||
var obj = JSON.parse(response);
|
||||
if(obj != '') {
|
||||
$('[name="state_id"]').html(obj);
|
||||
AIZ.plugins.bootstrapSelect('refresh');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function get_city(state_id) {
|
||||
$('[name="city"]').html("");
|
||||
$.ajax({
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
||||
},
|
||||
url: "{{route('get-city')}}",
|
||||
type: 'POST',
|
||||
data: {
|
||||
state_id: state_id
|
||||
},
|
||||
success: function (response) {
|
||||
var obj = JSON.parse(response);
|
||||
if(obj != '') {
|
||||
$('[name="city_id"]').html(obj);
|
||||
AIZ.plugins.bootstrapSelect('refresh');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@endsection
|
||||
@@ -0,0 +1,116 @@
|
||||
<div class="row">
|
||||
<div class="col-xl-6">
|
||||
@php
|
||||
$subtotal = 0;
|
||||
$tax = 0;
|
||||
@endphp
|
||||
@if (Session::has('pos.cart'))
|
||||
<ul class="list-group list-group-flush">
|
||||
@forelse (Session::get('pos.cart') as $key => $cartItem)
|
||||
@php
|
||||
$subtotal += $cartItem['price']*$cartItem['quantity'];
|
||||
$tax += $cartItem['tax']*$cartItem['quantity'];
|
||||
$stock = \App\Models\ProductStock::find($cartItem['stock_id']);
|
||||
@endphp
|
||||
<li class="list-group-item px-0">
|
||||
<div class="row gutters-10 align-items-center">
|
||||
<div class="col">
|
||||
<div class="d-flex">
|
||||
@if($stock->image == null)
|
||||
<img src="{{ uploaded_asset($stock->product->thumbnail_img) }}" class="img-fit size-60px">
|
||||
@else
|
||||
<img src="{{ uploaded_asset($stock->image) }}" class="img-fit size-60px">
|
||||
@endif
|
||||
<span class="flex-grow-1 ml-3 mr-0">
|
||||
<div class="text-truncate-2">{{ $stock->product->name }}</div>
|
||||
<span class="span badge badge-inline fs-12 badge-soft-secondary">{{ $cartItem['variant'] }}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3">
|
||||
<div class="fs-14 fw-600 text-right">{{ single_price($cartItem['price']) }}</div>
|
||||
<div class="fs-14 text-right">{{ translate('QTY') }}: {{ $cartItem['quantity'] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@empty
|
||||
<li class="list-group-item">
|
||||
<div class="text-center">
|
||||
<i class="las la-frown la-3x opacity-50"></i>
|
||||
<p>{{ translate('No Product Added') }}</p>
|
||||
</div>
|
||||
</li>
|
||||
@endforelse
|
||||
</ul>
|
||||
@else
|
||||
<div class="text-center">
|
||||
<i class="las la-frown la-3x opacity-50"></i>
|
||||
<p>{{ translate('No Product Added') }}</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="col-xl-6">
|
||||
<div class="pl-xl-4">
|
||||
<div class="card mb-4">
|
||||
<div class="card-header"><span class="fs-16">{{ translate('Customer Info') }}</span></div>
|
||||
<div class="card-body">
|
||||
@if(Session::has('pos.shipping_info') && Session::get('pos.shipping_info')['name'] != null)
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span class="">{{translate('Name')}}:</span>
|
||||
<span class="fw-600">{{ Session::get('pos.shipping_info')['name'] }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span class="">{{translate('Email')}}:</span>
|
||||
<span class="fw-600">{{ Session::get('pos.shipping_info')['email'] }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span class="">{{translate('Phone')}}:</span>
|
||||
<span class="fw-600">{{ Session::get('pos.shipping_info')['phone'] }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span class="">{{translate('Address')}}:</span>
|
||||
<span class="fw-600">{{ Session::get('pos.shipping_info')['address'] }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span class="">{{translate('Country')}}:</span>
|
||||
<span class="fw-600">{{ Session::get('pos.shipping_info')['country'] }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span class="">{{translate('City')}}:</span>
|
||||
<span class="fw-600">{{ Session::get('pos.shipping_info')['city'] }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span class="">{{translate('Postal Code')}}:</span>
|
||||
<span class="fw-600">{{ Session::get('pos.shipping_info')['postal_code'] }}</span>
|
||||
</div>
|
||||
@else
|
||||
<div class="text-center p-4">
|
||||
{{ translate('No customer information selected.') }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
|
||||
<span>{{translate('Total')}}</span>
|
||||
<span>{{ single_price($subtotal) }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
|
||||
<span>{{translate('Tax')}}</span>
|
||||
<span>{{ single_price($tax) }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
|
||||
<span>{{translate('Shipping')}}</span>
|
||||
<span>{{ single_price(Session::get('pos.shipping', 0)) }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
|
||||
<span>{{translate('Discount')}}</span>
|
||||
<span>{{ single_price(Session::get('pos.discount', 0)) }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between fw-600 fs-18 border-top pt-2">
|
||||
<span>{{translate('Total')}}</span>
|
||||
<span>{{ single_price($subtotal+$tax+Session::get('pos.shipping', 0) - Session::get('pos.discount', 0)) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,68 @@
|
||||
@extends('backend.layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
<h4 class="text-center text-muted">{{translate('POS Activation for Seller')}}</h4>
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0 h6">{{translate('POS Activation for Seller')}}</h5>
|
||||
</div>
|
||||
<div class="card-body text-center">
|
||||
<label class="aiz-switch aiz-switch-success mb-0">
|
||||
<input type="checkbox" onchange="updateSettings(this, 'pos_activation_for_seller')" @if(get_setting('pos_activation_for_seller') == 1) checked @endif>
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0 h6">{{ translate('Thermal Printer Size') }}</h5>
|
||||
</div>
|
||||
<div class="card-body text-center">
|
||||
<form class="form-horizontal" action="{{ route('business_settings.update') }}" method="POST">
|
||||
@csrf
|
||||
<div class="form-group row">
|
||||
<input type="hidden" name="types[]" value="print_width">
|
||||
<div class="input-group mb-3">
|
||||
<input type="text" class="form-control" name="print_width" placeholder="{{ translate('Print width in mm') }}"
|
||||
value="{{ get_setting('print_width') }}">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text" id="basic-addon2">{{ translate('mm') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group mb-0 text-right">
|
||||
<button type="submit" class="btn btn-sm btn-primary">{{ translate('Save') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@section('script')
|
||||
<script type="text/javascript">
|
||||
function updateSettings(el, type){
|
||||
if($(el).is(':checked')){
|
||||
var value = 1;
|
||||
}
|
||||
else{
|
||||
var value = 0;
|
||||
}
|
||||
$.post('{{ route('business_settings.update.activation') }}', {_token:'{{ csrf_token() }}', type:type, value:value}, function(data){
|
||||
if(data == '1'){
|
||||
AIZ.plugins.notify('success', '{{ translate('Settings updated successfully') }}');
|
||||
}
|
||||
else{
|
||||
AIZ.plugins.notify('danger', '{{ translate('Something went wrong') }}');
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@endsection
|
||||
@@ -0,0 +1,43 @@
|
||||
<div class="">
|
||||
@foreach (\App\Models\Address::where('user_id',$user_id)->get() as $key => $address)
|
||||
<label class="aiz-megabox d-block bg-white" style="display:block">
|
||||
<input type="radio" name="address_id" value="{{ $address->id }}" @if ($address->set_default) checked @endif required>
|
||||
<span class="d-flex p-3 pad-all aiz-megabox-elem">
|
||||
<span class="aiz-rounded-check flex-shrink-0 mt-1"></span>
|
||||
<span class="flex-grow-1 pl-3 pad-lft">
|
||||
<div>
|
||||
<span class="alpha-6">{{ translate('Address') }}:</span>
|
||||
<span class="strong-600 ml-2">{{ $address->address }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="alpha-6">{{ translate('Postal Code') }}:</span>
|
||||
<span class="strong-600 ml-2">{{ $address->postal_code }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="alpha-6">{{ translate('City') }}:</span>
|
||||
<span class="strong-600 ml-2">{{ $address->city->name }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="alpha-6">{{ translate('State') }}:</span>
|
||||
<span class="strong-600 ml-2">{{ $address->state->name }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="alpha-6">{{ translate('Country') }}:</span>
|
||||
<span class="strong-600 ml-2">{{ $address->country->name }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="alpha-6">{{ translate('Phone') }}:</span>
|
||||
<span class="strong-600 ml-2">{{ $address->phone }}</span>
|
||||
</div>
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
@endforeach
|
||||
<input type="hidden" id="customer_id" value="{{$user_id}}" >
|
||||
<div class="" onclick="add_new_address()">
|
||||
<div class="border p-3 rounded mb-3 bord-all pad-all c-pointer text-center bg-white">
|
||||
<i class="fa fa-plus fa-2x"></i>
|
||||
<div class="alpha-7">{{ translate('Add New Address') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,184 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{{ translate('INVOICE') }}</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<meta charset="UTF-8">
|
||||
<style media="all">
|
||||
@page {
|
||||
margin: 0;
|
||||
padding:0;
|
||||
}
|
||||
body{
|
||||
font-size: 0.75rem;
|
||||
font-family: "<?php echo $pdf_style_data['font_family'] ?>";
|
||||
font-weight: normal;
|
||||
direction: <?php echo $pdf_style_data['direction'] ?>;
|
||||
text-align: <?php echo $pdf_style_data['text_align'] ?>;
|
||||
padding:0;
|
||||
margin:0;
|
||||
}
|
||||
.gry-color *,
|
||||
.gry-color{
|
||||
color:#000;
|
||||
}
|
||||
table{
|
||||
width: 100%;
|
||||
}
|
||||
table th{
|
||||
font-weight: normal;
|
||||
}
|
||||
table.padding th{
|
||||
padding: .25rem .7rem;
|
||||
}
|
||||
table.padding td{
|
||||
padding: .25rem .7rem;
|
||||
}
|
||||
table.sm-padding td{
|
||||
padding: .1rem .7rem;
|
||||
}
|
||||
.border-bottom td,
|
||||
.border-bottom th{
|
||||
border-bottom:1px solid #e8e8f5;
|
||||
}
|
||||
.text-left{
|
||||
text-align:<?php echo $pdf_style_data['text_align'] ?>;
|
||||
}
|
||||
.text-right{
|
||||
text-align:<?php echo $pdf_style_data['not_text_align'] ?>;
|
||||
}
|
||||
.line-separator {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
border-top: 1px dotted #9c9ca1;
|
||||
margin: 10px 0 0;
|
||||
}
|
||||
.line-separator .line-separator-text {
|
||||
background-color:#fff !important;
|
||||
margin-top: -6px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
z-index: 1;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
|
||||
@php
|
||||
$logo = get_setting('header_logo');
|
||||
@endphp
|
||||
|
||||
<div style="padding: 1rem;padding-bottom: 0">
|
||||
<div style="text-align: center;padding: 0.25rem;">
|
||||
@if($logo != null)
|
||||
<img src="{{ uploaded_asset($logo) }}" height="20">
|
||||
@else
|
||||
<img src="{{ static_asset('assets/img/logo.png') }}" height="20">
|
||||
@endif
|
||||
</div>
|
||||
<div style="text-align: center;">
|
||||
<span style="font-size: 1.5rem;">{{ get_setting('site_name') }}</span><br>
|
||||
<span>{{ get_setting('contact_address') }}</span><br>
|
||||
<span>{{ translate('Email') }}: {{ get_setting('contact_email') }}</span><br>
|
||||
<span>{{ translate('Phone') }}: {{ get_setting('contact_phone') }}</span><br>
|
||||
</div>
|
||||
<div class="line-separator"><div class="line-separator-text" style="width: 70px;">{{ translate('RETAIL INVOICE') }}</div></div>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
{{ translate('Order ID') }}: <span class="strong">{{ $order->code }}</span>
|
||||
</td>
|
||||
<td style="font-size: 1rem;" class="text-right strong">{{ translate('Date') }}: <span class="strong">{{ date('d M Y h:i:sa', $order->date) }}</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{{ translate('Payment method') }}: <span class="strong">{{ translate(ucfirst(str_replace('_', ' ', $order->payment_type))) }}</span>
|
||||
</td>
|
||||
<td style="font-size: 1rem;" class="text-right strong"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div style="padding: 0 1rem;">
|
||||
<div style="border-bottom:1px dotted #9c9ca1;padding-bottom: 0.25rem;">
|
||||
<div class="line-separator"><div class="line-separator-text" style="width: 40px;">{{ translate('BILL TO') }}</div></div>
|
||||
<table>
|
||||
@php
|
||||
$shipping_address = json_decode($order->shipping_address);
|
||||
@endphp
|
||||
<tr><td class="strong">{{ translate('Name') }}: {{ $shipping_address->name }}</small></td></tr>
|
||||
<tr><td class="gry-color small">{{ translate('Address') }}: {{ $shipping_address->address }}, {{ $shipping_address->city }}, @if(isset(json_decode($order->shipping_address)->state)) {{ json_decode($order->shipping_address)->state }} - @endif {{ $shipping_address->postal_code }}, {{ $shipping_address->country }}</small></td></tr>
|
||||
<tr><td class="gry-color small">{{ translate('Email') }}: {{ $shipping_address->email }}</small></td></tr>
|
||||
<tr><td class="gry-color small">{{ translate('Phone') }}: {{ $shipping_address->phone }}</small></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="padding: 1rem;">
|
||||
<table class="text-left small border-bottom">
|
||||
<thead>
|
||||
<tr class="gry-color" style="">
|
||||
<th width="35%" class="text-left" style="padding-left: 0">{{ translate('Product Name') }}</th>
|
||||
<th width="10%" class="text-left">{{ translate('Qty') }}</th>
|
||||
<th width="20%" class="text-left">{{ translate('Unit Price') }}</th>
|
||||
<th width="15%" class="text-left">{{ translate('Tax') }}</th>
|
||||
<th width="20%" class="text-right" style="padding-right: 0">{{ translate('Total') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="strong">
|
||||
@foreach ($order->orderDetails as $key => $orderDetail)
|
||||
@if ($orderDetail->product != null)
|
||||
<tr class="">
|
||||
<td style="padding-left: 0">
|
||||
{{ $orderDetail->product->name }}
|
||||
@if($orderDetail->variation != null) ({{ $orderDetail->variation }}) @endif
|
||||
<br>
|
||||
|
||||
@php
|
||||
$product_stock = json_decode($orderDetail->product->stocks->first(), true);
|
||||
@endphp
|
||||
{{translate('SKU')}}: {{ $product_stock['sku'] }}
|
||||
</small>
|
||||
</td>
|
||||
<td class="">{{ $orderDetail->quantity }}</td>
|
||||
<td class="currency">{{ single_price($orderDetail->price/$orderDetail->quantity) }}</td>
|
||||
<td class="currency">{{ single_price($orderDetail->tax/$orderDetail->quantity) }}</td>
|
||||
<td class="text-right currency" style="padding-right: 0">{{ single_price($orderDetail->price+$orderDetail->tax) }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div style="padding:1rem;">
|
||||
<table class="text-right sm-padding small strong">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th class="gry-color text-left">{{ translate('Sub Total') }}</th>
|
||||
<td class="currency" style="padding-right: 0">{{ single_price($order->orderDetails->sum('price')) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="gry-color text-left">{{ translate('Shipping Cost') }}</th>
|
||||
<td class="currency" style="padding-right: 0">{{ single_price($order->orderDetails->sum('shipping_cost')) }}</td>
|
||||
</tr>
|
||||
<tr class="border-bottom">
|
||||
<th class="gry-color text-left">{{ translate('Total Tax') }}</th>
|
||||
<td class="currency" style="padding-right: 0">{{ single_price($order->orderDetails->sum('tax')) }}</td>
|
||||
</tr>
|
||||
<tr class="border-bottom">
|
||||
<th class="gry-color text-left">{{ translate('Coupon Discount') }}</th>
|
||||
<td class="currency" style="padding-right: 0">{{ single_price($order->coupon_discount) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="text-left strong">{{ translate('Grand Total') }}</th>
|
||||
<td class="currency" style="padding-right: 0">{{ single_price($order->grand_total) }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,35 @@
|
||||
<div class="modal-header bord-btm">
|
||||
<h4 class="modal-title h6">{{ translate('Select variation') }} - {{ $stocks->first()->product->getTranslation('name') }}</h4>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row gutters-5">
|
||||
@foreach ($stocks as $key => $stock)
|
||||
<div class="col-lg-3 col-sm-6">
|
||||
<label class="aiz-megabox d-block">
|
||||
<input type="radio" name="variant" value="{{ $stock->variant }}" @if ($stock->qty <= 0)
|
||||
disabled
|
||||
@endif>
|
||||
<span class="d-flex p-2 pad-all aiz-megabox-elem">
|
||||
<span class="aiz-rounded-check flex-shrink-0 @if ($stock->qty > 0)
|
||||
mt-1
|
||||
@endif"></span>
|
||||
<span class="flex-grow-1 pad-lft pl-2">
|
||||
<span class="d-block strong-600">{{ $stock->variant }}</span>
|
||||
<span class="d-block">Price: {{ single_price($stock->price) }}</span>
|
||||
<span class="badge badge-inline @if ($stock->qty <= 0)
|
||||
badge-secondary
|
||||
@else
|
||||
badge-success
|
||||
@endif">Stock: {{ $stock->qty }}</span>
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-styled btn-base-3" data-dismiss="modal">Close</button>
|
||||
<button type="button" onclick="addVariantProductToCart({{ $stocks->first()->product->id }})" class="btn btn-primary btn-styled btn-base-1">Add Product</button>
|
||||
</div>
|
||||
@@ -0,0 +1,77 @@
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<label class="col-sm-2 control-label" for="name">{{translate('Name')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" placeholder="{{translate('Name')}}" id="name" name="name" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-2 control-label" for="email">{{translate('Email')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="email" placeholder="{{translate('Email')}}" id="email" name="email" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-2 control-label" for="address">{{translate('Address')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<textarea placeholder="{{translate('Address')}}" id="address" name="address" class="form-control" required></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-2 control-label">{{translate('Country')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<select class="form-control aiz-selectpicker" data-live-search="true" data-placeholder="{{ translate('Select your country') }}" name="country_id" required>
|
||||
<option value="">{{ translate('Select your country') }}</option>
|
||||
@foreach (\App\Models\Country::where('status', 1)->get() as $key => $country)
|
||||
<option value="{{ $country->id }}">{{ $country->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-sm-2 control-label"">
|
||||
<label>{{ translate('State')}}</label>
|
||||
</div>
|
||||
<div class="col-sm-10">
|
||||
<select class="form-control mb-3 aiz-selectpicker" data-live-search="true" name="state_id" required>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-sm-2">
|
||||
<label>{{ translate('City')}}</label>
|
||||
</div>
|
||||
<div class="col-sm-10">
|
||||
<select class="form-control mb-3 aiz-selectpicker" data-live-search="true" name="city_id" required>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-2 control-label" for="postal_code">{{translate('Postal code')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="number" min="0" placeholder="{{translate('Postal code')}}" id="postal_code" name="postal_code" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-2 control-label" for="phone">{{translate('Phone')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="number" min="0" placeholder="{{translate('Phone')}}" id="phone" name="phone" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,639 @@
|
||||
@extends('seller.layouts.app')
|
||||
|
||||
@section('panel_content')
|
||||
|
||||
<section class="gry-bg py-4 profile">
|
||||
<div class="container-fluid">
|
||||
<form class="" action="" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
<div class="row gutters-10">
|
||||
<div class="col-md">
|
||||
<div class="row gutters-5 mb-3">
|
||||
<div class="col-md-6 mb-2 mb-md-0">
|
||||
<div class="form-group mb-0">
|
||||
<input class="form-control form-control-lg" type="text" name="keyword" placeholder="Search by Product Name/Barcode" onkeyup="filterProducts()">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 col-6">
|
||||
<select name="poscategory" class="form-control form-control-lg aiz-selectpicker" data-live-search="true" onchange="filterProducts()">
|
||||
<option value="">{{ translate('All Categories') }}</option>
|
||||
@foreach (\App\Models\Category::all() as $key => $category)
|
||||
<option value="category-{{ $category->id }}">{{ $category->getTranslation('name') }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3 col-6">
|
||||
<select name="brand" class="form-control form-control-lg aiz-selectpicker" data-live-search="true" onchange="filterProducts()">
|
||||
<option value="">{{ translate('All Brands') }}</option>
|
||||
@foreach (\App\Models\Brand::all() as $key => $brand)
|
||||
<option value="{{ $brand->id }}">{{ $brand->getTranslation('name') }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="aiz-pos-product-list c-scrollbar-light">
|
||||
<div class="d-flex flex-wrap justify-content-center" id="product-list">
|
||||
|
||||
</div>
|
||||
<div id="load-more" class="text-center">
|
||||
<div class="fs-14 d-inline-block fw-600 btn btn-soft-primary c-pointer" onclick="loadMoreProduct()">{{ translate('Loading..') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-auto w-md-350px w-lg-400px w-xl-500px">
|
||||
<div class="card mb-3">
|
||||
<div class="card-body">
|
||||
<div class="d-flex border-bottom pb-3">
|
||||
<div class="flex-grow-1">
|
||||
<select name="user_id" class="form-control aiz-selectpicker pos-customer" data-live-search="true" onchange="getShippingAddress()">
|
||||
<option value="">{{translate('Walk In Customer')}}</option>
|
||||
@foreach ($customers as $key => $customer)
|
||||
<option value="{{ $customer->id }}" data-contact="{{ $customer->email }}">
|
||||
{{ $customer->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<button type="button" class="btn btn-icon btn-soft-dark ml-3 mr-0" data-target="#new-customer" data-toggle="modal">
|
||||
<i class="las la-truck"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="" id="cart-details">
|
||||
<div class="aiz-pos-cart-list mb-4 mt-3 c-scrollbar-light">
|
||||
@php
|
||||
$subtotal = 0;
|
||||
$tax = 0;
|
||||
@endphp
|
||||
@if (Session::has('pos.cart'))
|
||||
<ul class="list-group list-group-flush">
|
||||
@forelse (Session::get('pos.cart') as $key => $cartItem)
|
||||
@php
|
||||
$subtotal += $cartItem['price']*$cartItem['quantity'];
|
||||
$tax += $cartItem['tax']*$cartItem['quantity'];
|
||||
$stock = \App\Models\ProductStock::find($cartItem['stock_id']);
|
||||
@endphp
|
||||
<li class="list-group-item py-0 pl-2">
|
||||
<div class="row gutters-5 align-items-center">
|
||||
<div class="col-auto w-60px">
|
||||
<div class="row no-gutters align-items-center flex-column aiz-plus-minus">
|
||||
<button class="btn col-auto btn-icon btn-sm fs-15" type="button" data-type="plus" data-field="qty-{{ $key }}" @if($stock->product->digital == 1) disabled @endif>
|
||||
<i class="las la-plus"></i>
|
||||
</button>
|
||||
<input type="text" name="qty-{{ $key }}" id="qty-{{ $key }}" class="col border-0 text-center flex-grow-1 fs-16 input-number" placeholder="1" value="{{ $cartItem['quantity'] }}" min="{{ $stock->product->min_qty }}" max="{{ $stock->qty }}" onchange="updateQuantity({{ $key }})">
|
||||
<button class="btn col-auto btn-icon btn-sm fs-15" type="button" data-type="minus" data-field="qty-{{ $key }}" @if($stock->product->digital == 1) disabled @endif>
|
||||
<i class="las la-minus"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="text-truncate-2">{{ $stock->product->name }}</div>
|
||||
<span class="span badge badge-inline fs-12 badge-soft-secondary">{{ $cartItem['variant'] }}</span>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="fs-12 opacity-60">{{ single_price($cartItem['price']) }} x {{ $cartItem['quantity'] }}</div>
|
||||
<div class="fs-15 fw-600">{{ single_price($cartItem['price']*$cartItem['quantity']) }}</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button type="button" class="btn btn-circle btn-icon btn-sm btn-soft-danger ml-2 mr-0" onclick="removeFromCart({{ $key }})">
|
||||
<i class="las la-trash-alt"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@empty
|
||||
<li class="list-group-item">
|
||||
<div class="text-center">
|
||||
<i class="las la-frown la-3x opacity-50"></i>
|
||||
<p>{{ translate('No Product Added') }}</p>
|
||||
</div>
|
||||
</li>
|
||||
@endforelse
|
||||
</ul>
|
||||
@else
|
||||
<div class="text-center">
|
||||
<i class="las la-frown la-3x opacity-50"></i>
|
||||
<p>{{ translate('No Product Added') }}</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
|
||||
<span>{{translate('Sub Total')}}</span>
|
||||
<span>{{ single_price($subtotal) }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
|
||||
<span>{{translate('Tax')}}</span>
|
||||
<span>{{ single_price($tax) }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
|
||||
<span>{{translate('Shipping')}}</span>
|
||||
<span>{{ single_price(Session::get('pos.shipping', 0)) }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between fw-600 mb-2 opacity-70">
|
||||
<span>{{translate('Discount')}}</span>
|
||||
<span>{{ single_price(Session::get('pos.discount', 0)) }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between fw-600 fs-18 border-top pt-2">
|
||||
<span>{{translate('Total')}}</span>
|
||||
<span>{{ single_price($subtotal+$tax+Session::get('pos.shipping', 0) - Session::get('pos.discount', 0)) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pos-footer mar-btm">
|
||||
<div class="d-flex flex-column flex-md-row justify-content-between">
|
||||
<div class="d-flex">
|
||||
<div class="dropdown mr-3 ml-0 dropup">
|
||||
<button class="btn btn-outline-dark btn-styled dropdown-toggle" type="button" data-toggle="dropdown">
|
||||
{{translate('Shipping')}}
|
||||
</button>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-lg">
|
||||
<div class="input-group">
|
||||
<input type="number" min="0" placeholder="Amount" name="shipping" class="form-control" value="{{ Session::get('pos.shipping', 0) }}" required onchange="setShipping()">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">{{ translate('Flat') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown dropup">
|
||||
<button class="btn btn-outline-dark btn-styled dropdown-toggle" type="button" data-toggle="dropdown">
|
||||
{{translate('Discount')}}
|
||||
</button>
|
||||
<div class="dropdown-menu p-3 dropdown-menu-lg">
|
||||
<div class="input-group">
|
||||
<input type="number" min="0" placeholder="Amount" name="discount" class="form-control" value="{{ Session::get('pos.discount', 0) }}" required onchange="setDiscount()">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">{{ translate('Flat') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-2 my-md-0">
|
||||
<button type="button" class="btn btn-primary btn-block" onclick="orderConfirmation()">{{ translate('Place Order') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@endsection
|
||||
|
||||
@section('modal')
|
||||
<!-- Address Modal -->
|
||||
<div id="new-customer" class="modal fade" role="dialog">
|
||||
<div class="modal-dialog modal-dialog-centered modal-dialog-zoom" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bord-btm">
|
||||
<h4 class="modal-title h6">{{translate('Shipping Address')}}</h4>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span></button>
|
||||
</div>
|
||||
<form id="shipping_form">
|
||||
<div class="modal-body" id="shipping_address">
|
||||
|
||||
|
||||
</div>
|
||||
</form>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-styled btn-base-3" data-dismiss="modal" id="close-button">{{translate('Close')}}</button>
|
||||
<button type="button" class="btn btn-primary btn-styled btn-base-1" id="confirm-address" data-dismiss="modal">{{translate('Confirm')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- new address modal -->
|
||||
<div id="new-address-modal" class="modal fade" role="dialog">
|
||||
<div class="modal-dialog modal-dialog-centered modal-dialog-zoom" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bord-btm">
|
||||
<h4 class="modal-title h6">{{translate('Shipping Address')}}</h4>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span></button>
|
||||
</div>
|
||||
<form class="form-horizontal" action="{{ route('addresses.store') }}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
<div class="modal-body">
|
||||
<input type="hidden" name="customer_id" id="set_customer_id" value="">
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-2 control-label" for="address">{{translate('Address')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<textarea placeholder="{{translate('Address')}}" id="address" name="address" class="form-control" required></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-2 control-label">{{translate('Country')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<select class="form-control aiz-selectpicker" data-live-search="true" data-placeholder="{{ translate('Select your country') }}" name="country_id" required>
|
||||
<option value="">{{ translate('Select your country') }}</option>
|
||||
@foreach (\App\Models\Country::where('status', 1)->get() as $key => $country)
|
||||
<option value="{{ $country->id }}">{{ $country->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-sm-2 control-label"">
|
||||
<label>{{ translate('State')}}</label>
|
||||
</div>
|
||||
<div class="col-sm-10">
|
||||
<select class="form-control mb-3 aiz-selectpicker" data-live-search="true" name="state_id" required>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-sm-2">
|
||||
<label>{{ translate('City')}}</label>
|
||||
</div>
|
||||
<div class="col-sm-10">
|
||||
<select class="form-control mb-3 aiz-selectpicker" data-live-search="true" name="city_id" required>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-2 control-label" for="postal_code">{{translate('Postal code')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="number" min="0" placeholder="{{translate('Postal code')}}" id="postal_code" name="postal_code" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-2 control-label" for="phone">{{translate('Phone')}}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="number" min="0" placeholder="{{translate('Phone')}}" id="phone" name="phone" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-styled btn-base-3" data-dismiss="modal">{{translate('Close')}}</button>
|
||||
<button type="submit" class="btn btn-primary btn-styled btn-base-1">{{translate('Save')}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="order-confirm" class="modal fade">
|
||||
<div class="modal-dialog modal-dialog-centered modal-dialog-zoom modal-xl">
|
||||
<div class="modal-content" id="variants">
|
||||
<div class="modal-header bord-btm">
|
||||
<h4 class="modal-title h6">{{translate('Order Summary')}}</h4>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span></button>
|
||||
</div>
|
||||
<div class="modal-body" id="order-confirmation">
|
||||
<div class="p-4 text-center">
|
||||
<i class="las la-spinner la-spin la-3x"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary btn-base-3" data-dismiss="modal">{{translate('Close')}}</button>
|
||||
<button type="button" onclick="oflinePayment()" class="btn btn-base-1 btn-warning">{{translate('Offline Payment')}}</button>
|
||||
<button type="button" onclick="submitOrder('cash_on_delivery')" class="btn btn-base-1 btn-info">{{translate('Confirm with COD')}}</button>
|
||||
<button type="button" onclick="submitOrder('cash')" class="btn btn-base-1 btn-success">{{translate('Confirm with Cash')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Offline Payment Modal --}}
|
||||
<div id="offlin_payment" class="modal fade" role="dialog">
|
||||
<div class="modal-dialog modal-dialog-centered modal-dialog-zoom" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bord-btm">
|
||||
<h4 class="modal-title h6">{{translate('Offline Payment Info')}}</h4>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-3 control-label" for="offline_payment_method">{{translate('Payment Method')}}</label>
|
||||
<div class="col-sm-9">
|
||||
<input placeholder="{{translate('Name')}}" id="offline_payment_method" name="offline_payment_method" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class=" row">
|
||||
<label class="col-sm-3 control-label" for="offline_payment_amount">{{translate('Amount')}}</label>
|
||||
<div class="col-sm-9">
|
||||
<input placeholder="{{translate('Amount')}}" id="offline_payment_amount" name="offline_payment_amount" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-sm-3 control-label" for="trx_id">{{translate('Transaction ID')}}</label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control mb-3" id="trx_id" name="trx_id" placeholder="{{ translate('Transaction ID') }}" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 col-form-label">{{ translate('Payment Proof') }}</label>
|
||||
<div class="col-md-9">
|
||||
<div class="input-group" data-toggle="aizuploader" data-type="image">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text bg-soft-secondary font-weight-medium">{{ translate('Browse')}}</div>
|
||||
</div>
|
||||
<div class="form-control file-amount">{{ translate('Choose image') }}</div>
|
||||
<input type="hidden" name="payment_proof" class="selected-files">
|
||||
</div>
|
||||
<div class="file-preview box sm">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary btn-base-3" data-dismiss="modal">{{translate('Close')}}</button>
|
||||
<button type="button" onclick="submitOrder('offline_payment')" class="btn btn-styled btn-base-1 btn-success">{{translate('Confirm')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('script')
|
||||
<script type="text/javascript">
|
||||
|
||||
var products = null;
|
||||
|
||||
$(document).ready(function(){
|
||||
$('body').addClass('side-menu-closed');
|
||||
$('#product-list').on('click','.add-plus:not(.c-not-allowed)',function(){
|
||||
var stock_id = $(this).data('stock-id');
|
||||
$.post('{{ route('pos.addToCart') }}',{_token:AIZ.data.csrf, stock_id:stock_id}, function(data){
|
||||
if(data.success == 1){
|
||||
updateCart(data.view);
|
||||
}else{
|
||||
AIZ.plugins.notify('danger', data.message);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
filterProducts();
|
||||
getShippingAddress();
|
||||
});
|
||||
|
||||
$("#confirm-address").click(function (){
|
||||
var data = new FormData($('#shipping_form')[0]);
|
||||
|
||||
$.ajax({
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': AIZ.data.csrf
|
||||
},
|
||||
method: "POST",
|
||||
url: "{{route('pos.set-shipping-address')}}",
|
||||
data: data,
|
||||
cache: false,
|
||||
contentType: false,
|
||||
processData: false,
|
||||
success: function (data, textStatus, jqXHR) {
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
function updateCart(data){
|
||||
$('#cart-details').html(data);
|
||||
AIZ.extra.plusMinus();
|
||||
}
|
||||
|
||||
function filterProducts(){
|
||||
var keyword = $('input[name=keyword]').val();
|
||||
var category = $('select[name=poscategory]').val();
|
||||
var brand = $('select[name=brand]').val();
|
||||
$.get('{{ route('pos.search_seller_product') }}',{
|
||||
keyword : keyword,
|
||||
category : category,
|
||||
brand : brand
|
||||
}, function(data){
|
||||
products = data;
|
||||
$('#product-list').html(null);
|
||||
setProductList(data);
|
||||
});
|
||||
}
|
||||
|
||||
function loadMoreProduct(){
|
||||
if(products != null && products.links.next != null){
|
||||
$('#load-more').find('.btn').html('{{ translate('Loading..') }}');
|
||||
$.get(products.links.next,{}, function(data){
|
||||
products = data;
|
||||
setProductList(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function setProductList(data){
|
||||
for (var i = 0; i < data.data.length; i++) {
|
||||
$('#product-list').append(
|
||||
`<div class="w-140px w-xl-180px w-xxl-210px mx-2">
|
||||
<div class="card bg-white c-pointer product-card hov-container">
|
||||
<div class="position-relative">
|
||||
${data.data[i].digital == 0
|
||||
?
|
||||
`<span class="absolute-top-left mt-1 ml-1 mr-0">
|
||||
${data.data[i].qty > 0
|
||||
? `<span class="badge badge-inline badge-success fs-13">{{ translate('In stock') }}`
|
||||
: `<span class="badge badge-inline badge-danger fs-13">{{ translate('Out of stock') }}` }
|
||||
: ${data.data[i].qty}</span>
|
||||
</span>`
|
||||
: ''
|
||||
}
|
||||
${data.data[i].variant != null
|
||||
? `<span class="badge badge-inline badge-warning absolute-bottom-left mb-1 ml-1 mr-0 fs-13 text-truncate">${data.data[i].variant}</span>`
|
||||
: '' }
|
||||
<img src="${data.data[i].thumbnail_image }" class="card-img-top img-fit h-120px h-xl-180px h-xxl-210px mw-100 mx-auto" >
|
||||
</div>
|
||||
<div class="card-body p-2 p-xl-3">
|
||||
<div class="text-truncate fw-600 fs-14 mb-2">${data.data[i].name}</div>
|
||||
<div class="">
|
||||
${data.data[i].price != data.data[i].base_price
|
||||
? `<del class="mr-2 ml-0">${data.data[i].base_price}</del><span>${data.data[i].price}</span>`
|
||||
: `<span>${data.data[i].base_price}</span>`
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="add-plus absolute-full rounded overflow-hidden hov-box ${(data.data[i].digital == 0 && data.data[i].qty <= 0) ? 'c-not-allowed' : '' }" data-stock-id="${data.data[i].stock_id}">
|
||||
<div class="absolute-full bg-dark opacity-50">
|
||||
</div>
|
||||
<i class="las la-plus absolute-center la-6x text-white"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
);
|
||||
}
|
||||
if (data.links.next != null) {
|
||||
$('#load-more').find('.btn').html('{{ translate('Load More.') }}');
|
||||
}
|
||||
else {
|
||||
$('#load-more').find('.btn').html('{{ translate('Nothing more found.') }}');
|
||||
}
|
||||
}
|
||||
|
||||
function removeFromCart(key){
|
||||
$.post('{{ route('pos.removeFromCart') }}', {_token:AIZ.data.csrf, key:key}, function(data){
|
||||
updateCart(data);
|
||||
});
|
||||
}
|
||||
|
||||
function addToCart(product_id, variant, quantity){
|
||||
$.post('{{ route('pos.addToCart') }}',{_token:AIZ.data.csrf, product_id:product_id, variant:variant, quantity, quantity}, function(data){
|
||||
$('#cart-details').html(data);
|
||||
$('#product-variation').modal('hide');
|
||||
});
|
||||
}
|
||||
|
||||
function updateQuantity(key){
|
||||
$.post('{{ route('pos.updateQuantity') }}',{_token:AIZ.data.csrf, key:key, quantity: $('#qty-'+key).val()}, function(data){
|
||||
if(data.success == 1){
|
||||
updateCart(data.view);
|
||||
}else{
|
||||
AIZ.plugins.notify('danger', data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function setDiscount(){
|
||||
var discount = $('input[name=discount]').val();
|
||||
$.post('{{ route('pos.setDiscount') }}',{_token:AIZ.data.csrf, discount:discount}, function(data){
|
||||
updateCart(data);
|
||||
});
|
||||
}
|
||||
|
||||
function setShipping(){
|
||||
var shipping = $('input[name=shipping]').val();
|
||||
$.post('{{ route('pos.setShipping') }}',{_token:AIZ.data.csrf, shipping:shipping}, function(data){
|
||||
updateCart(data);
|
||||
});
|
||||
}
|
||||
|
||||
function getShippingAddress(){
|
||||
$.post('{{ route('pos.getShippingAddress') }}',{_token:AIZ.data.csrf, id:$('select[name=user_id]').val()}, function(data){
|
||||
$('#shipping_address').html(data);
|
||||
});
|
||||
}
|
||||
|
||||
function add_new_address(){
|
||||
var customer_id = $('#customer_id').val();
|
||||
$('#set_customer_id').val(customer_id);
|
||||
$('#new-address-modal').modal('show');
|
||||
$("#close-button").click();
|
||||
}
|
||||
|
||||
function orderConfirmation(){
|
||||
$('#order-confirmation').html(`<div class="p-4 text-center"><i class="las la-spinner la-spin la-3x"></i></div>`);
|
||||
$('#order-confirm').modal('show');
|
||||
$.post('{{ route('pos.getOrderSummary') }}',{_token:AIZ.data.csrf}, function(data){
|
||||
$('#order-confirmation').html(data);
|
||||
});
|
||||
}
|
||||
|
||||
function oflinePayment(){
|
||||
$('#offlin_payment').modal('show');
|
||||
}
|
||||
|
||||
function submitOrder(payment_type){
|
||||
var user_id = $('select[name=user_id]').val();
|
||||
var shipping = $('input[name=shipping]:checked').val();
|
||||
var discount = $('input[name=discount]').val();
|
||||
var shipping_address = $('input[name=address_id]:checked').val();
|
||||
var offline_payment_method = $('input[name=offline_payment_method]').val();
|
||||
var offline_payment_amount = $('input[name=offline_payment_amount]').val();
|
||||
var offline_trx_id = $('input[name=trx_id]').val();
|
||||
var offline_payment_proof = $('input[name=payment_proof]').val();
|
||||
|
||||
$.post('{{ route('pos.order_place') }}',{
|
||||
_token : AIZ.data.csrf,
|
||||
user_id : user_id,
|
||||
shipping_address : shipping_address,
|
||||
payment_type : payment_type,
|
||||
shipping : shipping,
|
||||
discount : discount,
|
||||
offline_payment_method : offline_payment_method,
|
||||
offline_payment_amount : offline_payment_amount,
|
||||
offline_trx_id : offline_trx_id,
|
||||
offline_payment_proof : offline_payment_proof
|
||||
|
||||
}, function(data){
|
||||
if(data.success == 1){
|
||||
AIZ.plugins.notify('success', data.message );
|
||||
location.reload();
|
||||
}
|
||||
else{
|
||||
AIZ.plugins.notify('danger', data.message );
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//address
|
||||
$(document).on('change', '[name=country_id]', function() {
|
||||
var country_id = $(this).val();
|
||||
get_states(country_id);
|
||||
});
|
||||
|
||||
$(document).on('change', '[name=state_id]', function() {
|
||||
var state_id = $(this).val();
|
||||
get_city(state_id);
|
||||
});
|
||||
|
||||
function get_states(country_id) {
|
||||
$('[name="state"]').html("");
|
||||
$.ajax({
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
||||
},
|
||||
url: "{{route('get-state')}}",
|
||||
type: 'POST',
|
||||
data: {
|
||||
country_id : country_id
|
||||
},
|
||||
success: function (response) {
|
||||
var obj = JSON.parse(response);
|
||||
if(obj != '') {
|
||||
$('[name="state_id"]').html(obj);
|
||||
AIZ.plugins.bootstrapSelect('refresh');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function get_city(state_id) {
|
||||
$('[name="city"]').html("");
|
||||
$.ajax({
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
||||
},
|
||||
url: "{{route('get-city')}}",
|
||||
type: 'POST',
|
||||
data: {
|
||||
state_id: state_id
|
||||
},
|
||||
success: function (response) {
|
||||
var obj = JSON.parse(response);
|
||||
if(obj != '') {
|
||||
$('[name="city_id"]').html(obj);
|
||||
AIZ.plugins.bootstrapSelect('refresh');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@endsection
|
||||
@@ -0,0 +1,35 @@
|
||||
@extends('seller.layouts.app')
|
||||
|
||||
@section('panel_content')
|
||||
|
||||
<h4 class="text-center text-muted">{{translate('POS Configuration')}}</h4>
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0 h6">{{ translate('Thermal Printer Size') }}</h5>
|
||||
</div>
|
||||
<div class="card-body text-center">
|
||||
<form class="form-horizontal" action="{{ route('seller_business_settings.update') }}" method="POST">
|
||||
@csrf
|
||||
<div class="form-group row">
|
||||
<input type="hidden" name="types[]" value="print_width_seller_pos">
|
||||
<div class="input-group mb-3">
|
||||
<input type="text" class="form-control" name="print_width_seller_pos" placeholder="{{ translate('Print width in mm') }}"
|
||||
value="{{ get_setting('print_width_seller_pos') }}">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text" id="basic-addon2">{{ translate('mm') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group mb-0 text-right">
|
||||
<button type="submit" class="btn btn-sm btn-primary">{{ translate('Save') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
<div class="">
|
||||
@foreach (\App\Models\Address::where('user_id',$user_id)->get() as $key => $address)
|
||||
<label class="aiz-megabox d-block bg-white">
|
||||
<input type="radio" name="address_id" value="{{ $address->id }}" @if ($address->set_default) checked @endif required>
|
||||
<span class="d-flex p-3 aiz-megabox-elem">
|
||||
<span class="aiz-rounded-check flex-shrink-0 mt-1"></span>
|
||||
<span class="flex-grow-1 pl-3">
|
||||
<div>
|
||||
<span class="alpha-6">{{ translate('Address') }}:</span>
|
||||
<span class="strong-600 ml-2">{{ $address->address }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="alpha-6">{{ translate('Postal Code') }}:</span>
|
||||
<span class="strong-600 ml-2">{{ $address->postal_code }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="alpha-6">{{ translate('City') }}:</span>
|
||||
<span class="strong-600 ml-2">{{ $address->city }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="alpha-6">{{ translate('Country') }}:</span>
|
||||
<span class="strong-600 ml-2">{{ $address->country }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="alpha-6">{{ translate('Phone') }}:</span>
|
||||
<span class="strong-600 ml-2">{{ $address->phone }}</span>
|
||||
</div>
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
@endforeach
|
||||
<input type="hidden" id="customer_id" value="{{$user_id}}">
|
||||
<div class="col-md-6 mx-auto" onclick="add_new_address()">
|
||||
<div class="border p-3 rounded mb-3 c-pointer text-center bg-white">
|
||||
<i class="la la-plus la-2x"></i>
|
||||
<div class="alpha-7">{{ translate('Add New Address') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user