<?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 Yii;
use yii\helpers\Html;
use common\models\UserPointSale;
use common\models\PointSaleDistribution;
use common\components\ActiveRecordCommon;

/**
 * This is the model class for table "point_vente".
 *
 * @property integer $id
 * @property string $name
 * @property string $address
 * @property integer $id_producer
 * @property integer $default
 */
class PointSale extends ActiveRecordCommon
{
        var $orders = [];
        var $revenues = 0;
        var $revenues_with_tax = 0;
        var $data_select_orders;
        var $data_options_orders;
        var $users = [];
        var $users_comment = [];

        /**
         * @inheritdoc
         */
        public static function tableName()
        {
                return 'point_sale';
        }

        /**
         * @inheritdoc
         */
        public function rules()
        {
                return [
                        [['name'], 'required'],
                        [['restricted_access'], 'boolean'],
                        [['name', 'code'], 'string', 'max' => 255],
                        [['address', 'locality', 'infos_monday', 'infos_tuesday',
                                'infos_wednesday', 'infos_thursday', 'infos_friday',
                                'infos_saturday', 'infos_sunday', 'credit_functioning'], 'string'],
                        [['point_production', 'credit', 'delivery_monday', 'delivery_tuesday',
                                'delivery_wednesday', 'delivery_thursday', 'delivery_friday',
                                'delivery_saturday', 'delivery_sunday', 'default'], 'boolean'],
                        ['point_production', 'default', 'value' => 0],
                        [['id_producer', 'id_user'], 'integer'],
                        ['id_producer', 'required'],
                        [['users', 'users_comment', 'code'], 'safe'],
                        [['product_price_percent'], 'double'],
                ];
        }

        /**
         * @inheritdoc
         */
        public function attributeLabels()
        {
                return [
                        'id' => 'ID',
                        'name' => 'Nom',
                        'address' => 'Adresse',
                        'locality' => 'Localité',
                        'point_production' => 'Point de production',
                        'infos_monday' => 'Lundi',
                        'infos_tuesday' => 'Mardi',
                        'infos_wednesday' => 'Mercredi',
                        'infos_thursday' => 'Jeudi',
                        'infos_friday' => 'Vendredi',
                        'infos_saturday' => 'Samedi',
                        'infos_sunday' => 'Dimanche',
                        'restricted_access' => 'Accès restreint',
                        'credit' => 'Activer le Crédit',
                        'delivery_monday' => 'Lundi',
                        'delivery_tuesday' => 'Mardi',
                        'delivery_wednesday' => 'Mercredi',
                        'delivery_thursday' => 'Jeudi',
                        'delivery_friday' => 'Vendredi',
                        'delivery_saturday' => 'Samedi',
                        'delivery_sunday' => 'Dimanche',
                        'code' => 'Code',
                        'credit_functioning' => 'Utilisation du Crédit par l\'utilisateur',
                        'default' => 'Point de vente par défaut',
                        'id_user' => 'Contact',
                        'product_price_percent' => 'Prix produits : pourcentage'
                ];
        }

        /*
         * Relations
         */

        public function getUserPointSale()
        {
                return $this->hasMany(
                        UserPointSale::className(),
                        ['id_point_sale' => 'id']
                );
        }

        public function getPointSaleDistribution()
        {
                return $this->hasMany(
                        PointSaleDistribution::className(),
                        ['id_point_sale' => 'id']
                );
        }

        public function getUser()
        {
                return $this->hasOne(
                        User::className(),
                        ['id' => 'id_user']
                ) ;
        }

        /**
         * Retourne les options de base nécessaires à la fonction de recherche.
         *
         * @return array
         */
        public static function defaultOptionsSearch()
        {
                return [
                        'with' => [],
                        'join_with' => [],
                        'orderby' => '',
                        'attribute_id_producer' => 'point_sale.id_producer'
                ];
        }

        /**
         * Initialise les commandes liées au point de vente.
         *
         * @param array $ordersArray
         */
        public function initOrders($ordersArray)
        {
                $this->orders = [];
                $this->revenues = 0;
                $this->revenues_with_tax = 0;

                if ($ordersArray) {
                        foreach ($ordersArray as $order) {
                                if ($this->id == $order->id_point_sale) {
                                        $this->orders[] = $order;

                                        if (is_null($order->date_delete)) {
                                                $this->revenues += (float)$order->amount;
                                                $this->revenues_with_tax += (float)$order->amount_with_tax;
                                        }
                                }
                        }
                }
        }

        /**
         * Retourne les commandes liées à ce point de vente.
         *
         * @return array
         */
        public function getOrders()
        {
                return $this->orders;
        }

        /**
         * Enregistre le point de vente.
         *
         * @param boolean $runValidation
         * @param array $attributeNames
         * @return type
         */
        public function save($runValidation = true, $attributeNames = NULL)
        {
                $this->id_producer = GlobalParam::getCurrentProducerId();
                return parent::save($runValidation, $attributeNames);
        }

