<?php

/**
 * Copyright distrib (2018)
 *
 * contact@opendistrib.net
 *
 * Ce logiciel est un programme informatique servant à aider les producteurs
 * à distribuer leur production en circuits courts.
 *
 * Ce logiciel est régi par la licence CeCILL soumise au droit français et
 * respectant les principes de diffusion des logiciels libres. Vous pouvez
 * utiliser, modifier et/ou redistribuer ce programme sous les conditions
 * de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
 * sur le site "http://www.cecill.info".
 *
 * En contrepartie de l'accessibilité au code source et des droits de copie,
 * de modification et de redistribution accordés par cette licence, il n'est
 * offert aux utilisateurs qu'une garantie limitée.  Pour les mêmes raisons,
 * seule une responsabilité restreinte pèse sur l'auteur du programme,  le
 * titulaire des droits patrimoniaux et les concédants successifs.
 *
 * A cet égard  l'attention de l'utilisateur est attirée sur les risques
 * associés au chargement,  à l'utilisation,  à la modification et/ou au
 * développement et à la reproduction du logiciel par l'utilisateur étant
 * donné sa spécificité de logiciel libre, qui peut le rendre complexe à
 * manipuler et qui le réserve donc à des développeurs et des professionnels
 * avertis possédant  des  connaissances  informatiques approfondies.  Les
 * utilisateurs sont donc invités à charger  et  tester  l'adéquation  du
 * logiciel à leurs besoins dans des conditions permettant d'assurer la
 * sécurité de leurs systèmes et ou de leurs données et, plus généralement,
 * à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
 *
 * Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
 * pris connaissance de la licence CeCILL, et que vous en avez accepté les
 * termes.
 */

namespace common\models;

use common\helpers\Debug;
use common\helpers\GlobalParam;
use common\helpers\Price;
use common\models\Producer;
use Yii;
use yii\helpers\Html;
use common\components\ActiveRecordCommon;
use yii\web\NotFoundHttpException;

/**
 * This is the model class for table "order".
 *
 * @property integer $id
 * @property integer $id_user
 * @property string $date
 * @property string $date_update
 * @property integer $id_point_sale
 * @property integer $id_distribution
 * @property boolean $auto_payment
 * @property integer $id_subscription
 */
class Order extends ActiveRecordCommon
{
        var $amount = 0;
        var $amount_with_tax = 0;
        var $invoice_amount = 0;
        var $invoice_amount_with_tax = 0;
        var $paid_amount = 0;
        var $weight = 0;

        const ORIGIN_AUTO = 'auto';
        const ORIGIN_USER = 'user';
        const ORIGIN_ADMIN = 'admin';

        const PAYMENT_PAID = 'paid';
        const PAYMENT_UNPAID = 'unpaid';
        const PAYMENT_SURPLUS = 'surplus';

        const INVOICE_AMOUNT_TOTAL = 'invoice-total' ;
        const AMOUNT_TOTAL = 'total';
        const AMOUNT_PAID = 'paid';
        const AMOUNT_REMAINING = 'remaining';
        const AMOUNT_SURPLUS = 'surplus';

        const STATE_OPEN = 'open';
        const STATE_PREPARATION = 'preparation';
        const STATE_DELIVERED = 'delivered';

        /**
         * @inheritdoc
         */
        public static function tableName()
        {
                return 'order';
        }

        /**
         * @inheritdoc
         */
        public function rules()
        {
                return [
                        [['id_user', 'date', 'status'], 'required', 'message' => ''],
                        [['id_user', 'id_point_sale', 'id_distribution', 'id_subscription', 'id_invoice', 'id_quotation', 'id_delivery_note'], 'integer'],
                        [['auto_payment', 'tiller_synchronization', 'delivery_home'], 'boolean'],
                        [['status', 'reference', 'delivery_address'], 'string'],
                        [['date', 'date_update', 'comment', 'comment_point_sale', 'mean_payment'], 'safe']
                ];
        }

