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.

Order.php 34KB

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