You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

622 line
21KB

  1. <?php
  2. namespace Lc\CaracoleBundle\Repository\Order;
  3. use App\Entity\Delivery\DeliveryAvailabilityPointSale;
  4. use App\Entity\Delivery\DeliveryAvailabilityZone;
  5. use App\Entity\Order\OrderStatus;
  6. use App\Entity\Section\Section;
  7. use Doctrine\ORM\EntityManagerInterface;
  8. use Lc\CaracoleBundle\Builder\File\DocumentBuilder;
  9. use Lc\CaracoleBundle\Model\Merchant\MerchantInterface;
  10. use Lc\CaracoleBundle\Model\Order\OrderReductionCartInterface;
  11. use Lc\CaracoleBundle\Model\Order\OrderReductionCreditInterface;
  12. use Lc\CaracoleBundle\Model\Order\OrderShopInterface;
  13. use Lc\CaracoleBundle\Model\Section\SectionInterface;
  14. use Lc\CaracoleBundle\Repository\Merchant\MerchantStore;
  15. use Lc\CaracoleBundle\Repository\Reduction\ReductionCreditStore;
  16. use Lc\CaracoleBundle\Repository\Section\SectionStore;
  17. use Lc\CaracoleBundle\Resolver\OpeningResolver;
  18. use Lc\CaracoleBundle\Repository\SectionStoreTrait;
  19. use Lc\CaracoleBundle\Resolver\Price\PriceResolver;
  20. use Lc\SovBundle\Model\User\UserInterface;
  21. use Lc\SovBundle\Repository\AbstractStore;
  22. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  23. use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
  24. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  25. class OrderShopStore extends AbstractStore
  26. {
  27. use SectionStoreTrait;
  28. protected OrderShopRepositoryQuery $query;
  29. protected EntityManagerInterface $entityManager;
  30. protected PriceResolver $priceResolver;
  31. protected DocumentBuilder $documentBuilder;
  32. protected ReductionCreditStore $reductionCreditStore;
  33. protected SectionStore $sectionStore;
  34. protected OrderProductStore $orderProductStore;
  35. protected MerchantStore $merchantStore;
  36. protected FlashBagInterface $flashBag;
  37. protected OpeningResolver $openingResolver;
  38. protected ParameterBagInterface $parameterBag;
  39. protected UrlGeneratorInterface $router;
  40. public function __construct(
  41. OrderShopRepositoryQuery $query,
  42. EntityManagerInterface $entityManager,
  43. PriceResolver $priceResolver,
  44. DocumentBuilder $documentBuilder,
  45. ReductionCreditStore $reductionCreditStore,
  46. SectionStore $sectionStore,
  47. OrderProductStore $orderProductStore,
  48. MerchantStore $merchantStore,
  49. FlashBagInterface $flashBag,
  50. OpeningResolver $openingResolver,
  51. ParameterBagInterface $parameterBag,
  52. UrlGeneratorInterface $router
  53. ) {
  54. $this->query = $query;
  55. $this->entityManager = $entityManager;
  56. $this->priceResolver = $priceResolver;
  57. $this->documentBuilder = $documentBuilder;
  58. $this->reductionCreditStore = $reductionCreditStore;
  59. $this->sectionStore = $sectionStore;
  60. $this->orderProductStore = $orderProductStore;
  61. $this->merchantStore = $merchantStore;
  62. $this->flashBag = $flashBag;
  63. $this->openingResolver = $openingResolver;
  64. $this->parameterBag = $parameterBag;
  65. $this->router = $router;
  66. }
  67. // getOrderShopsOfWeek
  68. public function getByCycle(SectionInterface $section, $params = [])
  69. {
  70. $orderShops = $this->getBy(
  71. array_merge(
  72. [
  73. 'section' => $section,
  74. 'cycleNumber' => $this->getCycleNumberCurrentOrder($section),
  75. 'isValid' => true,
  76. ],
  77. $params
  78. )
  79. );
  80. return $orderShops;
  81. }
  82. // getOrderShopsOfWeekByUser
  83. public function getByCycleAndUser(SectionInterface $section, UserInterface $user, array $params = [])
  84. {
  85. return $this->getByCycle(
  86. $section,
  87. array_merge(
  88. [
  89. 'user' => $user,
  90. 'weekNumber' => $this->getCycleNumberCurrentOrder($section),
  91. 'excludeComplementaryOrderShops' => true
  92. ],
  93. $params
  94. )
  95. );
  96. }
  97. //public $countOrderShopsOfWeek = null;
  98. public function countByCycle(SectionInterface $section, bool $excludeComplementaryOrderShops = true)
  99. {
  100. return $this->getByCycle(
  101. $section,
  102. [
  103. 'count' => true,
  104. 'excludeComplementaryOrderShops' => $excludeComplementaryOrderShops
  105. ]
  106. );
  107. // @TODO : optimisation à remettre en place
  108. /*if (is_null($this->countOrderShopsOfWeek)) {
  109. $this->countOrderShopsOfWeek = $this->getByCycle(
  110. $section,
  111. [
  112. 'count' => true,
  113. 'excludeComplementaryOrderShops' => $excludeComplementaryOrderShops
  114. ]
  115. );
  116. }
  117. return $this->countOrderShopsOfWeek;*/
  118. }
  119. // getNextWeekId
  120. public function getNextCycleId(SectionInterface $section, int $cycleNumber): int
  121. {
  122. $lastOrder = $this->getOneLastOrderValidOfCycle($section, $cycleNumber);
  123. if ($lastOrder) {
  124. return intval($lastOrder->getCycleId() + 1);
  125. } else {
  126. return 1;
  127. }
  128. }
  129. public function getNextIdValidOrder(Section $section)
  130. {
  131. $lastOrder = $this->getOneLastOrderValid($section);
  132. if ($lastOrder) {
  133. return intval($lastOrder->getIdValidOrder() + 1);
  134. } else {
  135. return 1;
  136. }
  137. }
  138. // getOrderDatas
  139. public function getDatas(OrderShopInterface $orderShop, UserInterface $user = null): array
  140. {
  141. $data = [];
  142. $data['order'] = $orderShop;
  143. if ($orderShop) {
  144. $data['count'] = $orderShop->countQuantities();
  145. $data['total_with_tax'] = $this->priceResolver->getTotalWithTax($orderShop);
  146. $data['order_products_by_category'] = $orderShop->getOrderProductsByParentCategory();
  147. $data['total_remaining_to_be_paid'] = $this->getTotalRemainingToBePaid($orderShop);
  148. }
  149. return $data;
  150. }
  151. public function getAsJsonObject(OrderShopInterface $orderShop): array
  152. {
  153. $data['id'] = $orderShop->getId();
  154. $data['user'] = $orderShop->getUser()->getSummary();
  155. $data['orderStatus'] = $orderShop->getOrderStatus()->__toString();
  156. $data['deliveryAddress'] = $orderShop->getDeliveryAddress()->getSummary();
  157. $data['invoiceAddress'] = $orderShop->getInvoiceAddress()->getSummary();
  158. $data['total'] = $this->priceResolver->getTotal($orderShop);
  159. $data['totalWithTax'] = $this->priceResolver->getTotalWithTax($orderShop);
  160. $data['totalWithTaxAndReduction'] = $this->priceResolver->getTotalWithTax($orderShop);
  161. $i = 0;
  162. foreach ($orderShop->getOrderProductsByParentCategory() as $labelCategory => $orderProducts) {
  163. foreach ($orderProducts as $orderProduct) {
  164. $data['orderProducts'][$i]['id'] = $orderProduct->getId();
  165. $data['orderProducts'][$i]['product'] = $orderProduct->getProduct()->getId();
  166. $data['orderProducts'][$i]['quantityOrder'] = $orderProduct->getQuantityOrder();
  167. $data['orderProducts'][$i]['labelCategory'] = $labelCategory;
  168. $data['orderProducts'][$i]['title'] = $orderProduct->getTitle();
  169. $data['orderProducts'][$i]['price'] = $this->priceResolver->getPrice($orderProduct);
  170. $data['orderProducts'][$i]['priceWithTax'] = $this->priceResolver->getPriceWithTax($orderProduct);
  171. $data['orderProducts'][$i]['priceWithTaxAndReduction'] = $this->priceResolver->getPriceWithTaxAndReduction(
  172. $orderProduct
  173. );
  174. $data['orderProducts'][$i]['quantity'] = $orderProduct->getQuantityOrder();
  175. $data['orderProducts'][$i]['totalWithTaxAndReduction'] = $this->priceResolver->getTotalOrderProductsWithTaxAndReduction(
  176. array($orderProduct)
  177. );
  178. $i++;
  179. }
  180. }
  181. return $data;
  182. }
  183. public function groupOrderProductsByProductFamily(array $orderProducts): array
  184. {
  185. $orderProductsByProductFamily = [];
  186. foreach ($orderProducts as $orderProduct) {
  187. if ($orderProduct->getProduct() && $orderProduct->getProduct()->getProductFamily()) {
  188. $productFamily = $orderProduct->getProduct()->getProductFamily();
  189. if (!isset($orderProductsByProductFamily[$productFamily->getId()])) {
  190. $orderProductsByProductFamily[$productFamily->getId()] = [
  191. 'order_products' => [],
  192. 'total_quantity_weight' => 0,
  193. ];
  194. }
  195. $orderProductsByProductFamily[$productFamily->getId()]['order_products'][] = $orderProduct;
  196. $orderProductsByProductFamily[$productFamily->getId(
  197. )]['total_quantity_weight'] += ($orderProduct->getQuantityProduct() / $orderProduct->getUnit(
  198. )->getCoefficient()) * $orderProduct->getQuantityOrder();
  199. }
  200. }
  201. return $orderProductsByProductFamily;
  202. }
  203. // isOrderShopPositiveAmount
  204. public function isPositiveAmount(OrderShopInterface $orderShop)
  205. {
  206. return $this->priceResolver->getTotalWithTax($orderShop) >= 0;
  207. }
  208. public function isPaid(OrderShopInterface $orderShop, $mergeComplementaryOrderShop = false)
  209. {
  210. $totalOrderPayments = $this->getTotalOrderPayments($orderShop, $mergeComplementaryOrderShop);
  211. $totalOrder = $this->priceResolver->getTotalWithTax($orderShop);
  212. if ((abs($totalOrderPayments - $totalOrder) < 0.00001
  213. || $totalOrderPayments >= $totalOrder)
  214. && $totalOrder > 0) {
  215. return true;
  216. } else {
  217. return false;
  218. }
  219. }
  220. public function getTotalOrderPayments(OrderShopInterface $orderShop, $mergeComplementaryOrderShop = false): float
  221. {
  222. $totalAmount = floatval(0);
  223. foreach ($orderShop->getOrderPayments() as $orderPayment) {
  224. $totalAmount = $orderPayment->getAmount() + $totalAmount;
  225. }
  226. if ($mergeComplementaryOrderShop) {
  227. foreach ($orderShop->getComplementaryOrderShops() as $complementaryOrderShop) {
  228. foreach ($complementaryOrderShop->getOrderPayments() as $orderPayment) {
  229. $totalAmount = $orderPayment->getAmount() + $totalAmount;
  230. }
  231. }
  232. }
  233. return $totalAmount;
  234. }
  235. public
  236. function getTotalRemainingToBePaid(
  237. OrderShopInterface $orderShop
  238. ): float {
  239. return $this->priceResolver->getTotalWithTax($orderShop) - $this->getTotalOrderPayments($orderShop);
  240. }
  241. // isOrderShopPositiveAmountRemainingToBePaid
  242. public function isPositiveAmountRemainingToBePaid(OrderShopInterface $orderShop): bool
  243. {
  244. return $this->getTotalRemainingToBePaid($orderShop) > 0;
  245. }
  246. public function getCartByUserOrCreateIt($user)
  247. {
  248. $newOrderShop = $this->em->getRepository(OrderShopInterface::class)->findCartCurrent(['user' => $user]);
  249. if ($newOrderShop === null) {
  250. $newOrderShop = $this->createOrderShop(
  251. array(
  252. 'user' => $user,
  253. 'merchant' => $this->merchantUtils->getMerchantUser()
  254. )
  255. );
  256. }
  257. return $newOrderShop;
  258. }
  259. public function isCartAllowToBeOrder(OrderShopInterface $orderShop)
  260. {
  261. return true;
  262. }
  263. // countValidOrderShopByUserAllMerchant
  264. public function countValidByUserAllMerchant($user)
  265. {
  266. $totalOrder = 0;
  267. foreach ($this->merchantStore->getRepositoryQuery()->findAll() as $merchant) {
  268. $totalOrder += $this->countValidByUser($user, $merchant);
  269. }
  270. return $totalOrder;
  271. }
  272. public function countValidByUser(UserInterface $user, MerchantInterface $merchant = null)
  273. {
  274. return $this->getBy(
  275. [
  276. 'user' => $user,
  277. 'isValid' => true,
  278. 'merchant' => $merchant,
  279. 'excludeComplementaryOrderShops' => true,
  280. 'count' => true
  281. ]
  282. );
  283. }
  284. /*
  285. public function getCartCurrent(SectionInterface $section, UserInterface $user = null, VisitorInterface $visitor = null)
  286. {
  287. $paramsSearchOrderShop = [];
  288. $user = $this->security->getUser();
  289. $visitor = $this->userUtils->getVisitorCurrent();
  290. $orderShop = null;
  291. $orderShopUser = null;
  292. $orderShopVisitor = null;
  293. if ($user) {
  294. $orderShopUser = $this->orderShopRepo->findCartCurrent(
  295. [
  296. 'user' => $user
  297. ]
  298. );
  299. }
  300. if ($visitor) {
  301. $orderShopVisitor = $this->orderShopRepo->findCartCurrent(
  302. [
  303. 'visitor' => $visitor
  304. ]
  305. );
  306. }
  307. if ($orderShopUser || $orderShopVisitor) {
  308. // merge
  309. if ($orderShopUser && $orderShopVisitor && $orderShopUser != $orderShopVisitor
  310. && $orderShopVisitor->getOrderProducts() && count($orderShopVisitor->getOrderProducts())
  311. && $orderShopUser->getOrderStatus()->getAlias() == OrderStatus::ALIAS_CART) {
  312. $orderShop = $this->mergeOrderShops($orderShopUser, $orderShopVisitor);
  313. $this->utils->addFlash(
  314. 'success',
  315. "Votre panier visiteur vient d'être fusionné avec votre panier client."
  316. );
  317. } else {
  318. $orderShop = ($orderShopUser) ? $orderShopUser : $orderShopVisitor;
  319. }
  320. // set user
  321. if ($orderShop && $user && !$orderShop->getUser()) {
  322. $orderShop->setUser($user);
  323. $orderShop->setVisitor(null);
  324. $this->em->persist($orderShop);
  325. $this->em->flush();
  326. }
  327. }
  328. return $orderShop;
  329. }*/
  330. public function countValidOrderWithReductionCredit(
  331. OrderReductionCreditInterface $reductionCredit,
  332. UserInterface $user = null
  333. ): string {
  334. $query = $this->query->create();
  335. if ($user) {
  336. $query->filterByUser($user);
  337. }
  338. $query
  339. ->selectCount()
  340. ->filterByReductionCredit($reductionCredit)
  341. ->filterByStatus(OrderStatus::$statusAliasAsValid)
  342. ->filterBySection($this->section);
  343. return $query->count();
  344. }
  345. public function countValidOrderWithReductionCart(
  346. OrderReductionCartInterface $reductionCart
  347. ): string {
  348. $query = $this->query->create();
  349. $query
  350. ->selectCount()
  351. ->filterByReductionCart($reductionCart)
  352. ->filterByStatus(OrderStatus::$statusAliasAsValid)
  353. ->filterBySection($this->section);
  354. return $query->count();
  355. }
  356. public function countValidOrderWithReductionCartPerUser(
  357. OrderReductionCartInterface $reductionCart,
  358. UserInterface $user
  359. ): string {
  360. $query = $this->query->create();
  361. $query
  362. ->selectCount()
  363. ->filterByUser($user)
  364. ->filterByReductionCart($reductionCart)
  365. ->filterByStatus(OrderStatus::$statusAliasAsValid)
  366. ->filterBySection($this->section);
  367. return $query->count();
  368. }
  369. //findCartCurrent
  370. public function getCartCurrent(array $params): ?OrderShopInterface
  371. {
  372. $query = $this->query->create();
  373. if (isset($params['user'])) {
  374. $query
  375. ->filterByUser($params['user']);
  376. }
  377. if (isset($params['visitor'])) {
  378. $query
  379. ->filterByVisitor($params['visitor']);
  380. }
  381. $query
  382. ->selectOrderReductionCarts()
  383. ->filterByStatus(OrderStatus::$statusAliasAsValid)
  384. ->filterBySection($this->section);
  385. $results = $query->find();
  386. if ($results) {
  387. return $results[0];
  388. }
  389. return null;
  390. }
  391. //findLastOrderValidOfWeek
  392. public function getOneLastOrderValidOfWeek(int $weekNumber): ?OrderShopInterface
  393. {
  394. $query = $this->query->create();
  395. $query
  396. ->filterByWeekNumber($weekNumber)
  397. ->filterByStatus(OrderStatus::$statusAliasAsValid)
  398. ->filterIsNotMainOrderShop()
  399. ->orderBy('.weekId', 'DESC')
  400. ->filterBySection($this->section);
  401. return $query->findOne();
  402. }
  403. //findLastOrderValid
  404. public function getOneLastOrderValid(): ?OrderShopInterface
  405. {
  406. $query = $this->query->create();
  407. $query
  408. ->filterByStatus(OrderStatus::$statusAliasAsValid)
  409. ->filterIsNotMainOrderShop()
  410. ->orderBy('.idValidOrder', 'DESC')
  411. ->filterBySection($this->section);
  412. return $query->findOne();
  413. }
  414. //TODO Fonction à tester
  415. // findAllBy
  416. public function getAllBy(array $params = [])
  417. {
  418. $query = $this->query->create();
  419. if (isset($params['section'])) {
  420. $query->filterBySection($params['section']);
  421. } else {
  422. $query->filterBySection($this->section);
  423. }
  424. if (isset($params['count']) && $params['count']) {
  425. $query->selectCount();
  426. } else {
  427. if (isset($params['select'])) {
  428. $query->selectParam($params['select']);
  429. }
  430. }
  431. if (isset($params['dateStart']) || isset($params['dateEnd'])) {
  432. $params['dateField'] = isset($params['dateField']) ? $params['dateField'] : 'validationDate';
  433. }
  434. if (isset($params['dateStart'])) {
  435. $query->filterByDateStart($params['dateField'], $params['dateStart']);
  436. }
  437. if (isset($params['dateEnd'])) {
  438. $query->filterByDateEnd($params['dateField'], $params['dateEnd']);
  439. }
  440. if (isset($params['weekNumber'])) {
  441. $query->filterByWeekNumber($params['weekNumber']);
  442. }
  443. if (isset($params['isCart'])) {
  444. $query->filterByStatus(OrderStatus::$statusAliasAsCart);
  445. }
  446. if (isset($params['isValid'])) {
  447. $query->filterByStatus(OrderStatus::$statusAliasAsValid);
  448. }
  449. if (isset($params['isWaitingDelivery'])) {
  450. $query->filterByStatus(OrderStatus::$statusAliasWaitingDelivery);
  451. }
  452. if (isset($params['orderStatus'])) {
  453. $query->filterByStatus($params['orderStatus']);
  454. }
  455. if (isset($params['user'])) {
  456. $query->filterByUser($params['user']);
  457. }
  458. if (isset($params['address'])) {
  459. $query->filterByAddress($params['address']);
  460. }
  461. if (isset($params['weekDeliveryTrucks'])) {
  462. $query->filterByWeekDeliveryTruck($params['weekDeliveryTrucks']);
  463. }
  464. if (isset($params['estimatedDeliveryDateTime'])) {
  465. $date = clone $params['estimatedDeliveryDateTime'];
  466. $query
  467. ->filterByEstimatedDeliveryDateStart($date->format('Y-m-d 00:00:00'))
  468. ->filterByEstimatedDeliveryDateEnd($date->modify('+1 day')->format('Y-m-d 00:00:00'));
  469. }
  470. if (isset($params['deliveryDate'])) {
  471. $date = clone $params['deliveryDate'];
  472. $query
  473. ->filterByDeliveryDateStart($date->format('Y-m-d 00:00:00'))
  474. ->filterByDeliveryDateEnd($date->modify('+1 day')->format('Y-m-d 00:00:00'));
  475. }
  476. if (isset($params['mergeComplementaryOrderShops'])) {
  477. //TODO jointure peut être pas utile
  478. $query
  479. ->joinComplementaryOrderShops();
  480. }
  481. if (isset($params['excludeComplementaryOrderShops']) || isset($params['mergeComplementaryOrderShops'])) {
  482. $query->filterIsNullMainOrderShop();
  483. }
  484. if (isset($params['isCircuit'])) {
  485. $query->filterIsNullDeliveryPointSale();
  486. }
  487. if (isset($params['isDepository'])) {
  488. $query->filterIsNotNullDeliveryPointSale();
  489. }
  490. if (isset($params['isOffCircuit'])) {
  491. $query->filterIsPointSale('devAliasHorsTournee');
  492. }
  493. if (isset($params['isGiftVoucher'])) {
  494. $query->filterIsPointSale('devAliasGiftVoucher');
  495. }
  496. if (isset($params['deliveryAvailability'])) {
  497. $deliveryAvailability = $params['deliveryAvailability'];
  498. $deliveryAvailabilityZone = ($deliveryAvailability instanceof DeliveryAvailabilityZone) ? $deliveryAvailability : false;
  499. $deliveryAvailabilityPointSale = ($deliveryAvailability instanceof DeliveryAvailabilityPointSale) ? $deliveryAvailability : false;
  500. if ($deliveryAvailabilityZone) {
  501. $query->filterByAvailabilityPointZone($deliveryAvailabilityZone);
  502. }
  503. if ($deliveryAvailabilityPointSale) {
  504. $query->filterByAvailabilityPointZone($deliveryAvailabilityPointSale);
  505. }
  506. } else {
  507. $query->joinDeliverySlotZone();
  508. $query->joinDeliverySlotPointSale();
  509. }
  510. if (isset($params['orderBy'])) {
  511. $sort = isset($params['orderByDirection']) ? $params['orderByDirection'] : 'DESC';
  512. $query->orderBy($params['orderBy'], $sort);
  513. } else {
  514. $query->orderBy('.id', 'DESC');
  515. }
  516. if (isset($params['groupBy'])) {
  517. $query->groupBy($params['groupBy']);
  518. }
  519. if (isset($params['count']) && $params['count']) {
  520. return $query->count();
  521. }
  522. return $query->find();
  523. }
  524. }