![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/inventory.corals.io/Corals/modules/Inventory/Http/Controllers/ |
<?php namespace Corals\Modules\Inventory\Http\Controllers; use Carbon\Carbon; use Corals\Foundation\Http\Controllers\BaseController; use Corals\Modules\Inventory\DataTables\OrdersDataTable; use Corals\Modules\Inventory\Http\Requests\OrderPartialUpdateRequest; use Corals\Modules\Inventory\Http\Requests\OrderRequest; use Corals\Modules\Inventory\Models\Item; use Corals\Modules\Inventory\Models\Order; use Corals\Modules\Inventory\Services\OrderService; use Corals\Modules\Inventory\Traits\OrderCalculations; use Corals\Modules\Payment\Common\Models\Invoice; use Corals\Modules\Payment\Facades\Payments; use Illuminate\Http\Request; class OrdersController extends BaseController { use OrderCalculations; protected $orderService; public function __construct(OrderService $orderService) { $this->orderService = $orderService; $this->resource_url = config('inventory.models.order.resource_url'); $this->title = trans('Inventory::module.order.title'); $this->title_singular = trans('Inventory::module.order.title_singular'); parent::__construct(); } /** * @param OrderRequest $request * @param OrdersDataTable $dataTable * @return mixed */ public function index(OrderRequest $request, OrdersDataTable $dataTable) { $actions = $this->generateActions(); return $dataTable->render('Inventory::orders.index', compact('actions')); } protected function generateActions() { $types = config('inventory.types'); $actions = []; foreach ($types as $key => $label) { array_push($actions, [ 'icon' => 'fa fa-fw fa-circle-o', 'href' => url($this->resource_url . '/create?type=' . $key), 'label' => $label, 'data' => [] ]); } return $actions; } /** * @param OrderRequest $request * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function create(OrderRequest $request) { $this->validate($request, [ 'type' => 'sometimes|in:sales_order,inventory_order' ]); $order = new Order(); $order->type = $request->get('type', 'sales_order'); $order->status = 'pending'; $status = 'pending'; $billing = $order->billing; $billing['payment_status'] = $status; $order->currency = 'ILS'; $order->order_date = now()->toDateString(); if ($order->type == 'sales_order') { $order->invoice = [ 'code' => Invoice::getCode('INV'), 'invoice_date' => now()->toDateString(), 'due_date' => now()->toDateString(), 'status' => 'pending', ]; } $discountItem = [ 'code' => null, 'amount' => null, 'type' => null, ]; $taxesList = Payments::getTaxesList(); $this->setViewSharedData([ 'title_singular' => trans('Corals::labels.create_title', ['title' => $this->title_singular]) ]); return view("Inventory::orders.{$order->type}.create_edit") ->with(compact('order', 'taxesList', 'discountItem', 'billing')); } /** * @param OrderRequest $request * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ public function store(OrderRequest $request) { try { if ($request->type == 'sales_order') { $data = $this->getOrderDataFromRequest($request); $order = Order::create($data['orderData']); $order->items()->createMany($data['items']); $invoice = new Invoice($this->getInvoiceDataFromRequest($request, $data['orderItemsCalculations'])); $invoice = $order->invoice()->save($invoice); $this->createInvoiceItemsFromOrder($order, $invoice); } else { $data = $this->getOrderDataFromRequest($request); $order = Order::create($data['orderData']); $order->items()->createMany($data['items']); } if ($request->has('send_invoice')) { event('notifications.invoice.send_invoice', ['invoice' => $invoice]); } flash(trans('Corals::messages.success.created', ['item' => $this->title_singular]))->success(); } catch (\Exception $exception) { log_exception($exception, Order::class, 'store'); } return redirectTo($this->resource_url); } /** * @param OrderRequest $request * @param Order $order * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View */ public function show(OrderRequest $request, Order $order) { $invoice = $order->invoice; $available_gateways = \Payments::getAvailableGateways(); $gateway = ''; $urlPrefix = ''; $this->setViewSharedData([ 'title_singular' => trans('Corals::labels.show_title', ['title' => $this->title_singular]), 'showModel' => $order ]); return view('Inventory::orders.show')->with(compact('order', 'invoice', 'available_gateways', 'gateway', 'urlPrefix')); } /** * @param OrderRequest $request * @param Order $order * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function edit(OrderRequest $request, Order $order) { $items = $this->formatOrderItemsForEdit($order); $discountItem = $order->items()->where('type', 'Discount')->first(); if ($order->invoice) { $order->invoice->due_date = Carbon::parse($order->invoice->due_date)->toDateString(); $order->invoice->invoice_date = Carbon::parse($order->invoice->invoice_date)->toDateString(); } if ($discountItem) { $discountItem = [ 'code' => $discountItem->getProperty('code'), 'amount' => $discountItem->getProperty('amount'), 'type' => $discountItem->getProperty('type'), ]; } else { $discountItem = [ 'code' => null, 'amount' => null, 'type' => null, ]; } $taxesList = Payments::getTaxesList(); $this->setViewSharedData([ 'title_singular' => trans('Corals::labels.update_title', ['title' => $this->title_singular]) ]); return view("Inventory::orders.{$order->type}.create_edit") ->with(compact('order', 'taxesList', 'items', 'discountItem')); } /** * @param OrderRequest $request * @param Order $order * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ public function update(OrderRequest $request, Order $order) { try { if ($order->type == 'sales_order') { $data = $this->getOrderDataFromRequest($request); $order->update($data['orderData']); $order->inventoryTransactions()->forceDelete(); $order->items()->forceDelete(); $order->items()->createMany($data['items']); $invoiceData = $this->getInvoiceDataFromRequest($request, $data['orderItemsCalculations']); $invoice = $order->invoice; if ($invoice) { $invoice->update($invoiceData); } else { $invoice = $order->invoice()->create($invoiceData); } $this->createInvoiceItemsFromOrder($order, $invoice); if ($request->has('send_invoice')) { event('notifications.invoice.send_invoice', ['invoice' => $invoice]); } } $data = $this->getOrderDataFromRequest($request); $order->update($data['orderData']); $order->inventoryTransactions()->forceDelete(); $order->items()->forceDelete(); $order->items()->createMany($data['items']); flash(trans('Corals::messages.success.updated', ['item' => $this->title_singular]))->success(); } catch (\Exception $exception) { log_exception($exception, Order::class, 'update'); } return redirectTo($this->resource_url); } /** * @param OrderRequest $request * @param Order $order * @return \Illuminate\Http\JsonResponse */ public function destroy(OrderRequest $request, Order $order) { try { $this->orderService->destroy($request, $order); $message = [ 'level' => 'success', 'message' => trans('Corals::messages.success.deleted', ['item' => $this->title_singular]) ]; } catch (\Exception $exception) { log_exception($exception, Order::class, 'destroy'); $message = ['level' => 'error', 'message' => $exception->getMessage()]; } return response()->json($message); } protected function getOrderItems($request) { $items = $request->get('items'); { $orderItems = []; foreach ($items as $type => $typeItems) switch ($type) { case 'Item': foreach ($typeItems as $id => $item) { $itemModel = Item::find($id); if (!$itemModel) { continue; } $orderItems[] = [ 'item_code' => $itemModel->code, 'amount' => $item['unit_price'], 'description' => $item['description'], 'quantity' => $item['quantity'], 'type' => $type, 'sub_total' => floatval($item['unit_price']) * intval($item['quantity']), 'tax_ids' => $item['taxes'] ?? [] ]; } break; case 'Fee': foreach ($typeItems as $id => $item) { $orderItems[] = [ 'item_code' => $item['item_code'], 'tax_ids' => $item['taxes'] ?? [], 'amount' => $item['unit_price'], 'quantity' => $item['quantity'], 'sub_total' => floatval($item['unit_price']) * intval($item['quantity']), 'description' => $item['description'] ?? ($item['item_code'] . ' - ' . $type), 'type' => $type, ]; } break; } } return $orderItems; } protected function getOrderDataFromRequest($request) { $orderData = $request->only(['number', 'currency', 'inventory_id', 'status', 'type', 'supplier_id', 'order_date','notes']); if ($request->type == 'sales_order') { $orderData['user_id'] = $request->input('invoice.user_id'); $orderData['billing']['payment_status'] = $request->input('invoice.status'); $orderData['billing']['billing_address'] = $request->input('billing_address'); $orderData['shipping']['shipping_status'] = ''; $orderData['shipping']['shipping_address'] = $request->input('shipping_address'); } else { $orderData['billing']['payment_status'] = 'pending'; $orderData['billing']['billing_address'] = null; $orderData['shipping']['shipping_status'] = ''; $orderData['shipping']['shipping_address'] = null; } $items = $this->getOrderItems($request); $orderItemsCalculations = $this->calculateOrder($request->all(), false); if (!empty($orderItemsCalculations['tax_total'])) { $items[] = [ 'amount' => $orderItemsCalculations['tax_total'], 'quantity' => 1, 'sub_total' => $orderItemsCalculations['tax_total'], 'description' => 'Sales Tax', 'type' => 'Tax', 'properties' => [], ]; } if (!empty($orderItemsCalculations['discount'])) { $items[] = [ 'amount' => -1 * $orderItemsCalculations['discount'], 'quantity' => 1, 'sub_total' => -1 * $orderItemsCalculations['discount'], 'type' => 'Discount', 'properties' => [ 'type' => $request->input('discount_properties.type'), 'code' => $request->input('discount_properties.code'), 'amount' => $request->input('discount_properties.amount') ], ]; } $orderData['total'] = $orderItemsCalculations['invoiceTotal'] ?? 0; $orderData['sub_total'] = $orderItemsCalculations['subtotal'] ?? 0; $orderData['discount_total'] = $orderItemsCalculations['discount'] ?? 0; $orderData['tax_total'] = $orderItemsCalculations['tax_total'] ?? 0; return compact('orderData', 'items', 'orderItemsCalculations'); } public function reCalculateOrder(Request $request) { return $this->calculateOrder($request->all()); } public function formatOrderItemsForEdit($order) { $items = []; foreach ($order->items as $orderItem) { if (in_array($orderItem->type, ['Tax', 'Discount'])) { continue; } switch ($orderItem->type) { case 'Item': $items['Item'][] = [ 'id' => $orderItem->item->id, 'item_code' => $orderItem->item_code, 'unit_price' => $orderItem->amount, 'quantity' => $orderItem->quantity, 'description' => $orderItem->description, 'type' => $orderItem->type, 'tax_ids' => $orderItem->tax_ids ]; break; case 'Fee': $items['Fee'][] = [ 'id' => count($items['Fee'] ?? []), 'item_code' => $orderItem->item_code, 'unit_price' => $orderItem->amount, 'quantity' => $orderItem->quantity, 'description' => $orderItem->description, 'type' => $orderItem->type, 'tax_ids' => $orderItem->tax_ids ]; break; } } return $items; } protected function getInvoiceDataFromRequest($request, $orderItemsCalculations) { $invoiceData = $request->get('invoice'); $invoiceData['currency'] = $request->get('currency'); $invoiceData['sub_total'] = $orderItemsCalculations['subtotal']; $invoiceData['total'] = $orderItemsCalculations['invoiceTotal']; return $invoiceData; } protected function createInvoiceItemsFromOrder($order, $invoice) { $invoice_items = []; foreach ($order->items as $order_item) { $description = "$order_item->type-$order_item->item_code-$order_item->description"; $invoice_items[] = [ 'code' => \Str::random(6), 'description' => $description, 'amount' => $order_item->amount, 'quantity' => $order_item->quantity, 'itemable_id' => $order_item->id, 'itemable_type' => get_class($order_item), ]; } $invoice->items()->forceDelete(); $invoice->items()->createMany($invoice_items); } /** * @param OrderPartialUpdateRequest $request * @param Order $order * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function editPaymentDetails(OrderPartialUpdateRequest $request, Order $order) { $order_statuses = trans(config('inventory.models.order.statuses')); $payment_statuses = trans(config('inventory.models.order.payment_statuses')); $this->setViewSharedData(['title_singular' => trans('Inventory::module.order.update')]); return view('Inventory::orders.payment_details')->with(compact('order', 'order_statuses', 'payment_statuses')); } /** * @param OrderPartialUpdateRequest $request * @param Order $order * @return \Illuminate\Foundation\Application|\Illuminate\Http\JsonResponse|mixed */ public function updatePaymentDetails(OrderPartialUpdateRequest $request, Order $order) { try { $data = $request->all(); $billing = $order->billing ?? []; if ($request->has('billing')) { $billing = array_replace_recursive($billing, $data['billing']); $order->update([ 'billing' => $billing, ]); } $message = [ 'level' => 'success', 'message' => trans('Corals::messages.success.created', ['item' => $this->title_singular]) ]; } catch (\Exception $exception) { log_exception($exception, Order::class, 'update'); } return response()->json($message); } /** * @param OrderPartialUpdateRequest $request * @param Order $order * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function editOrderStatus(OrderPartialUpdateRequest $request, Order $order) { $order_statuses = trans(config('inventory.models.order.statuses')); $this->setViewSharedData(['title_singular' => trans('Inventory::module.order.update')]); return view('Inventory::orders.order_status')->with(compact('order', 'order_statuses')); } /** * @param OrderPartialUpdateRequest $request * @param Order $order * @return \Illuminate\Foundation\Application|\Illuminate\Http\JsonResponse|mixed */ public function updateOrderStatus(OrderPartialUpdateRequest $request, Order $order) { try { $data = $request->all(); $order->update([ 'status' => $data['status'], ]); $message = [ 'level' => 'success', 'message' => trans('Corals::messages.success.created', ['item' => $this->title_singular]) ]; } catch (\Exception $exception) { log_exception($exception, Order::class, 'update'); } return response()->json($message); } }