        /**
         * @inheritdoc
         */
        public function attributeLabels()
        {
                return [
                        'id' => 'ID',
                        'id_user' => 'Id User',
                        'date' => 'Date',
                        'date_update' => 'Date de modification',
                        'id_point_sale' => 'Point de vente',
                        'id_distribution' => 'Date de distribution',
                        'id_subscription' => 'Abonnement',
                        'status' => 'Statut',
                        'id_invoice' => 'Facture',
                        'id_quotation' => 'Devis',
                        'id_delivery_note' => 'Bon de livraison',
                        'reference' => 'Référence',
                        'delivery_home' => 'Livraison à domicile',
                        'delivery_address' => 'Adresse de livraison'
                ];
        }

        /*
         * Relations
         */

        public function getUser()
        {
                return $this->hasOne(User::className(), ['id' => 'id_user']);
        }

        public function getProductOrder()
        {
                return $this->hasMany(ProductOrder::className(), ['id_order' => 'id'])
                        ->orderBy(['product.order' => SORT_ASC])
                        ->joinWith('product');
        }

        public function getDistribution()
        {
                return $this->hasOne(Distribution::className(), ['id' => 'id_distribution'])
                        ->with('producer');
        }

        public function getPointSale()
        {
                return $this->hasOne(PointSale::className(), ['id' => 'id_point_sale'])
                        ->with('userPointSale');
        }

        public function getCreditHistory()
        {
                return $this->hasMany(CreditHistory::className(), ['id_order' => 'id']);
        }

        public function getSubscription()
        {
                return $this->hasOne(Subscription::className(), ['id' => 'id_subscription'])
                        ->with('productSubscription');
        }

        public function getInvoice()
        {
                return $this->hasOne(Invoice::className(), ['id' => 'id_invoice']);
        }

        public function getQuotation()
        {
                return $this->hasOne(Quotation::className(), ['id' => 'id_quotation']);
        }

        public function getDeliveryNote()
        {
                return $this->hasOne(DeliveryNote::className(), ['id' => 'id_delivery_note']);
        }

        /**
         * Retourne les options de base nécessaires à la fonction de recherche.
         *
         * @return array
         */
        public static function defaultOptionsSearch()
        {
                return [
                        'with' => ['productOrder', 'productOrder.product', 'creditHistory', 'creditHistory.userAction', 'pointSale'],
                        'join_with' => ['distribution', 'user', 'user.userProducer'],
                        'orderby' => 'order.date ASC',
                        'attribute_id_producer' => 'distribution.id_producer'
                ];
        }

        /**
         * Initialise le montant total, le montant déjà payé et le poids de la
         * commande.
         */
        public function init()
        {
                $this->initAmount();
                $this->initPaidAmount();

                return $this;
        }

        /**
         * Initialise le montant de la commande.
         *
         */
        public function initAmount()
        {
                $this->amount = 0;
                $this->amount_with_tax = 0;
                $this->invoice_amount = 0;
                $this->invoice_amount_with_tax = 0;
                $this->weight = 0;

                if (isset($this->productOrder)) {
                        foreach ($this->productOrder as $productOrder) {

                                $this->amount += $productOrder->price * $productOrder->quantity;
                                $this->amount_with_tax += Price::getPriceWithTax($productOrder->price, $productOrder->taxRate->value) * $productOrder->quantity;

                                $invoicePrice = $productOrder->invoice_price ? $productOrder->invoice_price : $productOrder->price ;
                                $this->invoice_amount += $invoicePrice * $productOrder->quantity;
                                $this->invoice_amount_with_tax += Price::getPriceWithTax($invoicePrice, $productOrder->taxRate->value) * $productOrder->quantity;

                                if ($productOrder->unit == 'piece') {
                                        if (isset($productOrder->product)) {
                                                $this->weight += ($productOrder->quantity * $productOrder->product->weight) / 1000;
                                        }
                                } else {
                                        $this->weight += $productOrder->quantity;
                                }
                        }
                }
        }

