<?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;
}
}