選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

894 行
34KB

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