        /**
         * Initialise le montant payé de la commande et le retourne.
         *
         * @return float
         */
        public function initPaidAmount()
        {
                if (isset($this->creditHistory)) {
                        $history = $this->creditHistory;
                } else {
                        $history = CreditHistory::find()
                                ->where(['id_order' => $this->id])
                                ->all();
                }

                $this->paid_amount = 0;

                if (count($history)) {
                        foreach ($history as $ch) {
                                if ($ch->type == CreditHistory::TYPE_PAYMENT) {
                                        $this->paid_amount += $ch->amount;
                                } elseif ($ch->type == CreditHistory::TYPE_REFUND) {
                                        $this->paid_amount -= $ch->amount;
                                }
                        }
                }
        }

        public function delete()
        {

                // remboursement si l'utilisateur a payé pour cette commande
                $amountPaid = $this->getAmount(Order::AMOUNT_PAID);
                if ($amountPaid > 0.01) {
                        $this->saveCreditHistory(
                                CreditHistory::TYPE_REFUND,
                                $amountPaid,
                                GlobalParam::getCurrentProducerId(),
                                $this->id_user,
                                User::getCurrentId()
                        );
                }

                // delete
                if (Producer::getConfig('option_behavior_cancel_order') == Producer::BEHAVIOR_DELETE_ORDER_DELETE ||
                        (Producer::getConfig('option_behavior_cancel_order') == Producer::BEHAVIOR_DELETE_ORDER_STATUS && strlen($this->date_delete))) {
                        ProductOrder::deleteAll(['id_order' => $this->id]);
                        return parent::delete();
                } // status 'delete'
                elseif (Producer::getConfig('option_behavior_cancel_order') == Producer::BEHAVIOR_DELETE_ORDER_STATUS) {
                        $this->date_delete = date('Y-m-d H:i:s');
                        return $this->save();
                }
        }


        /**
         * Changement de statut d'une commande
         *
         * @param $newStatus
         */
        public function changeOrderStatus($newStatus, $origin)
        {
                $orderStatusArray = GlobalParam::get('orderStatus');
                switch ($newStatus) {
                        case 'new-order' :
                                $this->addOrderStatusHistory($newStatus, $origin);
                                $this->status = $newStatus;
                                $this->save();
                                break;
                        case 'waiting-paiement-on-delivery':
                                if(in_array($newStatus, $orderStatusArray[$this->status]['nextStatusAllow'])){

                                        $this->addOrderStatusHistory($newStatus, $origin);
                                        $this->status = $newStatus;
                                        $this->save();
                                }
                                break;
                        case 'waiting-paiement-by-credit':
                                if(in_array($newStatus, $orderStatusArray[$this->status]['nextStatusAllow'])){

                                        $this->addOrderStatusHistory($newStatus, $origin);
                                        $this->status = $newStatus;
                                        $this->save();
                                }
                                break;
                        case 'paid-by-credit':
                                if(in_array($newStatus, $orderStatusArray[$this->status]['nextStatusAllow'])){

                                        $this->addOrderStatusHistory($newStatus, $origin);
                                        $this->status = $newStatus;
                                        $this->save();
                                }
                                break;
                        case 'waiting-delevery' :
                                if(in_array($newStatus, $orderStatusArray[$this->status]['nextStatusAllow'])){

                                        $this->addOrderStatusHistory($newStatus, $origin);
                                        $this->status = $newStatus;
                                        $this->save();
                                }
                                break;
                        case 'delivered':
                                if(in_array($newStatus, $orderStatusArray[$this->status]['nextStatusAllow'])){

                                        $this->addOrderStatusHistory($newStatus, $origin);
                                        $this->status = $newStatus;
                                        $this->save();
                                }
                                break;
                        case 'refunded':
                                if(in_array($newStatus, $orderStatusArray[$this->status]['nextStatusAllow'])){

                                        $this->addOrderStatusHistory($newStatus, $origin);
                                        $this->status = $newStatus;
                                        $this->save();
                                }
                                break;
                        case 'cancel':
                                if(in_array($newStatus, $orderStatusArray[$this->status]['nextStatusAllow'])){

                                        $this->addOrderStatusHistory($newStatus, $origin);
                                        $this->status = $newStatus;
                                        $this->save();
                                }
                                break;
                        default:
                                throw new NotFoundHttpException('Statut de commande inconnu.');
                                break;
                }
        }

