您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

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