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.

585 lines
19KB

  1. <?php
  2. namespace Lc\CaracoleBundle\Repository\Order;
  3. use Doctrine\ORM\EntityManagerInterface;
  4. use Lc\CaracoleBundle\Builder\File\DocumentBuilder;
  5. use Lc\CaracoleBundle\Model\Order\OrderShopInterface;
  6. use Lc\CaracoleBundle\Model\Order\OrderStatusModel;
  7. use Lc\CaracoleBundle\Model\Reduction\ReductionCartInterface;
  8. use Lc\CaracoleBundle\Model\Reduction\ReductionCreditInterface;
  9. use Lc\CaracoleBundle\Model\Reduction\ReductionCreditModel;
  10. use Lc\CaracoleBundle\Repository\Merchant\MerchantStore;
  11. use Lc\CaracoleBundle\Repository\Reduction\ReductionCreditStore;
  12. use Lc\CaracoleBundle\Repository\Section\SectionStore;
  13. use Lc\CaracoleBundle\Resolver\OpeningResolver;
  14. use Lc\CaracoleBundle\Repository\SectionStoreTrait;
  15. use Lc\CaracoleBundle\Solver\Order\OrderShopSolver;
  16. use Lc\CaracoleBundle\Solver\Price\PriceSolver;
  17. use Lc\CaracoleBundle\Solver\Reduction\ReductionCartSolver;
  18. use Lc\SovBundle\Model\User\UserInterface;
  19. use Lc\SovBundle\Repository\AbstractStore;
  20. use Lc\SovBundle\Repository\RepositoryQueryInterface;
  21. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  22. use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
  23. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  24. class OrderShopStore extends AbstractStore
  25. {
  26. use SectionStoreTrait;
  27. protected OrderShopRepositoryQuery $query;
  28. protected EntityManagerInterface $entityManager;
  29. protected PriceSolver $priceSolver;
  30. protected DocumentBuilder $documentBuilder;
  31. protected ReductionCreditStore $reductionCreditStore;
  32. protected ReductionCartSolver $reductionCartSolver;
  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. protected OrderShopSolver $orderShopSolver;
  41. public function __construct(
  42. OrderShopRepositoryQuery $query,
  43. EntityManagerInterface $entityManager,
  44. PriceSolver $priceSolver,
  45. DocumentBuilder $documentBuilder,
  46. ReductionCreditStore $reductionCreditStore,
  47. ReductionCartSolver $reductionCartSolver,
  48. SectionStore $sectionStore,
  49. OrderProductStore $orderProductStore,
  50. MerchantStore $merchantStore,
  51. FlashBagInterface $flashBag,
  52. ParameterBagInterface $parameterBag,
  53. UrlGeneratorInterface $router,
  54. OrderShopSolver $orderShopSolver
  55. ) {
  56. $this->query = $query;
  57. $this->entityManager = $entityManager;
  58. $this->priceSolver = $priceSolver;
  59. $this->documentBuilder = $documentBuilder;
  60. $this->reductionCreditStore = $reductionCreditStore;
  61. $this->reductionCartSolver = $reductionCartSolver;
  62. $this->sectionStore = $sectionStore;
  63. $this->orderProductStore = $orderProductStore;
  64. $this->merchantStore = $merchantStore;
  65. $this->flashBag = $flashBag;
  66. $this->parameterBag = $parameterBag;
  67. $this->router = $router;
  68. $this->orderShopSolver = $orderShopSolver;
  69. }
  70. public function orderByDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
  71. {
  72. $query->orderBy('id');
  73. return $query;
  74. }
  75. public function filtersDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
  76. {
  77. if($this->section) {
  78. $query->filterBySection($this->section);
  79. }
  80. return $query;
  81. }
  82. public function relationsDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
  83. {
  84. $query->joinOrderProduct();
  85. return $query;
  86. }
  87. // getOrderShopsOfWeek
  88. public function getByCurrentCycle($params = [], $query = null)
  89. {
  90. return $this->getBy(
  91. array_merge(
  92. [
  93. 'cycleNumber' => $this->orderShopSolver->getCycleNumberCurrentOrder($this->section),
  94. 'isValid' => true,
  95. ],
  96. $params
  97. ),
  98. $query
  99. );
  100. }
  101. // getOrderShopsOfWeekByUser
  102. public function getByCurrentCycleAndUser(UserInterface $user = null, array $params = [], $query = null)
  103. {
  104. return $this->getByCurrentCycle(
  105. array_merge(
  106. [
  107. 'user' => $user,
  108. 'cycleNumber' => $this->orderShopSolver->getCycleNumberCurrentOrder($this->section),
  109. 'excludeComplementaryOrderShops' => true
  110. ],
  111. $params
  112. ),
  113. $query
  114. );
  115. }
  116. //public $countOrderShopsOfWeek = null;
  117. // public function countByCurrentCycle(bool $excludeComplementaryOrderShops = true, $query = null)
  118. public function countByCurrentCycle(array $params, $query = null)
  119. {
  120. return $this->countBy(
  121. [
  122. 'cycleNumber' => $this->orderShopSolver->getCycleNumberCurrentOrder($this->section),
  123. 'excludeComplementaryOrderShops' => isset($params['excludeComplementaryOrderShops']) ?? true,
  124. ],
  125. $query
  126. );
  127. // @TODO : optimisation à remettre en place
  128. /*if (is_null($this->countOrderShopsOfWeek)) {
  129. $this->countOrderShopsOfWeek = $this->getByCurrentCycle(
  130. $section,
  131. [
  132. 'count' => true,
  133. 'excludeComplementaryOrderShops' => $excludeComplementaryOrderShops
  134. ]
  135. );
  136. }
  137. return $this->countOrderShopsOfWeek;*/
  138. }
  139. // getNextWeekId
  140. public function getNextCycleId(int $cycleNumber, $query = null): int
  141. {
  142. $lastOrder = $this->getOneLastValidByCycle($cycleNumber, $query);
  143. if ($lastOrder) {
  144. return intval($lastOrder->getCycleId() + 1);
  145. } else {
  146. return 1;
  147. }
  148. }
  149. public function getNextIdValidOrder($query = null): int
  150. {
  151. $lastOrder = $this->getOneLastValid($query);
  152. if ($lastOrder) {
  153. return intval($lastOrder->getIdValidOrder() + 1);
  154. } else {
  155. return 1;
  156. }
  157. }
  158. // countValidOrderShopByUserAllMerchant
  159. public function countValidByUserAllMerchant($user, $query = null): int
  160. {
  161. return $this->countBy(
  162. [
  163. 'user' => $user,
  164. 'isValid' => true,
  165. // @TODO : à tester
  166. 'isMerchantOnline' => true,
  167. 'excludeComplementaryOrderShops' => true
  168. ],
  169. $query
  170. );
  171. }
  172. public function countValidByUser(UserInterface $user, $query = null): int
  173. {
  174. return $this->countBy(
  175. [
  176. 'user' => $user,
  177. 'isValid' => true,
  178. 'excludeComplementaryOrderShops' => true
  179. ],
  180. $query
  181. );
  182. }
  183. public function countValidByCurrentCycle($query = null): int
  184. {
  185. return $this->countBy(
  186. [
  187. 'cycleNumber' => $this->orderShopSolver->getCycleNumberCurrentOrder($this->section),
  188. 'isValid' => true,
  189. 'excludeComplementaryOrderShops' => true
  190. ],
  191. $query
  192. );
  193. }
  194. // countValidOrderWithReductionCredit
  195. public function countValidWithReductionCredit(
  196. ReductionCreditInterface $reductionCredit,
  197. UserInterface $user = null,
  198. $query = null
  199. ): int {
  200. $query = $this->createDefaultQuery($query);
  201. if ($user) {
  202. $query->filterByUser($user);
  203. }
  204. $query
  205. ->selectCount()
  206. ->filterByReductionCredit($reductionCredit)
  207. ->filterByStatus(OrderStatusModel::$statusAliasAsValid);
  208. return $query->count();
  209. }
  210. // countValidOrderWithReductionCart
  211. public function countValidWithReductionCart(
  212. ReductionCartInterface $reductionCart,
  213. $query = null
  214. ): int {
  215. $query = $this->createDefaultQuery($query);
  216. $query
  217. ->selectCount()
  218. ->filterByReductionCart($reductionCart)
  219. ->filterByStatus(OrderStatusModel::$statusAliasAsValid);
  220. return $query->count();
  221. }
  222. // countValidOrderWithReductionCartPerUser
  223. public function countValidWithReductionCartByUser(
  224. ReductionCartInterface $reductionCart,
  225. UserInterface $user,
  226. $query = null
  227. ): int {
  228. $query = $this->createDefaultQuery($query);
  229. $query
  230. ->selectCount()
  231. ->filterByUser($user)
  232. ->filterByReductionCart($reductionCart)
  233. ->filterByStatus(OrderStatusModel::$statusAliasAsValid);
  234. return $query->count();
  235. }
  236. // findCartCurrent
  237. public function getOneCartCurrent(array $params = [], $query = null): ?OrderShopInterface
  238. {
  239. $query = $this->createDefaultQuery($query);
  240. if (isset($params['user'])) {
  241. $query->filterByUser($params['user']);
  242. }
  243. if (isset($params['visitor'])) {
  244. $query->filterByVisitor($params['visitor']);
  245. }
  246. $query
  247. ->selectOrderReductionCarts()
  248. ->filterByStatus(OrderStatusModel::$statusAliasAsValid);
  249. return $query->findOne();
  250. }
  251. // findLastOrderValidOfWeek
  252. public function getOneLastValidByCycle(int $cycleNumber, $query = null): ?OrderShopInterface
  253. {
  254. $query = $this->createDefaultQuery($query);
  255. $query
  256. ->filterByCycleNumber($cycleNumber)
  257. ->filterByStatus(OrderStatusModel::$statusAliasAsValid)
  258. ->filterIsNotComplementaryOrderShop()
  259. ->orderBy('.cycleId', 'DESC');
  260. return $query->findOne();
  261. }
  262. //findLastOrderValid
  263. public function getOneLastValid($query = null): ?OrderShopInterface
  264. {
  265. $query = $this->createDefaultQuery($query);
  266. $query
  267. ->filterByStatus(OrderStatusModel::$statusAliasAsValid)
  268. ->filterIsNotComplementaryOrderShop()
  269. ->orderBy('.idValidOrder', 'DESC');
  270. return $query->findOne();
  271. }
  272. public function countBy(array $params = [], $query = null)
  273. {
  274. $query = $this->createDefaultQuery($query);
  275. $query->selectCount();
  276. $this->applyGetByFilters($params, $query);
  277. return $query->count();
  278. }
  279. public function getBy(array $params = [], $query = null): array
  280. {
  281. $query = $this->createDefaultQuery($query);
  282. $this->applyGetByFilters($params, $query);
  283. $orderShops = $query->find();
  284. if (isset($params['mergeComplementaryOrderShops'])) {
  285. foreach ($orderShops as $orderShop) {
  286. $this->orderShopSolver->mergeComplentaryOrderShops($orderShop);
  287. }
  288. }
  289. return $orderShops;
  290. }
  291. protected function applyGetByFilters(array $params, $query)
  292. {
  293. if (isset($params['isMerchantOnline'])) {
  294. $query->filterIsMerchantOnline();
  295. }
  296. if (isset($params['select'])) {
  297. $query->selectParam($params['select']);
  298. }
  299. if (isset($params['dateStart']) || isset($params['dateEnd'])) {
  300. $params['dateField'] = isset($params['dateField']) ? $params['dateField'] : 'validationDate';
  301. }
  302. if (isset($params['dateStart'])) {
  303. $query->filterByDateStart($params['dateField'], $params['dateStart']);
  304. }
  305. if (isset($params['dateEnd'])) {
  306. $query->filterByDateEnd($params['dateField'], $params['dateEnd']);
  307. }
  308. if (isset($params['cycleNumber'])) {
  309. $query->filterByCycleNumber($params['cycleNumber']);
  310. }
  311. if (isset($params['isCart'])) {
  312. $query->filterByStatus(OrderStatusModel::$statusAliasAsCart);
  313. }
  314. if (isset($params['isValid'])) {
  315. $query->filterByStatus(OrderStatusModel::$statusAliasAsValid);
  316. }
  317. if (isset($params['isWaitingDelivery'])) {
  318. $query->filterByStatus(OrderStatusModel::$statusAliasWaitingDelivery);
  319. }
  320. if (isset($params['orderStatus'])) {
  321. $query->filterByStatus($params['orderStatus']);
  322. }
  323. if (isset($params['user'])) {
  324. $query->filterByUser($params['user']);
  325. }
  326. if (isset($params['address'])) {
  327. $query->filterByAddress($params['address']);
  328. }
  329. if (isset($params['mergeComplementaryOrderShops'])) {
  330. $query
  331. ->joinComplementaryOrderShops();
  332. }
  333. if (isset($params['excludeComplementaryOrderShops']) || isset($params['mergeComplementaryOrderShops'])) {
  334. $query->filterIsNullMainOrderShop();
  335. }
  336. if (isset($params['orderBy'])) {
  337. $sort = isset($params['orderByDirection']) ? $params['orderByDirection'] : 'DESC';
  338. $query->orderBy($params['orderBy'], $sort);
  339. } else {
  340. $query->orderBy('.id', 'DESC');
  341. }
  342. if (isset($params['groupBy'])) {
  343. $query->groupBy($params['groupBy']);
  344. }
  345. return $query;
  346. }
  347. public function isReductionGiftUsed(ReductionCreditInterface $reductionGift, $query = null)
  348. {
  349. if ($this->countValidWithReductionCredit($reductionGift, null, $query)) {
  350. return true;
  351. } else {
  352. return false;
  353. }
  354. }
  355. public function isReductionCreditUsed(
  356. ReductionCreditInterface $reductionCredit,
  357. UserInterface $user = null,
  358. $query = null
  359. ) {
  360. if ($this->countValidWithReductionCredit($reductionCredit, $user, $query)) {
  361. return true;
  362. } else {
  363. return false;
  364. }
  365. }
  366. public function getReductionCreditsAvailableByUser(UserInterface $user): array
  367. {
  368. $reductionCredits = $this->reductionCreditStore->getByTypeAndUser(ReductionCreditModel::TYPE_CREDIT, $user);
  369. $reductionCreditsArray = [];
  370. foreach ($reductionCredits as $reductionCredit) {
  371. if (!$this->countValidWithReductionCredit($reductionCredit, $user)) {
  372. $reductionCreditsArray[] = $reductionCredit;
  373. }
  374. }
  375. return $reductionCreditsArray;
  376. }
  377. public function getReductionGiftsAvailableByUser($user): array
  378. {
  379. $reductionGifts = $this->reductionCreditStore->getByTypeAndUser(ReductionCreditModel::TYPE_GIFT, $user);
  380. $reductionGiftsArray = [];
  381. foreach ($reductionGifts as $reductionGift) {
  382. if (!$this->countValidWithReductionCredit($reductionGift)) {
  383. $reductionGiftsArray[] = $reductionGift;
  384. }
  385. }
  386. return $reductionGiftsArray;
  387. }
  388. // getReductionCartRemainingQuantity
  389. public function getReductionCartRemainingQuantity(ReductionCartInterface $reductionCart): float
  390. {
  391. return $reductionCart->getAvailableQuantity() - $this->countValidWithReductionCart(
  392. $reductionCart
  393. );
  394. }
  395. // getReductionCartUsedQuantityPerUser
  396. public function getReductionCartUsedQuantityByUser(
  397. ReductionCartInterface $reductionCart,
  398. UserInterface $user
  399. ): float {
  400. return $this->countValidWithReductionCartByUser($reductionCart, $user);
  401. }
  402. // getReductionCartUsedQuantity
  403. public function getReductionCartUsedQuantity(ReductionCartInterface $reductionCart): float
  404. {
  405. return $this->countValidWithReductionCart($reductionCart);
  406. }
  407. // getReductionCartRemainingQuantityPerUser
  408. public function getReductionCartRemainingQuantityByUser(
  409. ReductionCartInterface $reductionCart,
  410. UserInterface $user
  411. ): float {
  412. if ($reductionCart->getAvailableQuantityPerUser()) {
  413. return $reductionCart->getAvailableQuantityPerUser() - $this->countValidWithReductionCartByUser(
  414. $reductionCart,
  415. $user
  416. );
  417. }
  418. return false;
  419. }
  420. // findAllAvailableForUser / getReductionCartsAvailableByUser
  421. public function getReductionCartAvailableByUser(UserInterface $user, $query = null)
  422. {
  423. $query = $this->createQuery($query);
  424. $reductionCarts = $query->find();
  425. $reductionCartsArray = [];
  426. foreach ($reductionCarts as $reductionCart) {
  427. if ($this->reductionCartSolver->matchWithUser($user)
  428. && $this->reductionCartSolver->matchWithGroupUser($user)
  429. && $this->getRemainingQuantityByUser($reductionCart, $user)
  430. && ($reductionCart->getUsers()->count() > 0 || $reductionCart->getGroupUsers()->count() > 0)) {
  431. $reductionCartsArray[] = $reductionCart;
  432. }
  433. }
  434. return $reductionCartsArray;
  435. }
  436. public function countValidOrderProductsOfCyclesByProducts(
  437. array $cycleNumbers,
  438. array $products,
  439. $query = null
  440. ): array {
  441. $query = $this->createDefaultQuery($query);
  442. $query
  443. ->filterByAlias(OrderStatusModel::$statusAliasAsValid)
  444. ->filterByCycleNumbers($cycleNumbers)
  445. ->filterByProducts($products)
  446. ->selectSum()
  447. ->groupBy('.cycleNumber, product.id');
  448. return $query->find();
  449. }
  450. public function countValidOrderProductsOfCycleByProduct(int $cycleNumber, int $productId, $query = null): ?string
  451. {
  452. $query = $this->createDefaultQuery($query);
  453. $query
  454. ->filterByAlias(OrderStatusModel::$statusAliasAsValid)
  455. ->filterByCycleNumber($cycleNumber)
  456. ->filterByProduct($productId)
  457. ->selectSumQuantityOrder()
  458. ->groupBy('.cycleNumber, product.id');
  459. $result = $query->findOne();
  460. if ($result) {
  461. return $result['quantity'];
  462. }
  463. return null;
  464. }
  465. public function isReductionCreditAllowAddToOrder(
  466. OrderShopInterface $orderShop,
  467. ReductionCreditInterface $reductionCredit
  468. ) {
  469. $user = $orderShop->getUser();
  470. // appartient à l'utilisateur
  471. if (!$reductionCredit->getUsers()->contains($user)) {
  472. // @TODO : déplacer la gestion du flash message
  473. //$this->flashBag->add('error', 'error.reductionCredit.userNotAllow');
  474. return false;
  475. }
  476. // n'a pas été utilisé
  477. if ($reductionCredit->getType() == ReductionCreditModel::TYPE_CREDIT) {
  478. if ($this->countValidWithReductionCredit($reductionCredit, $user) > 0) {
  479. // @TODO : déplacer la gestion du flash message
  480. //$this->flashBah->add('error', 'error.reductionCredit.alreadyUse');
  481. return false;
  482. }
  483. } else {
  484. if ($this->countValidWithReductionCredit($reductionCredit) > 0) {
  485. // @TODO : déplacer la gestion du flash message
  486. //$this->flashBah->add('error', 'error.reductionCredit.alreadyUse');
  487. return false;
  488. }
  489. }
  490. return true;
  491. }
  492. }