        public function addOrderStatusHistory($newStatus,$origin)
        {

                $orderStatusHistory = new OrderStatusHistory();
                $orderStatusHistory->id_user = User::getCurrentId();
                $orderStatusHistory->id_order = $this->id;
                $orderStatusHistory->status = $newStatus;
                $orderStatusHistory->origin = $origin;
                $orderStatusHistory->date = date('Y-m-d H:i:s');
                $orderStatusHistory->save();
        }

        /**
         * Retourne le montant de la commande (total, payé, restant, ou en surplus).
         *
         * @param boolean $format
         * @return float
         */

        public function getAmount($type = self::AMOUNT_TOTAL, $format = false)
        {
                $amount = $this->amount ;
                if($type == self::INVOICE_AMOUNT_TOTAL) {
                        $amount = $this->invoice_amount ;
                }

                return $this->_getAmountGeneric($type, $amount, $format) ;
        }

        public function getAmountWithTax($type = self::AMOUNT_TOTAL, $format = false)
        {
                $amount = $this->amount_with_tax ;
                if($type == self::INVOICE_AMOUNT_TOTAL) {
                        $amount = $this->invoice_amount_with_tax ;
                }

                return $this->_getAmountGeneric($type, $amount, $format) ;
        }

        protected function _getAmountGeneric($type, $amountOrder, $format)
        {
                switch ($type) {
                        case self::AMOUNT_TOTAL :
                        case self::INVOICE_AMOUNT_TOTAL :
                                $amount = $amountOrder;
                                break;
                        case self::AMOUNT_PAID :
                                $this->initPaidAmount();
                                $amount = $this->paid_amount;
                                break;
                        case self::AMOUNT_REMAINING :
                                $amount = $this->getAmountWithTax(self::AMOUNT_TOTAL)
                                        - $this->getAmountWithTax(self::AMOUNT_PAID);
                                break;
                        case self::AMOUNT_SURPLUS :
                                $amount = $this->getAmountWithTax(self::AMOUNT_PAID)
                                        - $this->getAmountWithTax(self::AMOUNT_TOTAL);
                                break;
                        /*default:
                                throw new NotFoundHttpException('Type de montant inconnu : '.$type) ;*/
                }

                if ($format) {
                        return Price::format($amount) ;
                } else {
                        return $amount;
                }
        }

        /**
         * Retourne les informations relatives à la commande au format JSON.
         *
         * @return string
         */
        public function getDataJson()
        {
                $order = Order::searchOne(['order.id' => $this->id]);

                $jsonOrder = [];
                if ($order) {
                        $jsonOrder = [
                                'products' => [],
                                'amount' => $order->amount,
                                'str_amount' => $order->getAmountWithTax(self::AMOUNT_TOTAL, true),
                                'paid_amount' => $order->getAmount(self::AMOUNT_PAID),
                                'comment' => $order->comment,
                        ];

                        foreach ($order->productOrder as $productOrder) {
                                $jsonOrder['products'][$productOrder->id_product] = $productOrder->quantity;
                        }
                }

                return json_encode($jsonOrder);
        }

