You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

931 lines
33KB

  1. <?php
  2. /**
  3. * Copyright distrib (2018)
  4. *
  5. * contact@opendistrib.net
  6. *
  7. * Ce logiciel est un programme informatique servant à aider les producteurs
  8. * à distribuer leur production en circuits courts.
  9. *
  10. * Ce logiciel est régi par la licence CeCILL soumise au droit français et
  11. * respectant les principes de diffusion des logiciels libres. Vous pouvez
  12. * utiliser, modifier et/ou redistribuer ce programme sous les conditions
  13. * de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
  14. * sur le site "http://www.cecill.info".
  15. *
  16. * En contrepartie de l'accessibilité au code source et des droits de copie,
  17. * de modification et de redistribution accordés par cette licence, il n'est
  18. * offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
  19. * seule une responsabilité restreinte pèse sur l'auteur du programme, le
  20. * titulaire des droits patrimoniaux et les concédants successifs.
  21. *
  22. * A cet égard l'attention de l'utilisateur est attirée sur les risques
  23. * associés au chargement, à l'utilisation, à la modification et/ou au
  24. * développement et à la reproduction du logiciel par l'utilisateur étant
  25. * donné sa spécificité de logiciel libre, qui peut le rendre complexe à
  26. * manipuler et qui le réserve donc à des développeurs et des professionnels
  27. * avertis possédant des connaissances informatiques approfondies. Les
  28. * utilisateurs sont donc invités à charger et tester l'adéquation du
  29. * logiciel à leurs besoins dans des conditions permettant d'assurer la
  30. * sécurité de leurs systèmes et ou de leurs données et, plus généralement,
  31. * à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
  32. *
  33. * Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
  34. * pris connaissance de la licence CeCILL, et que vous en avez accepté les
  35. * termes.
  36. */
  37. namespace common\logic\Producer;
  38. use common\logic\User\UserModel;
  39. use common\models\TaxRate;
  40. use common\logic\UserProducer\UserProducerModel;
  41. use Yii;
  42. use common\components\ActiveRecordCommon;
  43. use common\helpers\Departments;
  44. use yii\helpers\Html;
  45. /**
  46. * This is the model class for table "etablissement".
  47. *
  48. * @property integer $id
  49. * @property string $name
  50. * @property string $siret
  51. * @property string $logo
  52. * @property string $photo
  53. * @property string $description
  54. * @property string $postcode
  55. * @property string $city
  56. * @property float credit_limit_reminder
  57. * @property boolean online_payment
  58. * @property string mentions
  59. * @property string gcs
  60. * @property boolean option_allow_user_gift
  61. * @property string credit_functioning
  62. * @property boolean use_credit_checked_default
  63. * @property float credit_limit
  64. * @property string background_color_logo
  65. *
  66. */
  67. class ProducerModel extends ActiveRecordCommon
  68. {
  69. const CREDIT_FUNCTIONING_MANDATORY = 'mandatory';
  70. const CREDIT_FUNCTIONING_OPTIONAL = 'optional';
  71. const CREDIT_FUNCTIONING_USER = 'user';
  72. const HINT_CREDIT_FUNCTIONING = '<ul>'
  73. . '<li>Optionnelle : l\'utilisateur choisit s\'il utilise son Crédit ou non. Les commandes peuvent être payées ou impayées.</li>'
  74. . '<li>Obligatoire : toutes les commandes de l\'utilisateur son comptabilisées au niveau du Crédit. Toutes les commandes sont payées.</li>'
  75. . '<li>Basée sur l\'utilisateur : Crédit obligatoire si l\'utilisateur a le crédit activé au niveau de son compte, système de Crédit non affiché sinon.</li>'
  76. . '</ul>';
  77. public static $creditFunctioningArray = [
  78. self::CREDIT_FUNCTIONING_MANDATORY => 'Obligatoire',
  79. self::CREDIT_FUNCTIONING_OPTIONAL => 'Optionnelle',
  80. self::CREDIT_FUNCTIONING_USER => 'Basée sur l\'utilisateur',
  81. ];
  82. const BEHAVIOR_DELETE_ORDER_DELETE = 'delete';
  83. const BEHAVIOR_DELETE_ORDER_STATUS = 'status';
  84. const BEHAVIOR_HOME_POINT_SALE_DAY_LIST_WEEK = 'days-of-week';
  85. const BEHAVIOR_HOME_POINT_SALE_DAY_LIST_INCOMING_DISTRIBUTIONS = 'incoming-distributions';
  86. const BEHAVIOR_ORDER_SELECT_DISTRIBUTION_CALENDAR = 'calendar';
  87. const BEHAVIOR_ORDER_SELECT_DISTRIBUTION_LIST = 'list';
  88. const ORDER_REFERENCE_TYPE_NONE = '';
  89. const ORDER_REFERENCE_TYPE_YEARLY = 'yearly';
  90. const ORDER_ENTRY_POINT_DATE = 'date';
  91. const ORDER_ENTRY_POINT_POINT_SALE = 'point-sale';
  92. const BILLING_FREQUENCY_MONTHLY = 'monthly';
  93. const BILLING_FREQUENCY_QUARTERLY = 'quarterly';
  94. const BILLING_FREQUENCY_BIANNUAL = 'biannual';
  95. public static $billingFrequencyArray = [
  96. self::BILLING_FREQUENCY_MONTHLY => 'Mensuelle',
  97. self::BILLING_FREQUENCY_QUARTERLY => 'Trimestrielle',
  98. self::BILLING_FREQUENCY_BIANNUAL => 'Biannuelle',
  99. ];
  100. const BILLING_TYPE_CLASSIC = 'classic';
  101. const BILLING_TYPE_FREE_PRICE = 'free-price';
  102. public static $billingTypeArray = [
  103. self::BILLING_TYPE_CLASSIC => 'Classique',
  104. self::BILLING_TYPE_FREE_PRICE => 'Prix libre',
  105. ];
  106. var $secret_key_payplug;
  107. const ONLINE_PAYMENT_MINIMUM_AMOUNT_DEFAULT = 25;
  108. /**
  109. * @inheritdoc
  110. */
  111. public static function tableName()
  112. {
  113. return 'producer';
  114. }
  115. /**
  116. * @inheritdoc
  117. */
  118. public function rules()
  119. {
  120. return [
  121. [['name', 'type', 'id_tax_rate_default'], 'required'],
  122. [
  123. ['tiller_provider_token', 'tiller_restaurant_token'],
  124. 'required',
  125. 'when' => function ($model) {
  126. return $model->tiller == true;
  127. }
  128. ],
  129. [
  130. [
  131. 'order_delay',
  132. 'order_deadline',
  133. 'order_delay_monday',
  134. 'order_deadline_monday',
  135. 'order_delay_tuesday',
  136. 'order_deadline_tuesday',
  137. 'order_delay_wednesday',
  138. 'order_deadline_wednesday',
  139. 'order_delay_thursday',
  140. 'order_deadline_thursday',
  141. 'order_delay_friday',
  142. 'order_deadline_friday',
  143. 'order_delay_saturday',
  144. 'order_deadline_saturday',
  145. 'order_delay_sunday',
  146. 'order_deadline_sunday',
  147. 'id_tax_rate_default',
  148. 'document_quotation_duration',
  149. 'option_dashboard_number_distributions',
  150. 'option_online_payment_minimum_amount',
  151. 'option_document_price_decimals',
  152. 'option_billing_reduction_percentage',
  153. 'option_billing_permanent_transfer_amount',
  154. ],
  155. 'integer'
  156. ],
  157. [
  158. [
  159. 'order_deadline',
  160. 'order_deadline_monday',
  161. 'order_deadline_tuesday',
  162. 'order_deadline_wednesday',
  163. 'order_deadline_thursday',
  164. 'order_deadline_friday',
  165. 'order_deadline_saturday',
  166. 'order_deadline_sunday',
  167. ],
  168. 'in',
  169. 'range' => [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
  170. ],
  171. ['order_delay', 'in', 'range' => [1, 2, 3, 4, 5, 6, 7]],
  172. ['option_csv_separator', 'in', 'range' => [',', ';']],
  173. [
  174. 'code',
  175. function ($attribute, $params) {
  176. $code = $this->$attribute;
  177. $producer = ProducerModel::findOne(['code' => $code]);
  178. if ($producer && $producer->id != $this->id) {
  179. $this->addError($attribute, 'Ce code est déjà utilisé par un autre producteur.');
  180. }
  181. }
  182. ],
  183. [
  184. ['document_quotation_prefix', 'document_invoice_prefix', 'document_delivery_note_prefix'],
  185. function ($attribute, $params) {
  186. if (!ctype_upper($this->$attribute)) {
  187. $this->addError($attribute, 'Ne doit contenir que des majuscules');
  188. }
  189. }
  190. ],
  191. [
  192. [
  193. 'description',
  194. 'mentions',
  195. 'gcs',
  196. 'order_infos',
  197. 'slug',
  198. 'secret_key_payplug',
  199. 'background_color_logo',
  200. 'option_behavior_cancel_order',
  201. 'tiller_provider_token',
  202. 'tiller_restaurant_token',
  203. 'status',
  204. 'document_infos_bottom',
  205. 'document_infos_quotation',
  206. 'document_infos_invoice',
  207. 'document_infos_delivery_note',
  208. 'address',
  209. 'behavior_home_point_sale_day_list',
  210. 'behavior_order_select_distribution',
  211. 'option_payment_info',
  212. 'option_order_reference_type',
  213. 'option_order_entry_point',
  214. 'option_stripe_public_key',
  215. 'option_stripe_private_key',
  216. 'option_stripe_endpoint_secret',
  217. 'option_online_payment_type',
  218. 'option_tax_calculation_method',
  219. 'latest_version_opendistrib',
  220. 'option_csv_separator'
  221. ],
  222. 'string'
  223. ],
  224. [
  225. [
  226. 'negative_balance',
  227. 'credit',
  228. 'active',
  229. 'online_payment',
  230. 'user_manage_subscription',
  231. 'option_allow_user_gift',
  232. 'use_credit_checked_default',
  233. 'tiller',
  234. 'document_display_orders_invoice',
  235. 'document_display_orders_delivery_note',
  236. 'document_display_prices_delivery_note',
  237. 'document_display_product_description',
  238. 'option_email_confirm',
  239. 'option_email_confirm_producer',
  240. 'option_csv_export_all_products',
  241. 'option_csv_export_by_piece',
  242. 'option_export_display_product_reference',
  243. 'option_allow_order_guest',
  244. 'option_delivery',
  245. 'option_display_export_grid',
  246. 'option_stripe_mode_test',
  247. 'option_notify_producer_order_summary',
  248. 'option_billing_reduction',
  249. 'option_export_evoliz',
  250. 'option_display_message_new_opendistrib_version',
  251. 'option_billing_permanent_transfer'
  252. ],
  253. 'boolean'
  254. ],
  255. [
  256. [
  257. 'name',
  258. 'siret',
  259. 'logo',
  260. 'photo',
  261. 'postcode',
  262. 'city',
  263. 'code',
  264. 'type',
  265. 'credit_functioning',
  266. 'option_behavior_cancel_order',
  267. 'document_quotation_prefix',
  268. 'document_quotation_first_reference',
  269. 'document_invoice_prefix',
  270. 'document_invoice_first_reference',
  271. 'document_delivery_note_prefix',
  272. 'document_delivery_note_first_reference',
  273. 'option_billing_type',
  274. 'option_billing_frequency',
  275. ],
  276. 'string',
  277. 'max' => 255
  278. ],
  279. [['free_price', 'credit_limit_reminder', 'credit_limit'], 'double'],
  280. [
  281. 'free_price',
  282. 'compare',
  283. 'compareValue' => 0,
  284. 'operator' => '>=',
  285. 'type' => 'number',
  286. 'message' => 'Prix libre doit être supérieur ou égal à 0'
  287. ],
  288. [['option_dashboard_date_start', 'option_dashboard_date_end'], 'safe'],
  289. ];
  290. }
  291. /**
  292. * @inheritdoc
  293. */
  294. public function attributeLabels()
  295. {
  296. return [
  297. 'id' => 'ID',
  298. 'name' => 'Nom',
  299. 'siret' => 'Siret',
  300. 'logo' => 'Logo',
  301. 'photo' => 'Photo',
  302. 'description' => 'Description',
  303. 'postcode' => 'Code postal',
  304. 'city' => 'Ville',
  305. 'code' => "Code d'accès",
  306. 'order_delay' => 'Délai de commande',
  307. 'order_deadline' => 'Heure limite de commande',
  308. 'order_delay_monday' => 'Délai de commande (lundi)',
  309. 'order_deadline_monday' => 'Heure limite de commande (lundi)',
  310. 'order_delay_tuesday' => 'Délai de commande (mardi)',
  311. 'order_deadline_tuesday' => 'Heure limite de commande (mardi)',
  312. 'order_delay_wednesday' => 'Délai de commande (mercredi)',
  313. 'order_deadline_wednesday' => 'Heure limite de commande (mercredi)',
  314. 'order_delay_thursday' => 'Délai de commande (jeudi)',
  315. 'order_deadline_thursday' => 'Heure limite de commande (jeudi)',
  316. 'order_delay_friday' => 'Délai de commande (vendredi)',
  317. 'order_deadline_friday' => 'Heure limite de commande (vendredi)',
  318. 'order_delay_saturday' => 'Délai de commande (samedi)',
  319. 'order_deadline_saturday' => 'Heure limite de commande (samedi)',
  320. 'order_delay_sunday' => 'Délai de commande (dimanche)',
  321. 'order_deadline_sunday' => 'Heure limite de commande (dimanche)',
  322. 'negative_balance' => 'Solde négatif',
  323. 'credit' => 'Crédit pain',
  324. 'active' => 'Actif',
  325. 'date_creation' => 'Date de création',
  326. 'order_infos' => 'Informations',
  327. 'slug' => 'Slug',
  328. 'type' => 'Type de producteur',
  329. 'credit_limit_reminder' => 'Seuil de crédit limite avant relance',
  330. 'online_payment' => 'Activer le paiement en ligne (Stripe)',
  331. 'option_online_payment_type' => 'Type de paiement',
  332. 'option_stripe_mode_test' => 'Mode test',
  333. 'option_stripe_public_key' => 'Clé publique',
  334. 'option_stripe_private_key' => 'Clé secrète',
  335. 'option_stripe_endpoint_secret' => 'Clé secrète (endpoint)',
  336. 'user_manage_subscription' => 'Autoriser les utilisateurs à gérer leurs abonnements',
  337. 'mentions' => 'Mentions légales',
  338. 'gcs' => 'Conditions générales de vente',
  339. 'option_allow_user_gift' => 'Autoriser les utilisateurs à effectuer un don à la plateforme lors de leur commande',
  340. 'credit_functioning' => 'Utilisation du Crédit par l\'utilisateur',
  341. 'credit_limit' => 'Crédit limite',
  342. 'use_credit_checked_default' => 'Cocher par défaut l\'option "Utiliser mon crédit" lors de la commande de l\'utilisateur',
  343. 'background_color_logo' => 'Couleur de fond du logo',
  344. 'option_behavior_cancel_order' => 'Comportement lors de la suppression d\'une commande',
  345. 'tiller' => 'Tiller',
  346. 'tiller_provider_token' => 'Token provider',
  347. 'tiller_restaurant_token' => 'Token restaurant',
  348. 'status' => 'Statut',
  349. 'id_tax_rate_default' => 'Taxe',
  350. 'document_quotation_prefix' => 'Préfixe des devis',
  351. 'document_quotation_first_reference' => 'Première référence des devis',
  352. 'document_quotation_duration' => 'Durée du devis',
  353. 'document_invoice_prefix' => 'Préfixe des factures',
  354. 'document_invoice_first_reference' => 'Première référence des factures',
  355. 'document_delivery_note_prefix' => 'Préfixe des bons de livraison',
  356. 'document_delivery_note_first_reference' => 'Première référence des bons de livraison',
  357. 'document_infos_bottom' => 'Informations affichées en bas des documents',
  358. 'document_infos_quotation' => 'Informations affichées en bas des devis',
  359. 'document_infos_invoice' => 'Informations affichées en bas des factures',
  360. 'document_infos_delivery_note' => 'Informations affichées en bas des bons de livraison',
  361. 'address' => 'Adresse',
  362. 'document_display_orders_invoice' => 'Afficher le détail des commandes dans les factures',
  363. 'document_display_orders_delivery_note' => 'Afficher le détail des commandes dans les bons de livraison',
  364. 'document_display_prices_delivery_note' => 'Afficher le chiffrage dans les bons de livraison',
  365. 'behavior_home_point_sale_day_list' => 'Accueil : affichage des jours de distribution',
  366. 'behavior_order_select_distribution' => 'Sélection de la date de distribution',
  367. 'option_payment_info' => 'Informations liées au paiement',
  368. 'option_email_confirm' => 'Envoyer un email de confirmation au client',
  369. 'option_email_confirm_producer' => 'Envoyer un email de confirmation au producteur',
  370. 'option_dashboard_number_distributions' => 'Nombre de distributions affichées sur le tableau de board',
  371. 'option_dashboard_date_start' => 'Date de début',
  372. 'option_dashboard_date_end' => 'Date de fin',
  373. 'option_csv_export_all_products' => 'Exporter tous les produits dans le fichier récapitulatif (CSV)',
  374. 'option_csv_export_by_piece' => 'Exporter les produits par pièce dans le fichier récapitulatif (CSV)',
  375. 'option_order_reference_type' => 'Type de référence',
  376. 'option_export_display_product_reference' => 'Afficher la référence des produits au moment de l\'export',
  377. 'option_allow_order_guest' => 'Autoriser les visiteurs à passer commande (création de compte à la fin du tunnel)',
  378. 'option_order_entry_point' => 'Point d\'entrée par point de vente ou par date',
  379. 'option_delivery' => 'Proposer la livraison à domicile',
  380. 'option_display_export_grid' => 'Afficher l\'export grille dans les distributions',
  381. 'document_display_product_description' => 'Documents : afficher la description des produits',
  382. 'option_notify_producer_order_summary' => 'Recevoir les récapitulatifs de commande par email',
  383. 'option_billing_type' => 'Type de facturation',
  384. 'option_billing_frequency' => 'Fréquence de facturation',
  385. 'option_billing_reduction' => 'Réduction appliquée au moment de la facturation',
  386. 'option_tax_calculation_method' => 'Méthode de calcul de la TVA',
  387. 'option_export_evoliz' => 'Activer l\'export vers Evoliz',
  388. 'latest_version_opendistrib' => 'Dernière version d\'Opendistrib',
  389. 'option_csv_separator' => 'Séparateur de colonnes (CSV)',
  390. 'option_display_message_new_opendistrib_version' => 'Afficher les messages de mise à jour du logiciel Opendistrib',
  391. 'option_online_payment_minimum_amount' => 'Paiement en ligne : montant minimum',
  392. 'option_document_price_decimals' => 'Prix : nombre de décimales affichées',
  393. 'option_billing_reduction_percentage' => 'Réduction : pourcentage',
  394. 'option_billing_permanent_transfer' => 'Virement permanent',
  395. 'option_billing_permanent_transfer_amount' => 'Virement permanent : montant',
  396. ];
  397. }
  398. /*
  399. * Relations
  400. */
  401. public function getUserProducer()
  402. {
  403. return $this->hasMany(
  404. UserProducerModel::class,
  405. ['id_producer' => 'id']
  406. );
  407. }
  408. public function getUser()
  409. {
  410. return $this->hasMany(UserModel::className(), ['id_producer' => 'id']);
  411. }
  412. public function getContact()
  413. {
  414. return $this->hasMany(UserModel::className(), ['id_producer' => 'id'])
  415. ->where(['status' => User::STATUS_PRODUCER]);
  416. }
  417. public function getTaxRate()
  418. {
  419. return $this->hasOne(TaxRate::className(), ['id' => 'id_tax_rate_default']);
  420. }
  421. /**
  422. * Retourne les options de base nécessaires à la fonction de recherche.
  423. *
  424. * @return array
  425. */
  426. public static function defaultOptionsSearch()
  427. {
  428. return [
  429. 'with' => ['taxRate'],
  430. 'join_with' => [],
  431. 'orderby' => 'name ASC',
  432. 'attribute_id_producer' => 'id'
  433. ];
  434. }
  435. public function addUser($idUser, $idProducer)
  436. {
  437. $producerContainer = Yii::$app->logic->getProducerContainer();
  438. $producerContainer->getService()->addUser($idUser, $idProducer);
  439. }
  440. /**
  441. * Retourne le CA de l'établissement pour un mois donné.
  442. *
  443. * @param string $period
  444. * @param boolean $format
  445. * @return string
  446. */
  447. public function getTurnover($period = '', $format = false)
  448. {
  449. if (!$period) {
  450. $period = date('Y-m');
  451. }
  452. $connection = Yii::$app->getDb();
  453. $command = $connection->createCommand(
  454. '
  455. SELECT SUM(product_order.price * product_order.quantity) AS turnover
  456. FROM `order`, product_order, distribution, product
  457. WHERE `order`.id = product_order.id_order
  458. AND distribution.id_producer = :id_producer
  459. AND `order`.id_distribution = distribution.id
  460. AND product_order.id_product = product.id
  461. AND distribution.date > :date_begin
  462. AND distribution.date < :date_end',
  463. [
  464. ':date_begin' => date('Y-m-31', strtotime("-1 month", strtotime($period))),
  465. ':date_end' => date('Y-m-01', strtotime("+1 month", strtotime($period))),
  466. ':id_producer' => $this->id
  467. ]
  468. );
  469. $result = $command->queryOne();
  470. $turnover = $result['turnover'];
  471. if ($format) {
  472. return number_format($turnover, 2) . ' €';
  473. } else {
  474. return $turnover;
  475. }
  476. }
  477. public function getAmountToBeBilledByTurnover($turnover, $format = false)
  478. {
  479. $amountToBeBilled = 0;
  480. $producerPriceRangeArray = ProducerPriceRange::find()->all();
  481. foreach ($producerPriceRangeArray as $priceRange) {
  482. if ($turnover >= $priceRange->range_begin && $turnover < $priceRange->range_end) {
  483. $amountToBeBilled = $priceRange->price;
  484. }
  485. }
  486. if ($format) {
  487. return Price::format($amountToBeBilled, 0);
  488. } else {
  489. return $amountToBeBilled;
  490. }
  491. }
  492. public function getAmountToBeBilledByMonth($month, $format = false)
  493. {
  494. $turnover = $this->getTurnover($month);
  495. return $this->getAmountToBeBilledByTurnover($turnover, $format);
  496. }
  497. public function getSummaryAmountsToBeBilled($label, $numberOfMonths = 1)
  498. {
  499. $text = '';
  500. $numMonthCurrent = date('m');
  501. if ($numberOfMonths == 1
  502. || ($numberOfMonths == 3 && (in_array($numMonthCurrent, [1, 4, 7, 10])))
  503. || ($numberOfMonths == 6 && (in_array($numMonthCurrent, [1, 7])))) {
  504. for ($i = 1; $i <= $numberOfMonths; $i++) {
  505. $month = date('Y-m', strtotime('-' . $i . ' month'));
  506. $turnover = $this->getTurnover($month);
  507. if ($turnover) {
  508. $isBold = $this->isBillingTypeClassic() && !$this->option_billing_permanent_transfer;
  509. if ($isBold) $text .= '<strong>';
  510. $text .= $this->getAmountToBeBilledByTurnover($turnover, true);
  511. if ($isBold) $text .= '</strong>';
  512. $text .= ' / ' . Price::format($turnover, 0);
  513. $text .= '<br />';
  514. }
  515. }
  516. if (strlen($text)) {
  517. $text = $label . ' : <br />' . $text;
  518. }
  519. }
  520. return $text;
  521. }
  522. public function getAmountBilledLastMonth()
  523. {
  524. if ($this->isBillingTypeClassic()) {
  525. $month = date('Y-m', strtotime('-1 month'));
  526. return $this->getAmountToBeBilledByMonth($month);
  527. } elseif ($this->isBillingTypeFreePrice()) {
  528. return $this->free_price;
  529. }
  530. return 0;
  531. }
  532. /**
  533. * Retourne le montant à facturer pour une période donnée.
  534. *
  535. * @param string $periode
  536. * @param float $ca
  537. * @param boolean $format
  538. * @return string
  539. */
  540. public function getMAmountBilled($format = false)
  541. {
  542. if ($format) {
  543. return number_format($this->free_price, 2) . ' €';
  544. } else {
  545. return $this->free_price;
  546. }
  547. }
  548. /**
  549. * Retourne la facture d'une période donnée.
  550. *
  551. * @param string $periode
  552. * @return Facture
  553. */
  554. public function getInvoice($period = '')
  555. {
  556. if (!$period) {
  557. $period = date('Y-m', strtotime('-1 month'));
  558. }
  559. $invoice = Invoice::searchOne(
  560. ['id_producer' => $this->id, 'period' => ':period'],
  561. ['params' => [':period' => $period]]
  562. );
  563. return $invoice;
  564. }
  565. /**
  566. * Retourne la facture du mois dernier.
  567. *
  568. * @return Facture
  569. */
  570. public function getInvoiceLastMonth()
  571. {
  572. return $this->getInvoice(date('Y-m', strtotime('-1 month')));
  573. }
  574. /**
  575. * Retourne une configuration d'un établissement donné.
  576. *
  577. * @param string $config
  578. * @param integer $id_etablissement
  579. * @return mixed
  580. */
  581. public static function getConfig($config = '', $idProducer = 0)
  582. {
  583. if (strlen($config)) {
  584. if (!$idProducer) {
  585. $idProducer = GlobalParam::getCurrentProducerId();
  586. }
  587. $producer = self::findOne($idProducer);
  588. if ($producer) {
  589. return $producer->$config;
  590. }
  591. }
  592. return false;
  593. }
  594. /**
  595. * Retourne le montant de l'abonnement à prix libre définit par
  596. * le producteur.
  597. *
  598. * @param boolean $format
  599. * @return mixed
  600. */
  601. public function getFreePrice($format = true)
  602. {
  603. if (!is_null($this->free_price)) {
  604. if ($format) {
  605. return number_format($this->free_price, 2, ',', false) . ' €';
  606. } else {
  607. return $this->free_price;
  608. }
  609. }
  610. }
  611. public function getSpecificDelays()
  612. {
  613. $array = [];
  614. $daysArray = [
  615. 'monday',
  616. 'tuesday',
  617. 'wednesday',
  618. 'thursday',
  619. 'friday',
  620. 'saturday',
  621. 'sunday'
  622. ];
  623. foreach ($daysArray as $day) {
  624. $fieldDelay = 'order_delay_' . $day;
  625. $fieldDeadline = 'order_deadline_' . $day;
  626. $delay = $this->order_delay;
  627. $deadline = $this->order_deadline;
  628. if ($this->$fieldDelay) {
  629. $delay = $this->$fieldDelay;
  630. }
  631. if ($this->$fieldDeadline) {
  632. $deadline = $this->$fieldDeadline;
  633. }
  634. $array[$day] = [
  635. 'order_delay' => $delay,
  636. 'order_deadline' => $deadline,
  637. ];
  638. }
  639. return $array;
  640. }
  641. public function hasSpecificDelays()
  642. {
  643. $daysArray = [
  644. 'monday',
  645. 'tuesday',
  646. 'wednesday',
  647. 'thursday',
  648. 'friday',
  649. 'saturday',
  650. 'sunday'
  651. ];
  652. foreach ($daysArray as $day) {
  653. $fieldDelay = 'order_delay_' . $day;
  654. $fieldDeadline = 'order_deadline_' . $day;
  655. if ($this->$fieldDelay || $this->$fieldDeadline) {
  656. return true;
  657. }
  658. }
  659. return false;
  660. }
  661. /**
  662. * Retourne le chemin vers le fichier contenant la clé secrète d'API de Stripe
  663. *
  664. * @return string
  665. */
  666. public function getFilenamePrivateKeyApiStripe()
  667. {
  668. return '../../common/config/stripe/api-' . $this->id . '.key';
  669. }
  670. public function getFilenamePrivateKeyEndpointStripe()
  671. {
  672. return '../../common/config/stripe/endpoint-' . $this->id . '.key';
  673. }
  674. public function savePrivateKeyStripe($filename, $value)
  675. {
  676. if (strlen($value) > 0) {
  677. $handle = fopen($filename, "w");
  678. fwrite($handle, $value);
  679. fclose($handle);
  680. }
  681. }
  682. public function savePrivateKeyApiStripe()
  683. {
  684. $this->savePrivateKeyStripe(
  685. $this->getFilenamePrivateKeyApiStripe(),
  686. $this->option_stripe_private_key
  687. );
  688. }
  689. public function savePrivateKeyEndpointStripe()
  690. {
  691. $this->savePrivateKeyStripe(
  692. $this->getFilenamePrivateKeyEndpointStripe(),
  693. $this->option_stripe_endpoint_secret
  694. );
  695. }
  696. /**
  697. * Retourne la clé secrète d'API de Stripe.
  698. *
  699. * @return string
  700. */
  701. public function getPrivateKeyStripe($filename)
  702. {
  703. if (file_exists($filename)) {
  704. $handle = fopen($filename, "r");
  705. $filesize = filesize($filename);
  706. if ($handle && $filesize) {
  707. $secretKey = fread($handle, $filesize);
  708. fclose($handle);
  709. return $secretKey;
  710. }
  711. }
  712. return '';
  713. }
  714. public function getPrivateKeyApiStripe()
  715. {
  716. return $this->getPrivateKeyStripe($this->getFilenamePrivateKeyApiStripe());
  717. }
  718. public function getPrivateKeyEndpointStripe()
  719. {
  720. return $this->getPrivateKeyStripe($this->getFilenamePrivateKeyEndpointStripe());
  721. }
  722. /**
  723. * Retourne true si le compte est un compte de démo.
  724. *
  725. * @return boolean
  726. */
  727. public function isDemo()
  728. {
  729. if (strpos($this->name, 'Démo') !== false) {
  730. return true;
  731. }
  732. return false;
  733. }
  734. public function getFullAddress($nl2br = false)
  735. {
  736. $address = '';
  737. $address .= $this->name . "\n";
  738. if (strlen($this->address)) {
  739. $address .= $this->address . "\n";
  740. }
  741. if (strlen($this->postcode) || strlen($this->city)) {
  742. $address .= $this->postcode . ' ' . $this->city;
  743. }
  744. if ($nl2br) {
  745. $address = nl2br($address);
  746. }
  747. return $address;
  748. }
  749. public function getHtmlLogo()
  750. {
  751. $html = '';
  752. if (strlen($this->logo)) {
  753. $html = '<img src="' . $this->getUrlLogo() . '" class="producer-logo" />';
  754. }
  755. return $html;
  756. }
  757. public function getUrlLogo()
  758. {
  759. return Yii::$app->urlManagerProducer->getHostInfo() . '/' . Yii::$app->urlManagerProducer->baseUrl . '/uploads/' . $this->logo;
  760. }
  761. public function getEmailOpendistrib()
  762. {
  763. return $this->slug . '@opendistrib.net';
  764. }
  765. public function getMainContact()
  766. {
  767. if ($this->contact) {
  768. foreach ($this->contact as $contact) {
  769. if ($contact->is_main_contact) {
  770. return $contact;
  771. }
  772. }
  773. }
  774. return false;
  775. }
  776. public function isOnlinePaymentActive()
  777. {
  778. return $this->online_payment || ($this->option_stripe_mode_test && !Yii::$app->user->isGuest && Yii::$app->user->identity->status > 10);
  779. }
  780. public function isOnlinePaymentActiveAndTypeOrder()
  781. {
  782. return $this->isOnlinePaymentActive() && $this->option_online_payment_type == 'order';
  783. }
  784. public static function getBillingFrequencyPopulateDropdown()
  785. {
  786. return self::$billingFrequencyArray;
  787. }
  788. public function isBillingFrequencyMonthly()
  789. {
  790. return $this->option_billing_frequency == self::BILLING_FREQUENCY_MONTHLY;
  791. }
  792. public function isBillingFrequencyQuarterly()
  793. {
  794. return $this->option_billing_frequency == self::BILLING_FREQUENCY_QUARTERLY;
  795. }
  796. public function isBillingFrequencyBiannual()
  797. {
  798. return $this->option_billing_frequency == self::BILLING_FREQUENCY_BIANNUAL;
  799. }
  800. public static function getBillingTypePopulateDropdown()
  801. {
  802. return self::$billingTypeArray;
  803. }
  804. public function isBillingTypeClassic()
  805. {
  806. return $this->option_billing_type == self::BILLING_TYPE_CLASSIC;
  807. }
  808. public function isBillingTypeFreePrice()
  809. {
  810. return $this->option_billing_type == self::BILLING_TYPE_FREE_PRICE;
  811. }
  812. public function isUpToDateWithOpendistribVersion()
  813. {
  814. return $this->latest_version_opendistrib == GlobalParam::getOpendistribVersion();
  815. }
  816. public function updateOpendistribVersion()
  817. {
  818. $versionsArray = Opendistrib::getVersions();
  819. $this->latest_version_opendistrib = array_values($versionsArray)[0];
  820. $this->save();
  821. }
  822. public function getOnlinePaymentMinimumAmount()
  823. {
  824. $onlinePaymentMinimumAmount = self::getConfig('option_online_payment_minimum_amount');
  825. if (!$onlinePaymentMinimumAmount) {
  826. $onlinePaymentMinimumAmount = self::ONLINE_PAYMENT_MINIMUM_AMOUNT_DEFAULT;
  827. }
  828. return $onlinePaymentMinimumAmount;
  829. }
  830. }