/home/brandsfa/.trash/app/Http/Controllers/Vendor/POS/POSOrderController.php
<?php
namespace App\Http\Controllers\Vendor\POS;
use App\Contracts\Repositories\CustomerRepositoryInterface;
use App\Contracts\Repositories\OrderDetailRepositoryInterface;
use App\Contracts\Repositories\OrderRepositoryInterface;
use App\Contracts\Repositories\ProductRepositoryInterface;
use App\Contracts\Repositories\VendorRepositoryInterface;
use App\Enums\SessionKey;
use App\Enums\ViewPaths\Vendor\POSOrder;
use App\Http\Controllers\BaseController;
use App\Services\CartService;
use App\Services\OrderDetailsService;
use App\Services\OrderService;
use App\Services\POSService;
use App\Traits\CalculatorTrait;
use App\Traits\CustomerTrait;
use Brian2694\Toastr\Facades\Toastr;
use Illuminate\Contracts\View\View;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Str;
class POSOrderController extends BaseController
{
use CustomerTrait;
use CalculatorTrait;
/**
* @param ProductRepositoryInterface $productRepo
* @param CustomerRepositoryInterface $customerRepo
* @param OrderRepositoryInterface $orderRepo
* @param OrderDetailRepositoryInterface $orderDetailRepo
* @param VendorRepositoryInterface $vendorRepo
* @param POSService $POSService
* @param CartService $cartService
* @param OrderDetailsService $orderDetailsService
* @param OrderService $orderService
*/
public function __construct(
private readonly ProductRepositoryInterface $productRepo,
private readonly CustomerRepositoryInterface $customerRepo,
private readonly OrderRepositoryInterface $orderRepo,
private readonly OrderDetailRepositoryInterface $orderDetailRepo,
private readonly VendorRepositoryInterface $vendorRepo,
private readonly POSService $POSService,
private readonly CartService $cartService,
private readonly OrderDetailsService $orderDetailsService,
private readonly OrderService $orderService,
)
{
}
/**
* @param Request|null $request
* @param string|null $type
* @return View|Collection|LengthAwarePaginator|callable|RedirectResponse|null
*/
public function index(?Request $request, string $type = null): View|Collection|LengthAwarePaginator|null|callable|RedirectResponse
{
return $this->getOrderDetails(id:$type);
}
/**
* @param string $id
* @return View|RedirectResponse
*/
public function getOrderDetails(string $id):View|RedirectResponse
{
$vendorId = auth('seller')->id();
$vendor = $this->vendorRepo->getFirstWhere(params: ['id' => $vendorId]);
$getPOSStatus = getWebConfig('seller_pos');
if ($vendor['pos_status'] == 0 || $getPOSStatus == 0) {
Toastr::warning(translate('access_denied!!'));
return redirect()->back();
}
$order = $this->orderRepo->getFirstWhere(params:['id'=>$id],relations:['details', 'shipping', 'seller']);
return view(POSOrder::ORDER_DETAILS[VIEW], compact('order'));
}
/**
* @param Request $request
* @return RedirectResponse
*/
public function placeOrder(Request $request):RedirectResponse
{
$amount = $request['amount'];
$cartId =session(SessionKey::CURRENT_USER);
$condition = $this->POSService->checkConditions(amount: $amount);
if ($condition == 'true'){
return redirect()->back();
}
$userId = $this->cartService->getUserId();
if($request['type'] == 'wallet' && $userId != 0)
{
$customerBalance = $this->customerRepo->getFirstWhere(params:['id' => $userId]) ?? 0;
if($customerBalance['wallet_balance'] >= $amount)
{
$this->createWalletTransaction(user_id: $userId, amount: floatval($amount), transaction_type: 'order_place', reference: 'order_place_in_pos');
}else{
Toastr::error(translate('need_Sufficient_Amount_Balance'));
return back();
}
}
$cart = session($cartId);
$orderId = 100000 + $this->orderRepo->getList()->count() + 1;
$order = $this->orderRepo->getFirstWhere(params:['id'=>$orderId]);
if ($order) {
$orderId =$this->orderRepo->getList(orderBy:['id'=>'DESC'])->first()->id + 1;
}
foreach($cart as $item)
{
if(is_array($item))
{
$product = $this->productRepo->getFirstWhere(params:['id'=>$item['id']]);
if($product)
{
$tax = $this->getTaxAmount($item['price']-$item['discount'], $product['tax']);
$price = $product['tax_model'] == 'include' ? $item['price']-$tax : $item['price'];
$orderDetail = $this->orderDetailsService->getPOSOrderDetailsData(
orderId:$orderId, item: $item,
product: $product,price:$price,tax: $tax
);
if ($item['variant'] != null) {
$type = $item['variant'];
$variantStore = [];
foreach (json_decode($product['variation'],true) as $variant) {
if ($type == $variant['type']) {
$variant['qty'] -= $item['quantity'];
}
$variantStore[] = $variant;
}
$this->productRepo->update(id: $product['id'],data: ['variation' => json_encode($variantStore)]);
}
if($product['product_type'] == 'physical') {
$currentStock = $product['current_stock'] - $item['quantity'];
$this->productRepo->update(id: $product['id'],data: ['current_stock' =>$currentStock]);
}
$this->orderDetailRepo->add(data: $orderDetail);
}
}
}
$order = $this->orderService->getPOSOrderData(
orderId: $orderId,
cart: $cart,
amount: $amount,
paymentType: $request['type'],
addedBy: 'seller',
userId: $userId
);
$this->orderRepo->add(data: $order);
session()->forget($cartId);
session(['last_order' => $orderId]);
$this->cartService->getNewCartId();
Toastr::success(translate('order_placed_successfully'));
return redirect()->back();
}
public function cancelOrder(Request $request):JsonResponse
{
session()->remove($request['cart_id']);
$totalHoldOrders = $this->POSService->getTotalHoldOrders();
$cartNames = $this->POSService->getCartNames();
$cartItems = $this->getHoldOrderCalculationData(cartNames:$cartNames);
return response()->json([
'message' => $request['cart_id'].' '.translate('order_is_cancel'),
'status' => 'success',
'view' => view(POSOrder::CANCEL_ORDER[VIEW],compact('cartItems','totalHoldOrders'))->render(),
]);
}
/**
* @return JsonResponse
*/
public function getAllHoldOrdersView(Request $request):JsonResponse
{
$cartNames = $this->POSService->getCartNames();
$cartItems = $this->getHoldOrderCalculationData(cartNames:$cartNames);
$totalHoldOrders = $this->POSService->getTotalHoldOrders();
if(!empty($request['customer'])){
$searchValue = strtolower($request['customer']);
$filteredItems = collect($cartItems)->filter(function ($item) use ($searchValue) {
return str_contains(strtolower($item['customerName']), $searchValue) !== false;
});
$cartItems = $filteredItems->all();
}
return response()->json([
'flag' => 'inactive',
'totalHoldOrders'=>$totalHoldOrders,
'view' => view(POSOrder::HOLD_ORDERS[VIEW],compact('totalHoldOrders','cartItems'))->render(),
]);
}
/**
* @param array $cartNames
* @return array
*/
protected function getHoldOrderCalculationData(array $cartNames):array
{
$CustomerCartData = [];
foreach ($cartNames as $cartId) {
$CustomerData =$this->getCustomerCartData(cartName:$cartId);
$CartItemData = $this->calculateCartItemsData(cartName: $cartId, customerCartData: $CustomerData);
$CustomerCartData[$cartId] = array_merge($CustomerData[$cartId],$CartItemData);
}
return $CustomerCartData;
}
/**
* @param string $cartName
* @return array
*/
protected function getCustomerCartData(string $cartName):array
{
$customerCartData = [];
if (Str::contains($cartName, 'walking-customer')) {
$customerName = 'Walking Customer';
$customerPhone = "";
$customerId = 0 ;
} else {
$customerId = explode('-', $cartName)[2];
$currentCustomerData = $this->customerRepo->getFirstWhere(params: ['id' => $customerId]);
$customerName = $currentCustomerData['f_name'] . ' ' . $currentCustomerData['l_name'];
$customerPhone = $currentCustomerData['phone'];
}
$customerCartData[$cartName] = [
'customerName' => $customerName,
'customerPhone' => $customerPhone,
'customerId'=>$customerId,
];
return $customerCartData;
}
protected function calculateCartItemsData(string $cartName, array $customerCartData):array
{
$cartItemValue = [];
$subTotalCalculation = [
'countItem' => 0,
'taxCalculate' => 0 ,
'totalTaxShow' => 0,
'totalTax' => 0,
'subtotal' => 0,
'discountOnProduct' => 0,
'productSubtotal' => 0,
];
if(session()->get($cartName)) {
foreach (session()->get($cartName) as $cartItem) {
if (is_array($cartItem)) {
$product = $this->productRepo->getFirstWhere(params: ['id' => $cartItem['id']]);
$subTotalCalculation = $this->cartService->getCartSubtotalCalculation(
product: $product,
cartItem: $cartItem,
calculation : $subTotalCalculation
);
if ($cartItem['customerId'] == $customerCartData[$cartName]['customerId']) {
$cartItem['productSubtotal'] = $subTotalCalculation['productSubtotal'];
$subTotalCalculation['customerOnHold']=$cartItem['customerOnHold'];
$cartItemValue[] = $cartItem;
}
}
}
}
$totalCalculation = $this->cartService->getTotalCalculation(
subTotalCalculation:$subTotalCalculation,cartName: $cartName
);
return [
'countItem' => $subTotalCalculation['countItem'],
'total' => $totalCalculation['total'],
'subtotal' => $subTotalCalculation['subtotal'],
'taxCalculate' => $subTotalCalculation['taxCalculate'],
'totalTaxShow' => $subTotalCalculation['totalTaxShow'],
'totalTax' => $subTotalCalculation['totalTax'],
'discountOnProduct' => $subTotalCalculation['discountOnProduct'],
'productSubtotal' => $subTotalCalculation['productSubtotal'],
'cartItemValue' => $cartItemValue,
'couponDiscount' => $totalCalculation['couponDiscount'],
'extraDiscount' => $totalCalculation['extraDiscount'],
'customerOnHold' => $subTotalCalculation['customerOnHold']??false,
];
}
}