        /**
         * Enregistre un modèle de type CreditHistory.
         *
         * @param string $type
         * @param float $montant
         * @param integer $idProducer
         * @param integer $idUser
         * @param integer $idUserAction
         */
        public function saveCreditHistory($type, $amount, $idProducer, $idUser, $idUserAction)
        {
                $creditHistory = new CreditHistory;
                $creditHistory->id_user = $this->id_user;
                $creditHistory->id_order = $this->id;
                $creditHistory->amount = $amount;
                $creditHistory->type = $type;
                $creditHistory->id_producer = $idProducer;
                $creditHistory->id_user_action = $idUserAction;
                $creditHistory->populateRelation('order', $this);
                $creditHistory->populateRelation('user', User::find()->where(['id' => $this->id_user])->one());
                $creditHistory->save();
        }

        /**
         * Ajuste le crédit pour que la commande soit payée.
         *
         * @return boolean
         */
        public function processCredit()
        {
                if ($this->id_user) {
                        $paymentStatus = $this->getPaymentStatus();

                        if ($paymentStatus == self::PAYMENT_PAID) {
                                return true;
                        } elseif ($paymentStatus == self::PAYMENT_SURPLUS) {
                                $type = CreditHistory::TYPE_REFUND;
                                $amount = $this->getAmount(self::AMOUNT_SURPLUS);
                        } elseif ($paymentStatus == self::PAYMENT_UNPAID) {
                                $type = CreditHistory::TYPE_PAYMENT;
                                $amount = $this->getAmount(self::AMOUNT_REMAINING);
                        }

                        $this->saveCreditHistory(
                                $type,
                                $amount,
                                GlobalParam::getCurrentProducerId(),
                                $this->id_user,
                                User::getCurrentId()
                        );
                }
        }

        public function setTillerSynchronization()
        {
                $order = Order::searchOne(['id' => $this->id]);

                $paymentStatus = $order->getPaymentStatus();

                if ($paymentStatus == self::PAYMENT_PAID) {
                        $order->tiller_synchronization = 1 ;
                }
                else {
                        $order->tiller_synchronization = 0 ;
                }

                $order->save() ;

                return $order ;
        }

        /**
         * Retourne le statut de paiement de la commande (payée, surplus, ou impayée).
         *
         * @return string
         */
        public function getPaymentStatus()
        {
                // payé
                if ($this->getAmountWithtax() - $this->getAmount(self::AMOUNT_PAID) < 0.01 &&
                        $this->getAmountWithtax() - $this->getAmount(self::AMOUNT_PAID) > -0.01) {
                        return self::PAYMENT_PAID;
                } // à rembourser
                elseif ($this->getAmountWithtax() - $this->getAmount(self::AMOUNT_PAID) <= -0.01) {
                        return self::PAYMENT_SURPLUS;
                } // reste à payer
                elseif ($this->getAmountWithtax() - $this->getAmount(self::AMOUNT_PAID) >= 0.01) {
                        return self::PAYMENT_UNPAID;
                }
        }

        /**
         * Retourne le résumé du panier au format HTML.
         *
         * @return string
         */
        public function getCartSummary($htmlFormat = true)
        {
                if (!isset($this->productOrder)) {
                        $this->productOrder = productOrder::find()->where(['id_order' => $this->id])->all();
                }

                $html = '';
                $count = count($this->productOrder);
                $i = 0;
                foreach ($this->productOrder as $p) {
                        if (isset($p->product)) {
                                $html .= Html::encode($p->product->name) . ' (' . $p->quantity . '&nbsp;' . Product::strUnit($p->unit, 'wording_short', true) . ')';
                                if (++$i != $count) {
                                        if($htmlFormat) {
                                                $html .= '<br />';
                                        }
                                        else {
                                                $html .= "\n";
                                        }
                                }
                        }
                }

                return $html;
        }

        /**
         * Retourne le résumé du point de vente lié à la commande au format HTML.
         *
         * @return string
         */
        public function getPointSaleSummary()
        {
                $html = '';

                if (isset($this->pointSale)) {
                        $html .= '<span class="name-point-sale">' .
                                Html::encode($this->pointSale->name) .
                                '</span>' .
                                '<br /><span class="locality">'
                                . Html::encode($this->pointSale->locality)
                                . '</span>';

                        if (strlen($this->comment_point_sale)) {
                                $html .= '<div class="comment"><span>'
                                        . Html::encode($this->comment_point_sale)
                                        . '</span></div>';
                        }
                } else {
                        $html .= 'Point de vente supprimé';
                }

                return $html;
        }

