''], [['id_user', 'id_point_sale', 'id_distribution','id_subscription'], 'integer'], [['auto_payment', 'tiller_synchronization'], 'boolean'], [['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', ]; } /* * Relations */ public function getUser() { return $this->hasOne(User::className(), ['id' => 'id_user']); } public function getProductOrder() { return $this->hasMany(ProductOrder::className(),['id_order' => 'id']) ->with('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'); } /** * 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() { if (isset($this->productOrder)) { foreach ($this->productOrder as $productOrder) { $this->amount += $productOrder->price * $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, Producer::getId(), $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() ; } } /** * 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) { switch($type) { case self::AMOUNT_TOTAL : $amount = $this->amount ; break ; case self::AMOUNT_PAID : $this->initPaidAmount() ; $amount = $this->paid_amount ; break ; case self::AMOUNT_REMAINING : $amount = $this->getAmount(self::AMOUNT_TOTAL) - $this->getAmount(self::AMOUNT_PAID) ; break ; case self::AMOUNT_SURPLUS : $amount = $this->getAmount(self::AMOUNT_PAID) - $this->getAmount(self::AMOUNT_TOTAL) ; break ; } if ($format) { return number_format($amount, 2) . ' €'; } 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->getAmount(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, Producer::getId(), $this->id_user, User::getCurrentId() ); } } /** * Retourne le statut de paiement de la commande (payée, surplus, ou impayée). * * @return string */ public function getPaymentStatus() { // payé if ($this->getAmount() - $this->getAmount(self::AMOUNT_PAID) < 0.01 && $this->getAmount() - $this->getAmount(self::AMOUNT_PAID) > -0.01) { return self::PAYMENT_PAID ; } // à rembourser elseif ($this->getAmount() - $this->getAmount(self::AMOUNT_PAID) <= -0.01) { return self::PAYMENT_SURPLUS ; } // reste à payer elseif ($this->getAmount() - $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() { 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 .' '.Product::strUnit($p->unit, 'wording_short', true).')'; if (++$i != $count) { $html .= '
'; } } } 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 .= '' . Html::encode($this->pointSale->name) . '' . '
' . Html::encode($this->pointSale->locality) . ''; if (strlen($this->comment_point_sale)) { $html .= '
' . Html::encode($this->comment_point_sale) . '
'; } } else { $html .= 'Point de vente supprimé'; } return $html; } /** * Retourne le résumé du paiement (montant, statut). * * @return string */ public function getAmountSummary() { $html = ''; $html .= $this->getAmount(self::AMOUNT_TOTAL, true) . '
'; if ($this->paid_amount) { if ($this->getPaymentStatus() == Order::PAYMENT_PAID) { $html .= 'Payée'; } elseif ($this->getPaymentStatus() == Order::PAYMENT_UNPAID) { $html .= 'Non payée
Reste ' . $this->getAmount(Order::AMOUNT_REMAINING, true) . ' à payer'; } elseif ($this->getPaymentStatus() == Order::PAYMENT_SURPLUS) { $html .= 'Payée'; } } else { $html .= 'Non réglé'; } return $html; } /** * Retourne une chaine de caractère décrivant l'utilisateur lié à la commande. * * @return string */ public function getStrUser() { if (isset($this->user)) { 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() { $orderDelay = Producer::getConfig( 'order_delay', $this->distribution->id_producer ); $orderDeadline = Producer::getConfig( 'order_deadline', $this->distribution->id_producer ); $orderDate = strtotime($this->distribution->date); $today = strtotime(date('Y-m-d')); $todayHour = date('G'); $nbDays = (int) (($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 '' . $str . ''; } 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 = '
' . ' ' . $arr['str'].' le ' . date('d/m/Y à G\hi', strtotime($arr['date'])).'
' ; 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 ; } /** * 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)) { foreach($this->productOrder as $productOrder) { if($productOrder->unit == 'piece') { $count ++ ; } else { $count += $productOrder->quantity ; } } } return $count ; } /** * Retourne un bloc html présentant une date. * * @return string */ public function getBlockDate() { return '
'.strftime('%A', strtotime($this->distribution->date)).'
'.date('d', strtotime($this->distribution->date)).'
'.strftime('%B', strtotime($this->distribution->date)).'
' ; } }