Spamworldpro Mini Shell
Spamworldpro


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/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/corals/inventory.corals.io/Corals/modules/Inventory/Http/Controllers/OrdersController.php
<?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);
    }

}

Spamworldpro Mini