Untitled

 avatar
unknown
plain_text
a year ago
8.9 kB
2
Indexable
<?php

/**
 * File name: ParentOrderController.php
 * Last modified: 2020.06.11 at 16:10:52
 * Author: SmarterVision - https://codecanyon.net/user/smartervision
 * Copyright (c) 2020
 */

namespace App\Http\Controllers;

use App\Models\Coupon;
use App\Models\Order;
use App\Criteria\Users\AdminsCriteria;
use App\Notifications\NewOrder;
use App\Repositories\CartRepository;
use App\Repositories\CouponRepository;
use App\Repositories\NotificationRepository;
use App\Repositories\OrderRepository;
use App\Repositories\OrderStatusRepository;
use App\Repositories\PaymentRepository;
use App\Repositories\FoodOrderRepository;
use App\Repositories\ExtraRepository;
use App\Repositories\UserRepository;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
use Prettus\Validator\Exceptions\ValidatorException;
use Exception;

abstract class ParentOrderController extends Controller
{
    /** @var  OrderRepository */
    protected $orderRepository;
    /** @var  FoodOrderRepository */
    protected $foodOrderRepository;
    /** @var  CartRepository */
    protected $cartRepository;
    /** @var  UserRepository */
    protected $userRepository;
    /** @var  PaymentRepository */
    protected $paymentRepository;
    /** @var  NotificationRepository */
    protected $notificationRepository;
    protected $extraRepository;

    /** @var double */
    protected $total;
    /** @var double */
    protected $subtotal;

    /** @var Order */
    protected $order;
    /** @var Coupon */
    protected $coupon;
    /**
     * @var OrderStatusRepository
     */
    protected $orderStatusRepository;
    /**
     * @var CouponRepository
     */
    protected $couponRepository;


    /**
     * OrderAPIController constructor.
     * @param OrderRepository $orderRepo
     * @param FoodOrderRepository $foodOrderRepository
     * @param CartRepository $cartRepo
     * @param PaymentRepository $paymentRepo
     * @param NotificationRepository $notificationRepo
     * @param UserRepository $userRepository
     */
    public function __construct(OrderRepository $orderRepo, FoodOrderRepository $foodOrderRepository, CartRepository $cartRepo, PaymentRepository $paymentRepo, NotificationRepository $notificationRepo, UserRepository $userRepository, OrderStatusRepository $orderStatusRepository, CouponRepository $couponRepository, ExtraRepository $extraRepo)
    {
        parent::__construct();
        $this->orderRepository = $orderRepo;
        $this->foodOrderRepository = $foodOrderRepository;
        $this->cartRepository = $cartRepo;
        $this->userRepository = $userRepository;
        $this->paymentRepository = $paymentRepo;
        $this->notificationRepository = $notificationRepo;
        $this->orderStatusRepository = $orderStatusRepository;
        $this->couponRepository = $couponRepository;
        $this->extraRepository = $extraRepo;
        $this->order = new Order();
        $this->coupon = new Coupon();

        $this->__init();
    }

    abstract public function __init();

    protected function createOrder()
    {
        if (isset($this->order->payment->status)) {
            $this->calculateTotal();
            $this->order->order_status_id = 1;
            try {
                $orders = (collect($this->order))->only('user_id', 'order_status_id', 'tax', 'delivery_address_id', 'delivery_fee', 'note', 'sconto', 'orario', 'importo')->toArray();
                $order = $this->orderRepository->create(
                    array_merge(
                        ['ora_ritiro' => $orders["orario"]],
                        $orders
                    )
                );
                //$order = $this->orderRepository->create($orders);
                $this->order->id = $order->id;
                $this->syncFoods();
                $payment = $this->createPayment();
                $this->cartRepository->deleteWhere(['user_id' => $this->order->user_id]);
                $this->orderRepository->update(['payment_id' => $payment->id], $this->order->id);
            } catch (ValidatorException $e) {
                Log::error($e->getMessage());
            }
            $this->sendNotificationToManagers();
        }
    }

