|
- <?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 Yii;
- use common\components\ActiveRecordCommon ;
- use common\models\Producer;
- use common\models\PointSale;
- use common\models\UserPointSale;
- use common\models\Order;
- use common\models\ProductOrder;
- use common\models\User ;
-
- /**
- * 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
- */
- class Subscription extends ActiveRecordCommon
- {
- /**
- * @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'], 'integer'],
- [['auto_payment'], 'boolean'],
- [['date_begin', 'date_end', 'username'], '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'
- ];
- }
-
- /*
- * 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;
-
- $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 ;
- }
- }
|