        /**
         * Retourne le résumé du paiement (montant, statut).
         *
         * @return string
         */
        public function getAmountSummary()
        {
                $html = '';

                $creditActive = Producer::getConfig('credit') ;
                $html .= $this->getAmountWithTax(self::AMOUNT_TOTAL, true) ;

                if($creditActive) {
                        $html .= '<br />' ;
                        if ($this->paid_amount) {
                                if ($this->getPaymentStatus() == Order::PAYMENT_PAID) {
                                        $html .= '<span class="label label-success">Payée</span>';
                                }
                                elseif ($this->getPaymentStatus() == Order::PAYMENT_UNPAID) {
                                        $html .= '<span class="label label-danger">Non payée</span><br />
                                                Reste <strong>' . $this->getAmount(Order::AMOUNT_REMAINING, true) . '</strong> à payer';
                                }
                                elseif ($this->getPaymentStatus() == Order::PAYMENT_SURPLUS) {
                                        $html .= '<span class="label label-success">Payée</span>';
                                }
                        }
                        else {
                                $html .= '<span class="label label-default">Non réglé</span>';
                        }
                }


                return $html;
        }

        /**
         * Retourne une chaine de caractère décrivant l'utilisateur lié à la commande.
         *
         * @return string
         */
        public function getStrUser()
        {
                if (isset($this->user)) {
                        if(isset($this->user->name_legal_person) && strlen($this->user->name_legal_person)) {
                                return Html::encode($this->user->name_legal_person);
                        }
                        else {
                                return Html::encode($this->user->lastname . ' ' . $this->user->name);
                        }
                }
                elseif (strlen($this->username)) {
                        return Html::encode($this->username);
                }
                else {
                        return 'Client introuvable';
                }
        }

        /**
         * Retourne l'état de la commande (livrée, modifiable ou en préparation)
         *
         * @return string
         */
        public function getState()
        {
                $orderDate = strtotime($this->distribution->date);
                $today = strtotime(date('Y-m-d'));
                $todayHour = date('G');
                $dayDistribution = strtolower(date('l', strtotime($this->distribution->date))) ;

                $orderDelay = Producer::getConfig(
                        'order_delay',
                        $this->distribution->id_producer
                );
                $orderDelaySpecific = Producer::getConfig(
                        'order_delay_'.$dayDistribution,
                        $this->distribution->id_producer
                );
                if($orderDelaySpecific) {
                        $orderDelay = $orderDelaySpecific ;
                }

                $orderDeadline = Producer::getConfig(
                        'order_deadline',
                        $this->distribution->id_producer
                );
                $orderDeadlineSpecific = Producer::getConfig(
                        'order_deadline_'.$dayDistribution,
                        $this->distribution->id_producer
                );
                if($orderDeadlineSpecific) {
                        $orderDeadline = $orderDeadlineSpecific ;
                }

                $nbDays = (int) round((($orderDate - $today) / (24 * 60 * 60)));

                if ($nbDays <= 0) {
                        return self::STATE_DELIVERED;
                } elseif ($nbDays >= $orderDelay &&
                        ($nbDays != $orderDelay ||
                                ($nbDays == $orderDelay && $todayHour < $orderDeadline))) {
                        return self::STATE_OPEN;
                }
		
                return self::STATE_PREPARATION;
        }

