Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

828 lines
31KB

  1. <?php
  2. /**
  3. * Copyright distrib (2018)
  4. *
  5. * contact@opendistrib.net
  6. *
  7. * Ce logiciel est un programme informatique servant à aider les producteurs
  8. * à distribuer leur production en circuits courts.
  9. *
  10. * Ce logiciel est régi par la licence CeCILL soumise au droit français et
  11. * respectant les principes de diffusion des logiciels libres. Vous pouvez
  12. * utiliser, modifier et/ou redistribuer ce programme sous les conditions
  13. * de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
  14. * sur le site "http://www.cecill.info".
  15. *
  16. * En contrepartie de l'accessibilité au code source et des droits de copie,
  17. * de modification et de redistribution accordés par cette licence, il n'est
  18. * offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
  19. * seule une responsabilité restreinte pèse sur l'auteur du programme, le
  20. * titulaire des droits patrimoniaux et les concédants successifs.
  21. *
  22. * A cet égard l'attention de l'utilisateur est attirée sur les risques
  23. * associés au chargement, à l'utilisation, à la modification et/ou au
  24. * développement et à la reproduction du logiciel par l'utilisateur étant
  25. * donné sa spécificité de logiciel libre, qui peut le rendre complexe à
  26. * manipuler et qui le réserve donc à des développeurs et des professionnels
  27. * avertis possédant des connaissances informatiques approfondies. Les
  28. * utilisateurs sont donc invités à charger et tester l'adéquation du
  29. * logiciel à leurs besoins dans des conditions permettant d'assurer la
  30. * sécurité de leurs systèmes et ou de leurs données et, plus généralement,
  31. * à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
  32. *
  33. * Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
  34. * pris connaissance de la licence CeCILL, et que vous en avez accepté les
  35. * termes.
  36. */
  37. namespace common\models;
  38. use common\helpers\Debug;
  39. use common\helpers\GlobalParam;
  40. use common\helpers\Price;
  41. use Yii;
  42. use yii\helpers\Html;
  43. use common\models\Producer;
  44. use common\components\ActiveRecordCommon;
  45. use yii\web\NotFoundHttpException;
  46. /**
  47. * This is the model class for table "order".
  48. *
  49. * @property integer $id
  50. * @property integer $id_user
  51. * @property string $date
  52. * @property string $date_update
  53. * @property integer $id_point_sale
  54. * @property integer $id_distribution
  55. * @property boolean $auto_payment
  56. * @property integer $id_subscription
  57. */
  58. class Order extends ActiveRecordCommon
  59. {
  60. var $amount = 0;
  61. var $paid_amount = 0;
  62. var $weight = 0;
  63. const ORIGIN_AUTO = 'auto';
  64. const ORIGIN_USER = 'user';
  65. const ORIGIN_ADMIN = 'admin';
  66. const PAYMENT_PAID = 'paid';
  67. const PAYMENT_UNPAID = 'unpaid';
  68. const PAYMENT_SURPLUS = 'surplus';
  69. const AMOUNT_TOTAL = 'total';
  70. const AMOUNT_PAID = 'paid';
  71. const AMOUNT_REMAINING = 'remaining';
  72. const AMOUNT_SURPLUS = 'surplus';
  73. const STATE_OPEN = 'open';
  74. const STATE_PREPARATION = 'preparation';
  75. const STATE_DELIVERED = 'delivered';
  76. /**
  77. * @inheritdoc
  78. */
  79. public static function tableName()
  80. {
  81. return 'order';
  82. }
  83. /**
  84. * @inheritdoc
  85. */
  86. public function rules()
  87. {
  88. return [
  89. [['id_user', 'date', 'id_point_sale', 'id_distribution', 'status'], 'required', 'message' => ''],
  90. [['id_user', 'id_point_sale', 'id_distribution', 'id_subscription', 'id_invoice', 'id_quotation', 'id_delivery_note'], 'integer'],
  91. [['auto_payment', 'tiller_synchronization'], 'boolean'],
  92. [['date', 'date_update', 'comment', 'comment_point_sale', 'mean_payment'], 'safe']
  93. ];
  94. }
  95. /**
  96. * @inheritdoc
  97. */
  98. public function attributeLabels()
  99. {
  100. return [
  101. 'id' => 'ID',
  102. 'id_user' => 'Id User',
  103. 'date' => 'Date',
  104. 'date_update' => 'Date de modification',
  105. 'id_point_sale' => 'Point de vente',
  106. 'id_distribution' => 'Date de distribution',
  107. 'id_subscription' => 'Abonnement',
  108. 'status' => 'Statut',
  109. 'id_invoice' => 'Facture',
  110. 'id_quotation' => 'Devis',
  111. 'id_delivery_note' => 'Bon de livraison'
  112. ];
  113. }
  114. /*
  115. * Relations
  116. */
  117. public function getUser()
  118. {
  119. return $this->hasOne(User::className(), ['id' => 'id_user']);
  120. }
  121. public function getProductOrder()
  122. {
  123. return $this->hasMany(ProductOrder::className(), ['id_order' => 'id'])
  124. ->with('product');
  125. }
  126. public function getDistribution()
  127. {
  128. return $this->hasOne(Distribution::className(), ['id' => 'id_distribution'])
  129. ->with('producer');
  130. }
  131. public function getPointSale()
  132. {
  133. return $this->hasOne(PointSale::className(), ['id' => 'id_point_sale'])
  134. ->with('userPointSale');
  135. }
  136. public function getCreditHistory()
  137. {
  138. return $this->hasMany(CreditHistory::className(), ['id_order' => 'id']);
  139. }
  140. public function getSubscription()
  141. {
  142. return $this->hasOne(Subscription::className(), ['id' => 'id_subscription'])
  143. ->with('productSubscription');
  144. }
  145. public function getInvoice()
  146. {
  147. return $this->hasOne(Invoice::className(), ['id' => 'id_invoice']);
  148. }
  149. public function getQuotation()
  150. {
  151. return $this->hasOne(Quotation::className(), ['id' => 'id_quotation']);
  152. }
  153. public function getDeliveryNote()
  154. {
  155. return $this->hasOne(DeliveryNote::className(), ['id' => 'id_delivery_note']);
  156. }
  157. /**
  158. * Retourne les options de base nécessaires à la fonction de recherche.
  159. *
  160. * @return array
  161. */
  162. public static function defaultOptionsSearch()
  163. {
  164. return [
  165. 'with' => ['productOrder', 'productOrder.product', 'creditHistory', 'creditHistory.userAction', 'pointSale'],
  166. 'join_with' => ['distribution', 'user', 'user.userProducer'],
  167. 'orderby' => 'order.date ASC',
  168. 'attribute_id_producer' => 'distribution.id_producer'
  169. ];
  170. }
  171. /**
  172. * Initialise le montant total, le montant déjà payé et le poids de la
  173. * commande.
  174. */
  175. public function init()
  176. {
  177. $this->initAmount();
  178. $this->initPaidAmount();
  179. return $this;
  180. }
  181. /**
  182. * Initialise le montant de la commande.
  183. *
  184. */
  185. public function initAmount()
  186. {
  187. $this->amount = 0;
  188. $this->weight = 0;
  189. if (isset($this->productOrder)) {
  190. foreach ($this->productOrder as $productOrder) {
  191. $this->amount += Price::getPriceWithTax($productOrder->price, $productOrder->taxRate->value) * $productOrder->quantity;
  192. if ($productOrder->unit == 'piece') {
  193. if (isset($productOrder->product)) {
  194. $this->weight += ($productOrder->quantity * $productOrder->product->weight) / 1000;
  195. }
  196. } else {
  197. $this->weight += $productOrder->quantity;
  198. }
  199. }
  200. }
  201. }
  202. /**
  203. * Initialise le montant payé de la commande et le retourne.
  204. *
  205. * @return float
  206. */
  207. public function initPaidAmount()
  208. {
  209. if (isset($this->creditHistory)) {
  210. $history = $this->creditHistory;
  211. } else {
  212. $history = CreditHistory::find()
  213. ->where(['id_order' => $this->id])
  214. ->all();
  215. }
  216. $this->paid_amount = 0;
  217. if (count($history)) {
  218. foreach ($history as $ch) {
  219. if ($ch->type == CreditHistory::TYPE_PAYMENT) {
  220. $this->paid_amount += $ch->amount;
  221. } elseif ($ch->type == CreditHistory::TYPE_REFUND) {
  222. $this->paid_amount -= $ch->amount;
  223. }
  224. }
  225. }
  226. }
  227. public function delete()
  228. {
  229. // remboursement si l'utilisateur a payé pour cette commande
  230. $amountPaid = $this->getAmount(Order::AMOUNT_PAID);
  231. if ($amountPaid > 0.01) {
  232. $this->saveCreditHistory(
  233. CreditHistory::TYPE_REFUND,
  234. $amountPaid,
  235. GlobalParam::getCurrentProducerId(),
  236. $this->id_user,
  237. User::getCurrentId()
  238. );
  239. }
  240. // delete
  241. if (Producer::getConfig('option_behavior_cancel_order') == Producer::BEHAVIOR_DELETE_ORDER_DELETE ||
  242. (Producer::getConfig('option_behavior_cancel_order') == Producer::BEHAVIOR_DELETE_ORDER_STATUS && strlen($this->date_delete))) {
  243. ProductOrder::deleteAll(['id_order' => $this->id]);
  244. return parent::delete();
  245. } // status 'delete'
  246. elseif (Producer::getConfig('option_behavior_cancel_order') == Producer::BEHAVIOR_DELETE_ORDER_STATUS) {
  247. $this->date_delete = date('Y-m-d H:i:s');
  248. return $this->save();
  249. }
  250. }
  251. /**
  252. * Changement de statut d'une commande
  253. *
  254. * @param $newStatus
  255. */
  256. public function changeOrderStatus($newStatus, $origin)
  257. {
  258. $orderStatusArray = GlobalParam::get('orderStatus');
  259. switch ($newStatus) {
  260. case 'new-order' :
  261. $this->addOrderStatusHistory($newStatus, $origin);
  262. $this->status = $newStatus;
  263. $this->save();
  264. break;
  265. case 'waiting-paiement-on-delivery':
  266. if(in_array($newStatus, $orderStatusArray[$this->status]['nextStatusAllow'])){
  267. $this->addOrderStatusHistory($newStatus, $origin);
  268. $this->status = $newStatus;
  269. $this->save();
  270. }
  271. break;
  272. case 'waiting-paiement-by-credit':
  273. if(in_array($newStatus, $orderStatusArray[$this->status]['nextStatusAllow'])){
  274. $this->addOrderStatusHistory($newStatus, $origin);
  275. $this->status = $newStatus;
  276. $this->save();
  277. }
  278. break;
  279. case 'paid-by-credit':
  280. if(in_array($newStatus, $orderStatusArray[$this->status]['nextStatusAllow'])){
  281. $this->addOrderStatusHistory($newStatus, $origin);
  282. $this->status = $newStatus;
  283. $this->save();
  284. }
  285. break;
  286. case 'waiting-delevery' :
  287. if(in_array($newStatus, $orderStatusArray[$this->status]['nextStatusAllow'])){
  288. $this->addOrderStatusHistory($newStatus, $origin);
  289. $this->status = $newStatus;
  290. $this->save();
  291. }
  292. break;
  293. case 'delivered':
  294. if(in_array($newStatus, $orderStatusArray[$this->status]['nextStatusAllow'])){
  295. $this->addOrderStatusHistory($newStatus, $origin);
  296. $this->status = $newStatus;
  297. $this->save();
  298. }
  299. break;
  300. case 'refunded':
  301. if(in_array($newStatus, $orderStatusArray[$this->status]['nextStatusAllow'])){
  302. $this->addOrderStatusHistory($newStatus, $origin);
  303. $this->status = $newStatus;
  304. $this->save();
  305. }
  306. break;
  307. case 'cancel':
  308. if(in_array($newStatus, $orderStatusArray[$this->status]['nextStatusAllow'])){
  309. $this->addOrderStatusHistory($newStatus, $origin);
  310. $this->status = $newStatus;
  311. $this->save();
  312. }
  313. break;
  314. default:
  315. throw new NotFoundHttpException('Statut de commande inconnu.');
  316. break;
  317. }
  318. }
  319. public function addOrderStatusHistory($newStatus,$origin)
  320. {
  321. $orderStatusHistory = new OrderStatusHistory();
  322. $orderStatusHistory->id_user = User::getCurrentId();
  323. $orderStatusHistory->id_order = $this->id;
  324. $orderStatusHistory->status = $newStatus;
  325. $orderStatusHistory->origin = $origin;
  326. $orderStatusHistory->date = date('Y-m-d H:i:s');
  327. $orderStatusHistory->save();
  328. }
  329. /**
  330. * Retourne le montant de la commande (total, payé, restant, ou en surplus).
  331. *
  332. * @param boolean $format
  333. * @return float
  334. */
  335. public function getAmount($type = self::AMOUNT_TOTAL, $format = false)
  336. {
  337. switch ($type) {
  338. case self::AMOUNT_TOTAL :
  339. $amount = $this->amount;
  340. break;
  341. case self::AMOUNT_PAID :
  342. $this->initPaidAmount();
  343. $amount = $this->paid_amount;
  344. break;
  345. case self::AMOUNT_REMAINING :
  346. $amount = $this->getAmount(self::AMOUNT_TOTAL)
  347. - $this->getAmount(self::AMOUNT_PAID);
  348. break;
  349. case self::AMOUNT_SURPLUS :
  350. $amount = $this->getAmount(self::AMOUNT_PAID)
  351. - $this->getAmount(self::AMOUNT_TOTAL);
  352. break;
  353. }
  354. if ($format) {
  355. return number_format($amount, 2) . ' €';
  356. } else {
  357. return $amount;
  358. }
  359. }
  360. /**
  361. * Retourne les informations relatives à la commande au format JSON.
  362. *
  363. * @return string
  364. */
  365. public function getDataJson()
  366. {
  367. $order = Order::searchOne(['order.id' => $this->id]);
  368. $jsonOrder = [];
  369. if ($order) {
  370. $jsonOrder = [
  371. 'products' => [],
  372. 'amount' => $order->amount,
  373. 'str_amount' => $order->getAmount(self::AMOUNT_TOTAL, true),
  374. 'paid_amount' => $order->getAmount(self::AMOUNT_PAID),
  375. 'comment' => $order->comment,
  376. ];
  377. foreach ($order->productOrder as $productOrder) {
  378. $jsonOrder['products'][$productOrder->id_product] = $productOrder->quantity;
  379. }
  380. }
  381. return json_encode($jsonOrder);
  382. }
  383. /**
  384. * Enregistre un modèle de type CreditHistory.
  385. *
  386. * @param string $type
  387. * @param float $montant
  388. * @param integer $idProducer
  389. * @param integer $idUser
  390. * @param integer $idUserAction
  391. */
  392. public function saveCreditHistory($type, $amount, $idProducer, $idUser, $idUserAction)
  393. {
  394. $creditHistory = new CreditHistory;
  395. $creditHistory->id_user = $this->id_user;
  396. $creditHistory->id_order = $this->id;
  397. $creditHistory->amount = $amount;
  398. $creditHistory->type = $type;
  399. $creditHistory->id_producer = $idProducer;
  400. $creditHistory->id_user_action = $idUserAction;
  401. $creditHistory->populateRelation('order', $this);
  402. $creditHistory->populateRelation('user', User::find()->where(['id' => $this->id_user])->one());
  403. $creditHistory->save();
  404. }
  405. /**
  406. * Ajuste le crédit pour que la commande soit payée.
  407. *
  408. * @return boolean
  409. */
  410. public function processCredit()
  411. {
  412. if ($this->id_user) {
  413. $paymentStatus = $this->getPaymentStatus();
  414. if ($paymentStatus == self::PAYMENT_PAID) {
  415. return true;
  416. } elseif ($paymentStatus == self::PAYMENT_SURPLUS) {
  417. $type = CreditHistory::TYPE_REFUND;
  418. $amount = $this->getAmount(self::AMOUNT_SURPLUS);
  419. } elseif ($paymentStatus == self::PAYMENT_UNPAID) {
  420. $type = CreditHistory::TYPE_PAYMENT;
  421. $amount = $this->getAmount(self::AMOUNT_REMAINING);
  422. }
  423. $this->saveCreditHistory(
  424. $type,
  425. $amount,
  426. GlobalParam::getCurrentProducerId(),
  427. $this->id_user,
  428. User::getCurrentId()
  429. );
  430. }
  431. }
  432. /**
  433. * Retourne le statut de paiement de la commande (payée, surplus, ou impayée).
  434. *
  435. * @return string
  436. */
  437. public function getPaymentStatus()
  438. {
  439. // payé
  440. if ($this->getAmount() - $this->getAmount(self::AMOUNT_PAID) < 0.01 &&
  441. $this->getAmount() - $this->getAmount(self::AMOUNT_PAID) > -0.01) {
  442. return self::PAYMENT_PAID;
  443. } // à rembourser
  444. elseif ($this->getAmount() - $this->getAmount(self::AMOUNT_PAID) <= -0.01) {
  445. return self::PAYMENT_SURPLUS;
  446. } // reste à payer
  447. elseif ($this->getAmount() - $this->getAmount(self::AMOUNT_PAID) >= 0.01) {
  448. return self::PAYMENT_UNPAID;
  449. }
  450. }
  451. /**
  452. * Retourne le résumé du panier au format HTML.
  453. *
  454. * @return string
  455. */
  456. public function getCartSummary()
  457. {
  458. if (!isset($this->productOrder)) {
  459. $this->productOrder = productOrder::find()->where(['id_order' => $this->id])->all();
  460. }
  461. $html = '';
  462. $count = count($this->productOrder);
  463. $i = 0;
  464. foreach ($this->productOrder as $p) {
  465. if (isset($p->product)) {
  466. $html .= Html::encode($p->product->name) . ' (' . $p->quantity . '&nbsp;' . Product::strUnit($p->unit, 'wording_short', true) . ')';
  467. if (++$i != $count) {
  468. $html .= '<br />';
  469. }
  470. }
  471. }
  472. return $html;
  473. }
  474. /**
  475. * Retourne le résumé du point de vente lié à la commande au format HTML.
  476. *
  477. * @return string
  478. */
  479. public function getPointSaleSummary()
  480. {
  481. $html = '';
  482. if (isset($this->pointSale)) {
  483. $html .= '<span class="name-point-sale">' .
  484. Html::encode($this->pointSale->name) .
  485. '</span>' .
  486. '<br /><span class="locality">'
  487. . Html::encode($this->pointSale->locality)
  488. . '</span>';
  489. if (strlen($this->comment_point_sale)) {
  490. $html .= '<div class="comment"><span>'
  491. . Html::encode($this->comment_point_sale)
  492. . '</span></div>';
  493. }
  494. } else {
  495. $html .= 'Point de vente supprimé';
  496. }
  497. return $html;
  498. }
  499. /**
  500. * Retourne le résumé du paiement (montant, statut).
  501. *
  502. * @return string
  503. */
  504. public function getAmountSummary()
  505. {
  506. $html = '';
  507. $html .= $this->getAmount(self::AMOUNT_TOTAL, true) . '<br />';
  508. if ($this->paid_amount) {
  509. if ($this->getPaymentStatus() == Order::PAYMENT_PAID) {
  510. $html .= '<span class="label label-success">Payée</span>';
  511. } elseif ($this->getPaymentStatus() == Order::PAYMENT_UNPAID) {
  512. $html .= '<span class="label label-danger">Non payée</span><br />
  513. Reste <strong>' . $this->getAmount(Order::AMOUNT_REMAINING, true) . '</strong> à payer';
  514. } elseif ($this->getPaymentStatus() == Order::PAYMENT_SURPLUS) {
  515. $html .= '<span class="label label-success">Payée</span>';
  516. }
  517. } else {
  518. $html .= '<span class="label label-default">Non réglé</span>';
  519. }
  520. return $html;
  521. }
  522. /**
  523. * Retourne une chaine de caractère décrivant l'utilisateur lié à la commande.
  524. *
  525. * @return string
  526. */
  527. public function getStrUser()
  528. {
  529. if (isset($this->user)) {
  530. return Html::encode($this->user->lastname . ' ' . $this->user->name);
  531. } elseif (strlen($this->username)) {
  532. return Html::encode($this->username);
  533. } else {
  534. return 'Client introuvable';
  535. }
  536. }
  537. /**
  538. * Retourne l'état de la commande (livrée, modifiable ou en préparation)
  539. *
  540. * @return string
  541. */
  542. public function getState()
  543. {
  544. $orderDelay = Producer::getConfig(
  545. 'order_delay',
  546. $this->distribution->id_producer
  547. );
  548. $orderDeadline = Producer::getConfig(
  549. 'order_deadline',
  550. $this->distribution->id_producer
  551. );
  552. $orderDate = strtotime($this->distribution->date);
  553. $today = strtotime(date('Y-m-d'));
  554. $todayHour = date('G');
  555. $nbDays = (int)(($orderDate - $today) / (24 * 60 * 60));
  556. if ($nbDays <= 0) {
  557. return self::STATE_DELIVERED;
  558. } elseif ($nbDays >= $orderDelay &&
  559. ($nbDays != $orderDelay ||
  560. ($nbDays == $orderDelay && $todayHour < $orderDeadline))) {
  561. return self::STATE_OPEN;
  562. }
  563. return self::STATE_PREPARATION;
  564. }
  565. /**
  566. * Retourne l'origine de la commande (client, automatique ou admin) sous forme
  567. * texte ou HTML.
  568. *
  569. * @param boolean $with_label
  570. * @return string
  571. */
  572. public function getStrOrigin($withLabel = false)
  573. {
  574. $classLabel = '';
  575. $str = '';
  576. if ($this->origin == self::ORIGIN_USER) {
  577. $classLabel = 'success';
  578. $str = 'Client';
  579. } elseif ($this->origin == self::ORIGIN_AUTO) {
  580. $classLabel = 'default';
  581. $str = 'Auto';
  582. } elseif ($this->origin == self::ORIGIN_ADMIN) {
  583. $classLabel = 'warning';
  584. $str = 'Vous';
  585. }
  586. if ($withLabel) {
  587. return '<span class="label label-' . $classLabel . '">'
  588. . $str . '</span>';
  589. } else {
  590. return $str;
  591. }
  592. }
  593. /**
  594. * Retourne l'historique de la commande (ajoutée, modifiée, supprimée) au
  595. * format HTML.
  596. *
  597. * @return string
  598. */
  599. public function getStrHistory()
  600. {
  601. $arr = [
  602. 'class' => 'create',
  603. 'glyphicon' => 'plus',
  604. 'str' => 'Ajoutée',
  605. 'date' => $this->date
  606. ];
  607. if (!is_null($this->date_update)) {
  608. $arr = [
  609. 'class' => 'update',
  610. 'glyphicon' => 'pencil',
  611. 'str' => 'Modifiée',
  612. 'date' => $this->date_update
  613. ];
  614. }
  615. if (!is_null($this->date_delete)) {
  616. $arr = [
  617. 'class' => 'delete',
  618. 'glyphicon' => 'remove',
  619. 'str' => 'Annulée',
  620. 'date' => $this->date_delete
  621. ];
  622. }
  623. $html = '<div class="small"><span class="' . $arr['class'] . '">'
  624. . '<span class="glyphicon glyphicon-' . $arr['glyphicon'] . '"></span> '
  625. . $arr['str'] . '</span> le <strong>'
  626. . date('d/m/Y à G\hi', strtotime($arr['date'])) . '</strong></div>';
  627. return $html;
  628. }
  629. /**
  630. * Retourne une classe identifiant l'historique de la commande (ajoutée,
  631. * modifiée, supprimée).
  632. *
  633. * @return string
  634. */
  635. public function getClassHistory()
  636. {
  637. if (!is_null($this->date_delete)) {
  638. return 'commande-delete';
  639. }
  640. if (!is_null($this->date_update)) {
  641. return 'commande-update';
  642. }
  643. return 'commande-create';
  644. }
  645. /**
  646. * Retourne la quantité d'un produit donné de plusieurs commandes.
  647. *
  648. * @param integer $idProduct
  649. * @param array $orders
  650. * @param boolean $ignoreCancel
  651. *
  652. * @return integer
  653. */
  654. public static function getProductQuantity($idProduct, $orders, $ignoreCancel = false, $unit = null)
  655. {
  656. $quantity = 0;
  657. if (isset($orders) && is_array($orders) && count($orders)) {
  658. foreach ($orders as $c) {
  659. if (is_null($c->date_delete) || $ignoreCancel) {
  660. foreach ($c->productOrder as $po) {
  661. if ($po->id_product == $idProduct &&
  662. ((is_null($unit) && $po->product->unit == $po->unit) || (!is_null($unit) && strlen($unit) && $po->unit == $unit))) {
  663. $quantity += $po->quantity;
  664. }
  665. }
  666. }
  667. }
  668. }
  669. return $quantity;
  670. }
  671. /**
  672. * Recherche et initialise des commandes.
  673. *
  674. * @param array $params
  675. * @param array $conditions
  676. * @param string $orderby
  677. * @param integer $limit
  678. * @return array
  679. */
  680. public static function searchBy($params = [], $options = [])
  681. {
  682. $orders = parent::searchBy($params, $options);
  683. /*
  684. * Initialisation des commandes
  685. */
  686. if (is_array($orders)) {
  687. if (count($orders)) {
  688. foreach ($orders as $order) {
  689. if (is_a($order, 'common\models\Order')) {
  690. $order->init();
  691. }
  692. }
  693. return $orders;
  694. }
  695. } else {
  696. $order = $orders;
  697. if (is_a($order, 'common\models\Order')) {
  698. return $order->init();
  699. } // count
  700. else {
  701. return $order;
  702. }
  703. }
  704. return false;
  705. }
  706. /**
  707. * Retourne le nombre de produits commandés
  708. *
  709. * @return integer
  710. */
  711. public function countProducts()
  712. {
  713. $count = 0;
  714. if ($this->productOrder && is_array($this->productOrder)) {
  715. foreach ($this->productOrder as $productOrder) {
  716. if ($productOrder->unit == 'piece') {
  717. $count++;
  718. } else {
  719. $count += $productOrder->quantity;
  720. }
  721. }
  722. }
  723. return $count;
  724. }
  725. /**
  726. * Retourne un bloc html présentant une date.
  727. *
  728. * @return string
  729. */
  730. public function getBlockDate()
  731. {
  732. return '<div class="block-date">
  733. <div class="day">' . strftime('%A', strtotime($this->distribution->date)) . '</div>
  734. <div class="num">' . date('d', strtotime($this->distribution->date)) . '</div>
  735. <div class="month">' . strftime('%B', strtotime($this->distribution->date)) . '</div>
  736. </div>';
  737. }
  738. }