'ID', 'id_user' => 'Utilisateur', 'id_producer' => 'Etablissement', 'id_point_sale' => 'Point de vente', 'date_begin' => 'Date de début', 'date_end' => 'Date de fin', 'monday' => 'Lundi', 'tuesday' => 'Mardi', 'wednesday' => 'Mercredi', 'thursday' => 'Jeudi', 'friday' => 'Vendredi', 'saturday' => 'Samedi', 'sunday' => 'Dimanche', 'week_frequency' => 'Périodicité', 'auto_payment' => 'Paiement automatique', 'comment' => 'Commentaire' ]; } /* * Relations */ public function getUser() { return $this->hasOne(User::className(), ['id' => 'id_user']); } public function getProducer() { return $this->hasOne( Producer::className(), ['id' => 'id_producer'] ); } public function getPointSale() { return $this->hasOne( PointSale::className(), ['id' => 'id_point_sale'] ); } public function getProductSubscription() { return $this->hasMany( ProductSubscription::className(), ['id_subscription' => 'id'] )->with('product'); } /** * Retourne les options de base nécessaires à la fonction de recherche. * * @return array */ public static function defaultOptionsSearch() { return [ 'with' => ['producer'], 'join_with' => ['user', 'productSubscription', 'productSubscription.product', 'pointSale'], 'orderby' => 'user.name ASC', 'attribute_id_producer' => 'subscription.id_producer' ] ; } /** * Ajoute la commande pour une date donnée. * * @param string $date */ public function add($date) { // distribution $distribution = Distribution::searchOne([ 'distribution.date' => date('Y-m-d', strtotime($date)) ]) ; if ($distribution && count($this->productSubscription)) { // commande $order = new Order; if (strlen($this->username)) { $order->username = $this->username; $order->id_user = 0; } else { $order->id_user = $this->id_user; } $order->date = date('Y-m-d H:i:s'); $order->origin = Order::ORIGIN_AUTO; $order->id_point_sale = $this->id_point_sale; $order->id_distribution = $distribution->id; $order->id_subscription = $this->id; if(strlen($this->comment)) { $order->comment = $this->comment ; } $pointSale = PointSale::findOne($this->id_point_sale) ; $creditFunctioning = $pointSale->getCreditFunctioning() ; $order->auto_payment = 0 ; if($order->id_user && Producer::getConfig('credit') && $pointSale->credit) { if($creditFunctioning == Producer::CREDIT_FUNCTIONING_OPTIONAL) { $order->auto_payment = $this->auto_payment ; } elseif($creditFunctioning == Producer::CREDIT_FUNCTIONING_MANDATORY) { $order->auto_payment = 1 ; } elseif($creditFunctioning == Producer::CREDIT_FUNCTIONING_USER) { $user = User::findOne($order->id_user) ; $userProducer = UserProducer::searchOne([ 'id_user' => $order->id_user, 'id_producer' => $distribution->id_producer ]) ; if($userProducer) { $order->auto_payment = $userProducer->credit_active ; } } } $userPointSale = UserPointSale::searchOne([ 'id_point_sale' => $this->id_point_sale, 'id_user' => $this->id_user ]) ; if ($userPointSale && strlen($userPointSale->comment)) { $order->comment_point_sale = $userPointSale->comment; } $order->save(); // liaison utilisateur / point de vente if($order->id_user) { $pointSale = PointSale::findOne($this->id_point_sale) ; $pointSale->linkUser($order->id_user) ; } // produits $amountTotal = 0; $productsAdd = false; foreach ($this->productSubscription as $productSubscription) { $productOrder = new ProductOrder; $productOrder->id_order = $order->id; $productOrder->id_product = $productSubscription->product->id; $productOrder->quantity = $productSubscription->quantity; $productOrder->price = $productSubscription->product->price; $productOrder->unit = $productSubscription->unit; $productOrder->step = $productSubscription->step; $productOrder->save(); $productsAdd = true; } if (!$productsAdd) { $order->delete(); } } } /** * Ajoute les commandes pour une date donnée à partir des abonnements. * * @param string $date * @param boolean $force */ public static function addAll($date, $force = false) { $distribution = Distribution::searchOne([ 'date' => date('Y-m-d', strtotime($date)), 'id_producer' => Producer::getId(), ]) ; if ($distribution) { $arrayOrdersDistribution = Order::searchAll([ Order::tableName().'.id_distribution' => $distribution->id ]); $arraySubscriptions = self::searchByDate($date); foreach ($arraySubscriptions as $subscription) { if(!$subscription->hasOrderAlreadyExist($arrayOrdersDistribution)) { $subscription->add($date); } } } } /** * Informe s'il existe une commande correspond à l'abonnement courant. * * @param array $arrayOrders * @return boolean */ public function hasOrderAlreadyExist($arrayOrders) { if(is_array($arrayOrders) && count($arrayOrders) > 0) { foreach($arrayOrders as $order) { if((($order->id_user > 0 && $order->id_user == $this->id_user) || (!$order->id_user && $order->username == $this->username)) && $order->id_point_sale == $this->id_point_sale) { return true ; } } } return false ; } /** * Retourne les abonnements pour une date donnée. * * @param string $date * @return array */ public static function searchByDate($date) { $date = date('Y-m-d', strtotime($date)); $subscriptions = Subscription::searchAll() ; $arrSubscriptions = []; foreach ($subscriptions as $s) { if ($date >= $s->date_begin && (!$s->date_end || $date <= $s->date_end) && $s->matchWith($date)) { $arrSubscriptions[] = $s; } } return $arrSubscriptions; } /** * Valide le fait qu'un abonnement est bien compatible avec une date donnée. * * @param string $date * @return boolean */ public function matchWith($date) { $arrayDays = [ 1 => 'monday', 2 => 'tuesday', 3 => 'wednesday', 4 => 'thursday', 5 => 'friday', 6 => 'saturday', 7 => 'sunday' ] ; $nbDays = (strtotime($date) - strtotime($this->date_begin)) / (24 * 60 * 60); if (round($nbDays) % ($this->week_frequency * 7) < 7) { $numDay = date('N', strtotime($date)); $day = $arrayDays[$numDay] ; if ($this->$day) { return true ; } } return false ; } /** * Recherche les distributions futures où l'abonnement peut s'appliquer. * * @return array */ public function searchMatchedIncomingDistributions() { $producer = Producer::getCurrent() ; $params = [ ':date_earliest_order' => $producer->getEarliestDateOrder(), ':date_begin' => date('Y-m-d', strtotime($this->date_begin)), ':id_producer' => Producer::getId() ] ; $incomingDistributions = Distribution::find() ->where('id_producer = :id_producer') ->andWhere('date >= :date_begin') ->andWhere('date >= :date_earliest_order') ; if($this->date_end) { $incomingDistributions->andWhere('date < :date_end') ; $params[':date_end'] = date('Y-m-d', strtotime($this->date_end)) ; } $incomingDistributions->orderBy('date ASC') ; $incomingDistributions->params($params) ; $incomingDistributionsArray = $incomingDistributions->all() ; $matchedIncomingDistributionsArray = [] ; foreach($incomingDistributionsArray as $incomingDistribution) { if($this->matchWith($incomingDistribution->date)) { $matchedIncomingDistributionsArray[] = $incomingDistribution ; } } return $matchedIncomingDistributionsArray ; } public function deleteOrdersIncomingDistributions() { $params = [ ':id_producer' => Producer::getId(), ':date_today' => date('Y-m-d'), ':date_begin' => $this->date_begin, ':id_subscription' => $this->id ]; $orderDeadline = Producer::getConfig('order_deadline') ; $hour = date('G') ; if($hour >= $orderDeadline) { $conditionDistributionDate = 'distribution.date > :date_today' ; } else { $conditionDistributionDate = 'distribution.date >= :date_today' ; } $orders = Order::find() ->joinWith('distribution') ->where('distribution.id_producer = :id_producer') ->andWhere($conditionDistributionDate) ->andWhere('distribution.date >= :date_begin') ->andWhere('order.id_subscription = :id_subscription') ; if($this->date_end) { $orders->andWhere('distribution.date <= :date_end') ; $params[':date_end'] = $this->date_end ; } $orders->params($params) ; $ordersArray = $orders->all() ; $configCredit = Producer::getConfig('credit') ; if($ordersArray && count($ordersArray)) { foreach($ordersArray as $order) { $theOrder = Order::searchOne(['id' => $order->id]) ; // remboursement de la commande if ($theOrder->id_user && $theOrder->getAmount(Order::AMOUNT_PAID) && $configCredit) { $theOrder->saveCreditHistory( CreditHistory::TYPE_REFUND, $theOrder->getAmount(Order::AMOUNT_PAID), $theOrder->distribution->id_producer, $theOrder->id_user, User::getCurrentId() ); } ProductOrder::deleteAll(['id_order' => $order->id]) ; $order->delete() ; } } } public function updateIncomingDistributions($update = false) { $matchedDistributionsArray = $this->searchMatchedIncomingDistributions() ; if($update) { $this->deleteOrdersIncomingDistributions() ; } if(count($matchedDistributionsArray)) { foreach($matchedDistributionsArray as $distribution) { $this->add($distribution->date) ; } } } /** * Retourne true si des unités des ProductSubscription ne correspondent pas * aux Product. * * @return boolean */ public function hasUnitsNotMatch() { if(isset($this->productSubscription) && is_array($this->productSubscription)) { foreach($this->productSubscription as $productSubscription) { if(isset($productSubscription->product) && $productSubscription->unit != $productSubscription->product->unit) { return true ; } } } return false ; } }