        /**
         * Retourne l'origine de la commande (client, automatique ou admin) sous forme
         * texte ou HTML.
         *
         * @param boolean $with_label
         * @return string
         */
        public function getStrOrigin($withLabel = false)
        {
                $classLabel = '';
                $str = '';

                if ($this->origin == self::ORIGIN_USER) {
                        $classLabel = 'success';
                        $str = 'Client';
                } elseif ($this->origin == self::ORIGIN_AUTO) {
                        $classLabel = 'default';
                        $str = 'Auto';
                } elseif ($this->origin == self::ORIGIN_ADMIN) {
                        $classLabel = 'warning';
                        $str = 'Vous';
                }

                if ($withLabel) {
                        return '<span class="label label-' . $classLabel . '">'
                                . $str . '</span>';
                } else {
                        return $str;
                }
        }

        /**
         * Retourne l'historique de la commande (ajoutée, modifiée, supprimée) au
         * format HTML.
         *
         * @return string
         */
        public function getStrHistory()
        {
                $arr = [
                        'class' => 'create',
                        'glyphicon' => 'plus',
                        'str' => 'Ajoutée',
                        'date' => $this->date
                ];

                if (!is_null($this->date_update)) {
                        $arr = [
                                'class' => 'update',
                                'glyphicon' => 'pencil',
                                'str' => 'Modifiée',
                                'date' => $this->date_update
                        ];
                }
                if (!is_null($this->date_delete)) {
                        $arr = [
                                'class' => 'delete',
                                'glyphicon' => 'remove',
                                'str' => 'Annulée',
                                'date' => $this->date_delete
                        ];
                }

                $html = '<div class="small"><span class="' . $arr['class'] . '">'
                        . '<span class="glyphicon glyphicon-' . $arr['glyphicon'] . '"></span> '
                        . $arr['str'] . '</span> le <strong>'
                        . date('d/m/Y à G\hi', strtotime($arr['date'])) . '</strong></div>';

                return $html;
        }

        /**
         * Retourne une classe identifiant l'historique de la commande (ajoutée,
         * modifiée, supprimée).
         *
         * @return string
         */
        public function getClassHistory()
        {
                if (!is_null($this->date_delete)) {
                        return 'commande-delete';
                }
                if (!is_null($this->date_update)) {
                        return 'commande-update';
                }
                return 'commande-create';
        }

        /**
         * Retourne la quantité d'un produit donné de plusieurs commandes.
         *
         * @param integer $idProduct
         * @param array $orders
         * @param boolean $ignoreCancel
         *
         * @return integer
         */
        public static function getProductQuantity($idProduct, $orders, $ignoreCancel = false, $unit = null)
        {
                $quantity = 0;

                if (isset($orders) && is_array($orders) && count($orders)) {
                        foreach ($orders as $c) {
                                if (is_null($c->date_delete) || $ignoreCancel) {
                                        foreach ($c->productOrder as $po) {
                                                if ($po->id_product == $idProduct &&
                                                        ((is_null($unit) && $po->product->unit == $po->unit) || (!is_null($unit) && strlen($unit) && $po->unit == $unit))) {
                                                        $quantity += $po->quantity;
                                                }
                                        }
                                }
                        }
                }

                return $quantity;
        }

        public static function getProductQuantityPieces($idProduct, $orders)
        {
                $quantity = 0;

                if (isset($orders) && is_array($orders) && count($orders)) {
                        foreach ($orders as $c) {
                                if (is_null($c->date_delete)) {
                                        foreach ($c->productOrder as $po) {
                                                if ($po->id_product == $idProduct) {
                                                        if($po->unit == 'piece') {
                                                                $quantity += $po->quantity ;
                                                        }
                                                        else {
                                                                if(isset($po->product) && $po->product->weight > 0) {
                                                                        $quantity += ($po->quantity * Product::$unitsArray[$po->unit]['coefficient']) / $po->product->weight ;
                                                                }
                                                        }
                                                }
                                        }
                                }
                        }
                }

                return $quantity;
        }