        /**
         * Traite la mise à jour de l'attribut 'point_production'.
         */
        public function processPointProduction()
        {
                if ($this->point_production) {
                        PointSale::updateAll(
                                ['point_production' => 0],
                                ['id_producer' => $this->id_producer]
                        );
                        $this->point_production = 1;
                        $this->save();
                }
        }

        /**
         * Traite les accès restreints d'un point de vente.
         */
        public function processRestrictedAccess()
        {
                UserPointSale::deleteAll(['id_point_sale' => $this->id]);

                if (is_array($this->users) && count($this->users)) {
                        foreach ($this->users as $key => $val) {
                                $user = User::findOne($val);
                                if ($user) {
                                        $userPointSale = new UserPointSale;
                                        $userPointSale->id_user = $val;
                                        $userPointSale->id_point_sale = $this->id;
                                        if (isset($this->users_comment[$val]) && strlen($this->users_comment[$val])) {
                                                $userPointSale->comment = $this->users_comment[$val];
                                        }
                                        $userPointSale->save();
                                }
                        }
                }
        }

        /**
         * Retourne le commentaire de l'utilisateur courant lié au point de vente.
         *
         * @return string|null
         */
        public function getComment()
        {
                if (isset($this->userPointSale)) {
                        foreach ($this->userPointSale as $userPointSale) {
                                if ($userPointSale->id_user == User::getCurrentId()) {
                                        return $userPointSale->comment;
                                }
                        }
                }
                return null;
        }

        /**
         * Retourne le nombre de points de vente pour l'établissement courant.
         *
         * @return integer
         */
        public static function count()
        {
                return self::searchCount(['id_producer' => GlobalParam::getCurrentProducerId()]);
        }

        /**
         * Vérifie le code d'accès à un point de vente.
         *
         * @param string $code
         * @return boolean
         */
        public function validateCode($code)
        {
                if (strlen($this->code)) {
                        if (trim(strtolower($code)) == trim(strtolower($this->code))) {
                                return true;
                        } else {
                                return false;
                        }
                }

                return true;
        }

        /**
         * Retourne les jours de livraison du point de vente sous forme d'une chaine
         * de caractères.
         *
         * @return string
         */
        public function getStrDeliveryDays()
        {
                $str = '';

                if ($this->delivery_monday) $str .= 'lundi, ';
                if ($this->delivery_tuesday) $str .= 'mardi, ';
                if ($this->delivery_wednesday) $str .= 'mercredi, ';
                if ($this->delivery_thursday) $str .= 'jeudi, ';
                if ($this->delivery_friday) $str .= 'vendredi, ';
                if ($this->delivery_saturday) $str .= 'samedi, ';
                if ($this->delivery_sunday) $str .= 'dimanche, ';

                if (strlen($str)) {
                        return substr($str, 0, strlen($str) - 2);
                } else {
                        return '';
                }
        }

        /**
         * Retourne un commentaire informant l'utilisateur sur les détails de
         * livraison d'un point de vente et pour un jour donné.
         *
         * @param string $jour
         * @return string
         */
        public function getStrInfos($day)
        {
                $str = '';
                $field = 'infos_' . $day;

                if (strlen($this->$field)) {
                        $str = nl2br(Html::encode($this->$field));
                        $str = preg_replace('/\[select_previous_day\](.*?)\[\/select_previous_day\]/', '<a href="javascript:void(0);" class="select-previous-day">$1</a>', $str);
                }
                return $str;
        }

        /**
         * Retourne le mode de fonctionnement du crédit du point de vente.
         *
         * @return string
         */
        public function getCreditFunctioning()
        {
                return strlen($this->credit_functioning) > 0 ?
                        $this->credit_functioning :
                        Producer::getConfig('credit_functioning');
        }

        /**
         * Lie un utilisateur au point de vente.
         *
         * @param integer $idUser
         */
        public function linkUser($idUser)
        {
                if ($idUser) {
                        $userPointSale = UserPointSale::find()
                                ->where([
                                        'id_user' => $idUser,
                                        'id_point_sale' => $this->id
                                ])->one();

                        if (!$userPointSale) {
                                $userPointSale = new UserPointSale;
                                $userPointSale->id_user = $idUser;
                                $userPointSale->id_point_sale = $this->id;
                                $userPointSale->save();
                        }
                }
        }

        public static function populateDropdownList()
        {
                $pointSalesArrayDropdown = ['' => '--'] ;
                $pointSalesArray = PointSale::find()->where('id_producer = ' . GlobalParam::getCurrentProducerId())->all() ;

                foreach($pointSalesArray as $pointSale) {
                        $pointSalesArrayDropdown[$pointSale['id']] = $pointSale['name'] ;
                }

                return $pointSalesArrayDropdown ;
        }
}
