<?php
namespace App\Controller;
use App\Entity\Item;
use App\Entity\Order;
use App\Entity\OrderElement;
use App\Entity\Supplier;
use App\Entity\SupplierWarehouseItem;
use App\Repository\ItemRepository;
use App\Repository\OrderElementRepository;
use App\Repository\OrderRepository;
use App\Repository\PaymentOrderElementRepository;
use App\Repository\PaymentOrderRepository;
use App\Repository\ProductRepository;
use App\Repository\SupplierRepository;
use App\Repository\SupplierWarehouseItemRepository;
use App\Repository\UserRepository;
use App\Repository\WarehouseRepository;
use App\Service\CreateOrder;
use App\Service\DTO\OldCRMOrderElementRequest;
use App\Service\DTO\OldCRMOrderRequest;
use App\Service\DTO\OrderDTO;
use App\Service\Helper\RequestHelper;
use App\Service\Order\OrderCollect;
use App\Service\Order\OrderConfirm;
use App\Service\Order\OrderIssue;
use App\Service\Order\Payment;
use App\Service\OrderElement\OrderElementCreator;
use App\Service\OrderElement\OrderProductCreator;
use App\Service\Product\ProductCreator;
use App\Service\Sberbank;
use App\Service\UserFind;
use DateTime;
use Doctrine\ORM\ORMException;
use Exception;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
/**
* @Route("/order")
*/
class OrderController extends BaseController
{
/**
* @Route("/public_list", methods="GET")
* @throws ORMException
*/
public function publicList(Request $request, OrderRepository $orderRepository, UserFind $userFind, OrderDTO $orderDTO): JsonResponse
{
$user = $userFind->executeFind($request->cookies->get('user'));
if(!$user) return new JsonResponse([]);
return new JsonResponse($orderDTO->getPublicList($orderRepository->findBy(['user' => $user])));
}
/**
* @Route("/list", methods="GET")
* @throws Exception
*/
public function list(Request $request, OrderRepository $orderRepository): JsonResponse
{
$from = new DateTime($request->query->get('from'));
$to = new DateTime($request->query->get('to'));
return new JsonResponse(OrderDTO::getOrdersList(...$orderRepository->getList($from, $to)));
}
/**
* @Route("/payments", methods="GET")
* @throws Exception
*/
public function payments(Request $request, PaymentOrderRepository $paymentOrderRepository, UserRepository $userRepository): JsonResponse
{
$from = new DateTime($request->query->get('from'));
$to = new DateTime($request->query->get('to'));
$user = $userRepository->find($request->query->getInt('queryUserId'));
return new JsonResponse(OrderDTO::getOrdersPaymentsList(...$paymentOrderRepository->getList($from, $to, $user)));
}
/**
* @Route("/payments_elements", methods="GET")
* @throws Exception
*/
public function paymentsElements(Request $request, PaymentOrderElementRepository $paymentOrderElementRepository, UserRepository $userRepository): JsonResponse
{
$from = new DateTime($request->query->get('from'));
$to = new DateTime($request->query->get('to'));
$user = $userRepository->find($request->query->getInt('queryUserId'));
return new JsonResponse(OrderDTO::getOrdersElementsPaymentsList(...$paymentOrderElementRepository->getList($from, $to, $user)));
}
/**
* @Route("/{hash}", methods="GET")
*/
public function order(Request $request, string $hash, OrderRepository $orderRepository, UserFind $userFind, OrderDTO $orderDTO): JsonResponse
{
/** @var Order $order */
$order = $orderRepository->findOneBy(['hash' => $hash]);
if(!$order) return new JsonResponse([]);
return new JsonResponse($orderDTO->getPublic($order));
}
/**
* @Route("/{order}/sberbank_payed_form", methods="GET")
* @throws ORMException
*/
public function sberbankPayedForm(Request $request, Order $order, Sberbank $sberbank): JsonResponse
{
return new JsonResponse($sberbank->getPayedForm($order));
}
/**
* @Route("/add", methods="POST")
* @throws Exception
*/
public function add(Request $request, OrderRepository $orderRepository): JsonResponse
{
$order = $orderRepository->addOrder(null, $this->findUserByCookie($request->cookies->get('user')));
return new JsonResponse(['id' => $order->getId(), 'result' => 'success']);
}
/**
* @Route("/{order}/data", methods="GET")
* @throws Exception
*/
public function getData(Order $order): JsonResponse
{
return new JsonResponse(OrderDTO::getOrderData($order));
}
/**
* @Route("/{order}/products", methods="GET")
* @throws Exception
*/
public function products(Order $order): JsonResponse
{
return new JsonResponse(OrderDTO::getOrderProducts($order));
}
/**
* @Route("/create_from_crm", methods="POST")
* @throws Exception
*/
public function createFromCrm(
Request $request,
ItemRepository $itemRepository,
OrderRepository $orderRepository,
UserRepository $userRepository,
WarehouseRepository $warehouseRepository,
OrderElementCreator $orderElementCreator,
OrderConfirm $orderConfirmService,
OrderCollect $orderCollectService,
OrderIssue $orderIssueService
): JsonResponse
{
$crmOrderId = $request->request->getInt('crmOrderId');
if($order = $orderRepository->findOneBy(['crmOrderId' => $crmOrderId]))
return new JsonResponse(['id' => $order->getId(), 'result' => 'success']);
$order = $orderRepository->addOrder($crmOrderId, $userRepository->findOneBy(['deprecatedUserId' => $request->request->get('userId')]));
foreach ($request->request->get('products') as $product) {
$warehouse = $warehouseRepository->findOneBy(['alias' => 'sklad']);
$item = $itemRepository->findOneBy(['warehouse' => $warehouse, 'product' => (int)$product['productId']]);
if(!$item) continue;
$orderElementCreator->createOrderElement(
$order,
$item,
null,
(int)$product['quantity'],
(int)$product['price'] * 100,
);
}
$orderConfirmService->confirmOrder($order);
$orderCollectService->collectOrder($order);
$orderIssueService->issueOrder($order);
return new JsonResponse(['id' => $order->getId(), 'result' => 'success']);
}
/**
* @Route("/payment_from_old_crm", methods="POST")
* @throws Exception
* @throws TransportExceptionInterface
*/
public function paymentFromOldCrm(
Request $request,
ItemRepository $itemRepository,
OrderElementRepository $orderElementRepository,
PaymentOrderRepository $paymentOrderRepository,
SupplierRepository $supplierRepository,
SupplierWarehouseItemRepository $supplierWarehouseItemRepository,
UserRepository $userRepository,
WarehouseRepository $warehouseRepository,
CreateOrder $createOrderService,
OrderElementCreator $orderElementCreator,
Payment $paymentService,
ProductCreator $productCreator
): JsonResponse
{
$orderElements = [];
$oldCrmRequest = new OldCRMOrderRequest($request);
$order = $createOrderService->createFromOldCrm($oldCrmRequest);
$existsElements = [];
foreach ($order->getElements() as $orderElement) {
if($orderElement->getCrmSpareId()) $existsElements[$orderElement->getCrmSpareId()] = $orderElement;
}
foreach ($oldCrmRequest->getElements() as $element) {
if(array_key_exists($element->getElementId(), $existsElements)) {
$orderElements[] = $existsElements[$element->getElementId()];
continue;
}
$supplierAlias = $element->getSupplierAlias();
$product = $productCreator->createProduct($element->getBrand(), $element->getArticle(), $element->getDescription());
$item = null;
$supplierWarehouseItem = null;
if($supplierAlias === 'sklad' && $product) {
$warehouse = $warehouseRepository->findOneBy(['alias' => 'sklad']);
$item = $itemRepository->findOneBy(['warehouse' => $warehouse, 'product' => $product]);
$item = $item ?: $itemRepository->addItem($warehouse, $product);
}
if(!$item) {
/** @var Supplier $supplier */
$supplier = $supplierRepository->findOneBy(['alias' => $supplierAlias]);
$warehouse = $supplier->getWarehouses()->first();
/** @var SupplierWarehouseItem $supplierWarehouseItem */
$supplierWarehouseItem = $supplierWarehouseItemRepository->findItemByWarehouseAndProduct($product, $warehouse);
if (!$supplierWarehouseItem) {
$supplierWarehouseItem = $supplierWarehouseItemRepository->addSupplierWarehouseItem($warehouse, $product);
}
}
$searcherUser = $userRepository->findOneBy(['deprecatedUserId' => $element->getSearcherUserId()]);
$orderElement = $orderElementCreator->createOrderElement(
$order,
$item,
$supplierWarehouseItem,
$element->getQuantity(),
$element->getPrice() * 100,
);
if($orderElement) {
$orderElementRepository->update($orderElement->setCrmSpareId($element->getElementId()));
if($searcherUser) $orderElementRepository->update($orderElement->setSearcherUser($searcherUser));
$orderElements[] = $orderElement;
}
}
$amount = $request->request->getInt('amount') / 100;
$remainingAmount = abs($amount);
$paymentOrder = $paymentOrderRepository->addOrder($order, $amount, $request->request->get( 'paymentType'));
foreach ($orderElements as $orderElement) {
if($remainingAmount <= 0) continue;
$remainingAmount = $amount > 0
? $paymentService->addOrderElementHistory($paymentOrder, $orderElement, $remainingAmount)
: $paymentService->removeOrderElementHistory($paymentOrder, $orderElement, $remainingAmount);
}
return new JsonResponse(['id' => $order->getId(), 'result' => 'success']);
}
/**
* @Route("/{order}/add_item/{item}", methods="POST")
* @throws Exception
*/
public function addItem(
Request $request,
Order $order,
Item $item,
OrderElementCreator $orderElementCreator
): JsonResponse
{
$orderElementCreator->createOrderElement(
$order,
$item,
null,
$request->request->getInt('quantity', 1),
$item->getPrice(),
);
return new JsonResponse(['result' => 'success']);
}
/**
* @Route("/{order}/confirm", methods="POST")
* @throws Exception
*/
public function confirmOrder(Order $order, OrderConfirm $orderConfirm): JsonResponse
{
$orderConfirm->confirmOrder($order);
return new JsonResponse(['result' => 'success']);
}
/**
* @Route("/payments/chart_data", methods="GET")
* @throws Exception
*/
public function paymentsChartData(
Request $request,
PaymentOrderElementRepository $paymentOrderElementRepository,
UserRepository $userRepository
): JsonResponse
{
$queryUser = $userRepository->find($request->query->getInt('queryUserId'));
$out = [];
$users = [];
$amounts = [];
foreach ($userRepository->findManagers() as $user) {
if(!$user->getManager()) continue;
$users[] = $user;
$amounts[$user->getManager()->getFirstName()] = 0;
}
foreach ($paymentOrderElementRepository->getList(new DateTime($request->query->get('from')), new DateTime($request->query->get('to')), $queryUser) as $paymentOrderElement) {
$date = $paymentOrderElement->getCreatedAt()->format('d.m.y');
if(!isset($out[$date])) $out[$date] = ['name' => $date];
foreach ($users as $user) {
if(!isset($out[$date][$user->getManager()->getFirstName()])) $out[$date][$user->getManager()->getFirstName()] = 0;
if($paymentOrderElement->getOrderElement()->getSearcherUser() === $user) {
$out[$date][$user->getManager()->getFirstName()] += $paymentOrderElement->getPrice() / 100;
$amounts[$user->getManager()->getFirstName()] += $paymentOrderElement->getPrice() / 100;
}
}
}
return new JsonResponse(['amounts' => $amounts, 'chart' => array_values($out)]);
}
}