    /**
     * @return float
     */
    protected function calculateTotal(): float
    {
        $carts = $this->order->user->cart;
        $this->order->tax = 0;
        foreach ($carts as $_cart) {
            $price = $_cart->food->applyCoupon($this->coupon);
            foreach ($_cart->extras as $option) {
                $price += $option->price;
            }

            $this->total += $price * $_cart->quantity;
            $this->order->tax += $price * $_cart->quantity * $_cart->food->vat / 100;
        }
        $this->subtotal = $this->total;
        //$this->calculateTaxFee();
        $this->total += $this->order->tax;
        if ($this->order->delivery_fee > 0) {
            $this->total += $this->order->delivery_fee;
        } else {
            $this->calculateDeliveryFee();
        }
        $this->total -= $this->order->sconto;

        $this->total = round($this->total, 2);
        return $this->total;
    }

    /**
     * calculate the total of order with delivery fee
     */
    protected function calculateDeliveryFee(): void
    {
        try {
            $carts = $this->order->user->cart;
            $this->order->delivery_fee = $carts[0]->food->restaurant->delivery_fee;
            $this->total += $this->order->delivery_fee;
        } catch (Exception $exception) {
            Log::error($exception->getMessage());
        }
    }

    /**
     * calculate the total of the order with the tax fee
     */
    protected function calculateTaxFee(): void
    {
        try {
            $carts = $this->order->user->cart;
            if (empty($carts[0]->food->restaurant->default_tax)) {
                $this->order->tax = $this->total * setting('default_tax', 0) / 100;
            } else {
                $this->order->tax = $this->total * $carts[0]->food->restaurant->default_tax / 100;
            }
            $this->total += $this->order->tax;
        } catch (Exception $exception) {
            Log::error($exception->getMessage());
        }
    }

    protected function syncFoods()
    {

        /*foreach ($this->order->user->cart as $cart) {
            $foods = [
                'order_id' => $this->order->id,
                'food_id' => $cart->food_id,
                'price' => $cart->food->applyCoupon($this->coupon),
                'quantity' => $cart->quantity,
                'options' => $cart->extras->pluck('id')->toArray(),
            ];
            try {
                $this->foodOrderRepository->create($foods);
            } catch (ValidatorException $e) {
            }

        }*/
        foreach ($this->order->user->cart as $foodOrder) {
            $foodOrder['order_id'] = $this->order->id;
            $price = $foodOrder->food->applyCoupon($this->coupon);
            foreach ($foodOrder->extras->pluck('id')->toArray() as $extraId) {
                $extra = $this->extraRepository->findWithoutFail($extraId);
                $price += $extra->price;
            }

            //$total = $price * $foodOrder->quantity;
            //$total+=$price * $_cart->quantity * $_cart->food->vat/100;

            $foods = [
                'order_id' => $this->order->id,
                'food_id' => $foodOrder->food_id,
                'price' => $price,
                'quantity' => $foodOrder->quantity,
                'extras' => $foodOrder->extras->pluck('id')->toArray(),
            ];
            // $total += $foodOrder['price'] * $foodOrder['quantity'];
            $this->foodOrderRepository->create($foods);
        }
    }

    /**
     * @return mixed
     * @throws ValidatorException
     */
    protected function createPayment()
    {

        $payment = $this->paymentRepository->create([
            "user_id" => $this->order->user_id,
            "description" => $this->order->payment->description ?? trans("lang.payment_order_done"),
            "price" => $this->order->payment->price,
            "status" => $this->order->payment->status,
            "method" => $this->order->payment->method,
        ]);

        return $payment;
    }

    protected function sendNotificationToManagers()
    {
        try {
            $this->userRepository->pushCriteria(new AdminsCriteria());
            $admins = $this->userRepository->all();

            Notification::send($this->order->user->cart[0]->food->restaurant->users->merge($admins), new NewOrder($this->order));
        } catch (\Exception $e) {
            Notification::send($this->order->user->cart[0]->food->restaurant->users, new NewOrder($this->order));
        }
    }

    protected function getOrderId()
    {
        $order = $this->orderRepository->orderBy('id', 'DESC')->first();
        return $order->id + 1;
    }
}