'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' ]; } /* * 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; $order->auto_payment = $this->auto_payment ; $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(); // 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->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)) ]) ; if ($distribution) { $countOrdersProd = Order::searchCount([ Order::tableName().'.id_distribution' => $distribution->id ]) ; if (!$countOrdersProd || $force) { $subscriptions = self::searchByDate($date); foreach ($subscriptions as $s) { $s->add($date); } } } } /** * 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 ($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 ]; $orders = Order::find() ->joinWith('distribution') ->where('distribution.id_producer = :id_producer') ->andWhere('distribution.date >= :date_today') ->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() ; if($ordersArray && count($ordersArray)) { foreach($ordersArray as $order) { 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) ; } } } }