|
- <?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\GlobalParam;
- use common\models\PointSale;
- use common\models\User;
- use Yii;
- use common\components\ActiveRecordCommon;
- use common\models\Producer;
- use common\models\UserPointSale;
- use common\models\Order;
- use common\models\ProductOrder;
-
- /**
- * This is the model class for table "commande_auto".
- *
- * @property integer $id
- * @property integer $id_user
- * @property integer $id_producer
- * @property integer $id_point_sale
- * @property string $date_begin
- * @property string $date_end
- * @property integer $monday
- * @property integer $tuesday
- * @property integer $wednesday
- * @property integer $thursday
- * @property integer $friday
- * @property integer $saturday
- * @property integer $sunday
- * @property integer $week_frequency
- * @property string $username
- * @property string $auto_payment
- * @property string $comment
- */
- class Subscription extends ActiveRecordCommon
- {
- const AUTO_PAYMENT_DEDUCTED = 1;
- const AUTO_PAYMENT_YES = 2;
- const AUTO_PAYMENT_NO = 0;
-
-
- /**
- * @inheritdoc
- */
- public static function tableName()
- {
- return 'subscription';
- }
-
- /**
- * @inheritdoc
- */
- public function rules()
- {
- return [
- [['id_producer', 'id_point_sale'], 'required'],
- [['id_user', 'id_producer', 'id_point_sale', 'monday', 'tuesday',
- 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'week_frequency', 'auto_payment'], 'integer'],
- [['username', 'comment', 'date_begin', 'date_end'], 'safe'],
- ];
- }
-
- /**
- * @inheritdoc
- */
- public function attributeLabels()
- {
- return [
- 'id' => '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, $force = false)
- {
- // distribution
- $now = date('Y-m-d');
- $distributionDate = date('Y-m-d', strtotime($date));
- $distribution = Distribution::searchOne([
- 'distribution.date' => $distributionDate
- ]);
-
- if ($distribution
- && $distribution->active
- && ($distributionDate > $now || $force)
- && count($this->productSubscription)
- && $this->id_point_sale) {
-
- // commande
- $order = new Order;
- if (strlen($this->username)) {
- $order->username = $this->username;
- $order->id_user = 0;
- } else {
- $order->id_user = $this->id_user;
- }
-
- $user = false;
- if ($this->id_user) {
- $user = User::findOne($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->status = 'tmp-order';
- if (strlen($this->comment)) {
- $order->comment = $this->comment;
- }
-
- $pointSale = PointSale::findOne($this->id_point_sale);
-
- if ($pointSale) {
- $order->auto_payment = 0;
- if($this->auto_payment == self::AUTO_PAYMENT_DEDUCTED) {
- $order->auto_payment = $order->isCreditAutoPayment();
- }
- elseif($this->auto_payment == self::AUTO_PAYMENT_YES) {
- $order->auto_payment = 1;
- }
- elseif($this->auto_payment == self::AUTO_PAYMENT_NO) {
- $order->auto_payment = 0;
- }
-
- $order->tiller_synchronization = $order->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();
-
- // liaison utilisateur / point de vente
- if ($order->id_user) {
- $pointSale = PointSale::findOne($this->id_point_sale);
- $pointSale->linkUser($order->id_user);
- }
-
- // produits
- $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->getPrice([
- 'user' => $user,
- 'point_sale' => $pointSale,
- 'quantity' => $productSubscription->quantity
- ]);
- $productOrder->unit = $productSubscription->product->unit;
- $productOrder->step = $productSubscription->product->step;
- $productOrder->id_tax_rate = $productSubscription->product->taxRate->id;
- $productOrder->save();
- $productsAdd = true;
- }
-
- if (!$productsAdd) {
- $order->delete();
- }
-
- $order->initReference();
- }
- }
- }
-
- /**
- * 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' => GlobalParam::getCurrentProducerId(),
- ]);
-
- 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, $force);
- }
- }
- }
- }
-
- /**
- * 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()
- {
- $params = [
- ':date_earliest_order' => date('Y-m-d'),
- ':date_begin' => date('Y-m-d', strtotime($this->date_begin)),
- ':id_producer' => GlobalParam::getCurrentProducerId()
- ];
-
- $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();
- Distribution::filterDistributionsByDateDelay($incomingDistributionsArray);
-
- $matchedIncomingDistributionsArray = [];
- foreach ($incomingDistributionsArray as $incomingDistribution) {
- if ($this->matchWith($incomingDistribution->date)) {
- $matchedIncomingDistributionsArray[] = $incomingDistribution;
- }
- }
-
- return $matchedIncomingDistributionsArray;
- }
-
- public function deleteOrdersIncomingDistributions($deleteAfterDateEnd = false)
- {
- $dateStart = $this->date_begin;
- $comparatorDateStart = '>=';
- if($deleteAfterDateEnd) {
- $dateStart = $this->date_end;
- $comparatorDateStart = '>';
- }
-
- $params = [
- ':id_producer' => GlobalParam::getCurrentProducerId(),
- ':date_today' => date('Y-m-d'),
- ':date_start' => $dateStart,
- ':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 '.$comparatorDateStart.' :date_start')
- ->andWhere('order.id_subscription = :id_subscription');
-
- $orders->params($params);
-
- $ordersArray = $orders->all();
- $configCredit = Producer::getConfig('credit');
-
- $countOrdersDeleted = 0;
- 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()
- );
- }
-
- $order->delete(true);
-
- $countOrdersDeleted ++;
- }
- }
-
- return $countOrdersDeleted;
- }
-
- public function updateIncomingDistributions($update = false)
- {
- $matchedDistributionsArray = $this->searchMatchedIncomingDistributions();
-
- if ($update) {
- $this->deleteOrdersIncomingDistributions();
- }
-
- if (count($matchedDistributionsArray)) {
- foreach ($matchedDistributionsArray as $distribution) {
- $this->add($distribution->date);
- }
- }
- }
-
- public function getUsername()
- {
- if ($this->user) {
- return $this->user->getUsername();
- }
-
- return $this->username;
- }
-
-
- }
|