        /**
         * Recherche et initialise des commandes.
         *
         * @param array $params
         * @param array $conditions
         * @param string $orderby
         * @param integer $limit
         * @return array
         */
        public static function searchBy($params = [], $options = [])
        {
                $orders = parent::searchBy($params, $options);

                /*
                 * Initialisation des commandes
                 */

                if (is_array($orders)) {
                        if (count($orders)) {
                                foreach ($orders as $order) {
                                        if (is_a($order, 'common\models\Order')) {
                                                $order->init();
                                        }
                                }
                                return $orders;
                        }
                } else {
                        $order = $orders;
                        if (is_a($order, 'common\models\Order')) {
                                return $order->init();
                        } // count
                        else {
                                return $order;
                        }
                }

                return false;
        }

        /**
         * Retourne le nombre de produits commandés
         *
         * @return integer
         */
        public function countProducts()
        {
                $count = 0;
                if ($this->productOrder && is_array($this->productOrder)) {
                        return count($this->productOrder) ;
                }
                return 0;
        }

        /**
         * Retourne un bloc html présentant une date.
         *
         * @return string
         */
        public function getBlockDate()
        {
                return '<div class="block-date">
                    <div class="day">' . strftime('%A', strtotime($this->distribution->date)) . '</div>
                    <div class="num">' . date('d', strtotime($this->distribution->date)) . '</div>
                    <div class="month">' . strftime('%B', strtotime($this->distribution->date)) . '</div>
                </div>';
        }

        public function getUsername()
        {
                $username = '' ;
                if($this->user) {
                        $username = $this->user->getUsername() ;
                }
                if(strlen($this->username)) {
                        $username = $this->username ;
                }
                return $username ;
        }

        public function initInvoicePrices($params = [])
        {
                foreach($this->productOrder as $productOrder) {
                        if($productOrder->product) {
                                $productOrder->invoice_price = $productOrder->product->getPrice([
                                        'user' => isset($params['user']) ? $params['user'] : null,
                                        'user_producer' => isset($params['user_producer']) ? $params['user_producer'] : null,
                                        'point_sale' => isset($params['point_sale']) ? $params['point_sale'] : null
                                ]) ;
                                $productOrder->save() ;
                        }
                }
        }

        public function initReference()
        {
                $idProducer = GlobalParam::getCurrentProducerId() ;
                $producer = Producer::findOne($idProducer) ;

                if(!$this->reference && $producer->option_order_reference_type == Producer::ORDER_REFERENCE_TYPE_YEARLY)
                {
                        $lastOrder = Order::find()->innerJoinWith('distribution', true)
                                ->where(['>=', 'distribution.date', date('Y').'-01-01'])
                                ->andWhere([
                                        'distribution.id_producer' => $producer->id
                                ])
                                ->andWhere(['not', ['order.reference' => null]])
                                ->orderBy('order.reference DESC')
                                ->one() ;

                        if($lastOrder && $lastOrder->reference && strlen($lastOrder->reference) > 0) {
                                $pattern = '#A([0-9]+)C([0-9]+)#';
                                preg_match($pattern, $lastOrder->reference, $matches, PREG_OFFSET_CAPTURE);
                                $sizeNumReference = strlen($matches[2][0]);
                                $numReference = ((int)$matches[2][0]) + 1;
                                $numReference = str_pad($numReference, $sizeNumReference, '0', STR_PAD_LEFT);

                                $this->reference = 'A'.$matches[1][0].'C'.$numReference ;
                        }
                        else {
                                $this->reference = 'A'.date('y').'C0001' ;
                        }

                        $this->save() ;
                }
        }

        public function getCommentReport()
        {
                $comment = '' ;

                $hasComment = false ;
                if($this->comment && strlen($this->comment) > 0) {
                        $hasComment = true ;
                        $comment .= $this->comment ;
                }

                if($this->delivery_home && $this->delivery_address && strlen($this->delivery_address) > 0) {
                        if($hasComment) {
                                $comment .= '<br /><br />' ;
                        }

                        $comment .= '<strong>Livraison à domicile :</strong><br />' ;
                        $comment .= nl2br($this->delivery_address) ;
                }

                return $comment ;
        }
}
