No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

875 líneas
33KB

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