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.

OrderShopStore.php 22KB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  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 function getTotalRemainingToBePaid(OrderShopInterface $orderShop): float
  236. {
  237. return $this->priceResolver->getTotalWithTax($orderShop) - $this->getTotalOrderPayments($orderShop);
  238. }
  239. // isOrderShopPositiveAmountRemainingToBePaid
  240. public function isPositiveAmountRemainingToBePaid(OrderShopInterface $orderShop): bool
  241. {
  242. return $this->getTotalRemainingToBePaid($orderShop) > 0;
  243. }
  244. public function getCartByUserOrCreateIt($user)
  245. {
  246. $newOrderShop = $this->em->getRepository(OrderShopInterface::class)->findCartCurrent(['user' => $user]);
  247. if ($newOrderShop === null) {
  248. $newOrderShop = $this->createOrderShop(
  249. array(
  250. 'user' => $user,
  251. 'merchant' => $this->merchantUtils->getMerchantUser()
  252. )
  253. );
  254. }
  255. return $newOrderShop;
  256. }
  257. public function isCartAllowToBeOrder(OrderShopInterface $orderShop)
  258. {
  259. return true;
  260. }
  261. // countValidOrderShopByUserAllMerchant
  262. public function countValidByUserAllMerchant($user)
  263. {
  264. $totalOrder = 0;
  265. foreach ($this->merchantStore->getRepositoryQuery()->findAll() as $merchant) {
  266. $totalOrder += $this->countValidByUser($user, $merchant);
  267. }
  268. return $totalOrder;
  269. }
  270. public function countValidByUser(UserInterface $user, MerchantInterface $merchant = null)
  271. {
  272. return $this->getBy(
  273. [
  274. 'user' => $user,
  275. 'isValid' => true,
  276. 'merchant' => $merchant,
  277. 'excludeComplementaryOrderShops' => true,
  278. 'count' => true
  279. ]
  280. );
  281. }
  282. /*
  283. public function getCartCurrent(SectionInterface $section, UserInterface $user = null, VisitorInterface $visitor = null)
  284. {
  285. $paramsSearchOrderShop = [];
  286. $user = $this->security->getUser();
  287. $visitor = $this->userUtils->getVisitorCurrent();
  288. $orderShop = null;
  289. $orderShopUser = null;
  290. $orderShopVisitor = null;
  291. if ($user) {
  292. $orderShopUser = $this->orderShopRepo->findCartCurrent(
  293. [
  294. 'user' => $user
  295. ]
  296. );
  297. }
  298. if ($visitor) {
  299. $orderShopVisitor = $this->orderShopRepo->findCartCurrent(
  300. [
  301. 'visitor' => $visitor
  302. ]
  303. );
  304. }
  305. if ($orderShopUser || $orderShopVisitor) {
  306. // merge
  307. if ($orderShopUser && $orderShopVisitor && $orderShopUser != $orderShopVisitor
  308. && $orderShopVisitor->getOrderProducts() && count($orderShopVisitor->getOrderProducts())
  309. && $orderShopUser->getOrderStatus()->getAlias() == OrderStatus::ALIAS_CART) {
  310. $orderShop = $this->mergeOrderShops($orderShopUser, $orderShopVisitor);
  311. $this->utils->addFlash(
  312. 'success',
  313. "Votre panier visiteur vient d'être fusionné avec votre panier client."
  314. );
  315. } else {
  316. $orderShop = ($orderShopUser) ? $orderShopUser : $orderShopVisitor;
  317. }
  318. // set user
  319. if ($orderShop && $user && !$orderShop->getUser()) {
  320. $orderShop->setUser($user);
  321. $orderShop->setVisitor(null);
  322. $this->em->persist($orderShop);
  323. $this->em->flush();
  324. }
  325. }
  326. return $orderShop;
  327. }*/
  328. // countValidOrderWithReductionCredit
  329. public function countValidWithReductionCredit(
  330. OrderReductionCreditInterface $reductionCredit,
  331. UserInterface $user = null
  332. ): string {
  333. $query = $this->query->create();
  334. if ($user) {
  335. $query->filterByUser($user);
  336. }
  337. $query
  338. ->selectCount()
  339. ->filterByReductionCredit($reductionCredit)
  340. ->filterByStatus(OrderStatus::$statusAliasAsValid)
  341. ->filterBySection($this->section);
  342. return $query->count();
  343. }
  344. // countValidOrderWithReductionCart
  345. public function countValidWithReductionCart(
  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. // countValidOrderWithReductionCartPerUser
  357. public function countValidWithReductionCartPerUser(
  358. OrderReductionCartInterface $reductionCart,
  359. UserInterface $user
  360. ): string {
  361. $query = $this->query->create();
  362. $query
  363. ->selectCount()
  364. ->filterByUser($user)
  365. ->filterByReductionCart($reductionCart)
  366. ->filterByStatus(OrderStatus::$statusAliasAsValid)
  367. ->filterBySection($this->section);
  368. return $query->count();
  369. }
  370. // findCartCurrent
  371. public function getCartCurrent(array $params): ?OrderShopInterface
  372. {
  373. $query = $this->query->create();
  374. if (isset($params['user'])) {
  375. $query
  376. ->filterByUser($params['user']);
  377. }
  378. if (isset($params['visitor'])) {
  379. $query
  380. ->filterByVisitor($params['visitor']);
  381. }
  382. $query
  383. ->selectOrderReductionCarts()
  384. ->filterByStatus(OrderStatus::$statusAliasAsValid)
  385. ->filterBySection($this->section);
  386. $results = $query->find();
  387. if ($results) {
  388. return $results[0];
  389. }
  390. return null;
  391. }
  392. // findLastOrderValidOfWeek
  393. public function getOneLastValidOfCycle(int $cycleNumber): ?OrderShopInterface
  394. {
  395. $query = $this->query->create();
  396. $query
  397. ->filterByCycleNumber($cycleNumber)
  398. ->filterByStatus(OrderStatus::$statusAliasAsValid)
  399. ->filterIsNotMainOrderShop()
  400. ->orderBy('.weekId', 'DESC')
  401. ->filterBySection($this->section);
  402. return $query->findOne();
  403. }
  404. //findLastOrderValid
  405. public function getOneLastValid(): ?OrderShopInterface
  406. {
  407. $query = $this->query->create();
  408. $query
  409. ->filterByStatus(OrderStatus::$statusAliasAsValid)
  410. ->filterIsNotMainOrderShop()
  411. ->orderBy('.idValidOrder', 'DESC')
  412. ->filterBySection($this->section);
  413. return $query->findOne();
  414. }
  415. // @TODO : Fonction à tester
  416. // findAllBy
  417. public function getBy(array $params = [])
  418. {
  419. $query = $this->query->create();
  420. if (isset($params['section'])) {
  421. $query->filterBySection($params['section']);
  422. } else {
  423. $query->filterBySection($this->section);
  424. }
  425. if (isset($params['count']) && $params['count']) {
  426. $query->selectCount();
  427. } else {
  428. if (isset($params['select'])) {
  429. $query->selectParam($params['select']);
  430. }
  431. }
  432. if (isset($params['dateStart']) || isset($params['dateEnd'])) {
  433. $params['dateField'] = isset($params['dateField']) ? $params['dateField'] : 'validationDate';
  434. }
  435. if (isset($params['dateStart'])) {
  436. $query->filterByDateStart($params['dateField'], $params['dateStart']);
  437. }
  438. if (isset($params['dateEnd'])) {
  439. $query->filterByDateEnd($params['dateField'], $params['dateEnd']);
  440. }
  441. if (isset($params['cycleNumber'])) {
  442. $query->filterByCycleNumber($params['cycleNumber']);
  443. }
  444. if (isset($params['isCart'])) {
  445. $query->filterByStatus(OrderStatus::$statusAliasAsCart);
  446. }
  447. if (isset($params['isValid'])) {
  448. $query->filterByStatus(OrderStatus::$statusAliasAsValid);
  449. }
  450. if (isset($params['isWaitingDelivery'])) {
  451. $query->filterByStatus(OrderStatus::$statusAliasWaitingDelivery);
  452. }
  453. if (isset($params['orderStatus'])) {
  454. $query->filterByStatus($params['orderStatus']);
  455. }
  456. if (isset($params['user'])) {
  457. $query->filterByUser($params['user']);
  458. }
  459. if (isset($params['address'])) {
  460. $query->filterByAddress($params['address']);
  461. }
  462. if (isset($params['weekDeliveryTrucks'])) {
  463. $query->filterByWeekDeliveryTruck($params['weekDeliveryTrucks']);
  464. }
  465. if (isset($params['estimatedDeliveryDateTime'])) {
  466. $date = clone $params['estimatedDeliveryDateTime'];
  467. $query
  468. ->filterByEstimatedDeliveryDateStart($date->format('Y-m-d 00:00:00'))
  469. ->filterByEstimatedDeliveryDateEnd($date->modify('+1 day')->format('Y-m-d 00:00:00'));
  470. }
  471. if (isset($params['deliveryDate'])) {
  472. $date = clone $params['deliveryDate'];
  473. $query
  474. ->filterByDeliveryDateStart($date->format('Y-m-d 00:00:00'))
  475. ->filterByDeliveryDateEnd($date->modify('+1 day')->format('Y-m-d 00:00:00'));
  476. }
  477. if (isset($params['mergeComplementaryOrderShops'])) {
  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. }