Преглед на файлове

Merge branch 'feature/devis_bl_factures' into dev

dev
Guillaume Bourgeois преди 4 години
родител
ревизия
45f85547b7
променени са 100 файла, в които са добавени 11010 реда и са изтрити 6164 реда
  1. +9
    -2
      .gitignore
  2. +59
    -0
      backend/assets/VuejsAlertsAsset.php
  3. +2
    -1
      backend/assets/VuejsDistributionIndexAsset.php
  4. +64
    -0
      backend/assets/VuejsDocumentFormAsset.php
  5. +63
    -0
      backend/assets/VuejsUserFormAsset.php
  6. +2
    -1
      backend/controllers/AccessController.php
  7. +85
    -0
      backend/controllers/DeliveryNoteController.php
  8. +3
    -2
      backend/controllers/DevelopmentController.php
  9. +1048
    -907
      backend/controllers/DistributionController.php
  10. +554
    -0
      backend/controllers/DocumentController.php
  11. +62
    -0
      backend/controllers/InvoiceController.php
  12. +1003
    -1004
      backend/controllers/OrderController.php
  13. +1
    -1
      backend/controllers/PointSaleController.php
  14. +33
    -0
      backend/controllers/ProducerAdminController.php
  15. +4
    -3
      backend/controllers/ProducerController.php
  16. +5
    -2
      backend/controllers/ProductController.php
  17. +85
    -0
      backend/controllers/QuotationController.php
  18. +2
    -1
      backend/controllers/ReportController.php
  19. +4
    -3
      backend/controllers/SiteController.php
  20. +4
    -3
      backend/controllers/StatsController.php
  21. +13
    -9
      backend/controllers/SubscriptionController.php
  22. +171
    -0
      backend/controllers/TaxRateAdminController.php
  23. +13
    -11
      backend/controllers/UserController.php
  24. +2
    -1
      backend/models/AccessUserProducerForm.php
  25. +3
    -2
      backend/models/CreditForm.php
  26. +5
    -4
      backend/models/MailForm.php
  27. +145
    -0
      backend/views/delivery-note/index.php
  28. +164
    -157
      backend/views/development/index.php
  29. +136
    -77
      backend/views/distribution/index.php
  30. +1
    -1
      backend/views/distribution/report.php
  31. +313
    -0
      backend/views/document/_form.php
  32. +53
    -0
      backend/views/document/create.php
  33. +129
    -0
      backend/views/document/download.php
  34. +54
    -0
      backend/views/document/update.php
  35. +135
    -0
      backend/views/invoice/index.php
  36. +12
    -1
      backend/views/layouts/content.php
  37. +207
    -190
      backend/views/layouts/header.php
  38. +11
    -0
      backend/views/layouts/left.php
  39. +215
    -207
      backend/views/layouts/main-old.php
  40. +2
    -1
      backend/views/layouts/main.php
  41. +131
    -115
      backend/views/point-sale/_form.php
  42. +29
    -1
      backend/views/producer/update.php
  43. +125
    -81
      backend/views/product/_form.php
  44. +132
    -114
      backend/views/product/index.php
  45. +128
    -0
      backend/views/quotation/index.php
  46. +1
    -1
      backend/views/site/index.php
  47. +5
    -10
      backend/views/subscription/_form.php
  48. +6
    -21
      backend/views/subscription/index.php
  49. +58
    -0
      backend/views/tax-rate-admin/create.php
  50. +80
    -0
      backend/views/tax-rate-admin/index.php
  51. +58
    -0
      backend/views/tax-rate-admin/update.php
  52. +81
    -71
      backend/views/user/_form.php
  53. +2
    -1
      backend/views/user/credit.php
  54. +6
    -1
      backend/views/user/index.php
  55. +105
    -0
      backend/web/css/document/download.css
  56. +119
    -26
      backend/web/css/screen.css
  57. +37
    -5
      backend/web/js/backend.js
  58. +39
    -0
      backend/web/js/vuejs/alerts.js
  59. +75
    -3
      backend/web/js/vuejs/distribution-index.js
  60. +180
    -0
      backend/web/js/vuejs/document-form.js
  61. +4
    -0
      backend/web/js/vuejs/producer-update.js
  62. +1
    -16
      backend/web/js/vuejs/subscription-form.js
  63. +49
    -0
      backend/web/js/vuejs/user-form.js
  64. +20
    -0
      backend/web/sass/_alerts.scss
  65. +23
    -3
      backend/web/sass/distribution/_index.scss
  66. +43
    -0
      backend/web/sass/document/_form.scss
  67. +12
    -0
      backend/web/sass/document/_index.scss
  68. +110
    -0
      backend/web/sass/document/download.scss
  69. +4
    -1
      backend/web/sass/screen.scss
  70. +1
    -0
      common/assets/CommonAsset.php
  71. +194
    -198
      common/components/ActiveRecordCommon.php
  72. +112
    -109
      common/config/main.php
  73. +90
    -37
      common/config/params.php
  74. +50
    -0
      common/helpers/Debug.php
  75. +84
    -0
      common/helpers/GlobalParam.php
  76. +50
    -39
      common/helpers/Price.php
  77. +1
    -1
      common/helpers/Tiller.php
  78. +47
    -0
      common/mail/sendDocument-html.php
  79. +45
    -0
      common/mail/sendDocument-text.php
  80. +1
    -1
      common/models/CreditHistory.php
  81. +2
    -1
      common/models/CreditHistorySearch.php
  82. +93
    -0
      common/models/DeliveryNote.php
  83. +95
    -0
      common/models/DeliveryNoteSearch.php
  84. +2
    -1
      common/models/Development.php
  85. +332
    -333
      common/models/Distribution.php
  86. +357
    -0
      common/models/Document.php
  87. +44
    -87
      common/models/Invoice.php
  88. +85
    -0
      common/models/InvoiceSearch.php
  89. +823
    -695
      common/models/Order.php
  90. +81
    -0
      common/models/OrderStatusHistory.php
  91. +347
    -337
      common/models/PointSale.php
  92. +2
    -1
      common/models/PointSaleDistribution.php
  93. +2
    -1
      common/models/PointSaleSearch.php
  94. +487
    -459
      common/models/Producer.php
  95. +320
    -268
      common/models/Product.php
  96. +125
    -93
      common/models/ProductOrder.php
  97. +2
    -1
      common/models/ProductSearch.php
  98. +91
    -0
      common/models/Quotation.php
  99. +85
    -0
      common/models/QuotationSearch.php
  100. +421
    -441
      common/models/Subscription.php

+ 9
- 2
.gitignore Целия файл

@@ -26,5 +26,12 @@ phpunit.phar
# local phpunit config
/phpunit.xml

/vendor/*
*/.git
*/.git
vendor/*

common/config/bootstrap.php


backend/web/assets/*
producer/web/assets/*
frontend/web/assets/*

+ 59
- 0
backend/assets/VuejsAlertsAsset.php Целия файл

@@ -0,0 +1,59 @@
<?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 backend\assets;

use yii\web\AssetBundle;
use yii;


class VuejsAlertsAsset extends \common\components\MyAssetBundle
{
public $basePath = '@webroot';
public $baseUrl = '@web';
public $css = [];
public $js = [];
public $depends = [
'common\assets\CommonAsset'
];

public function __construct()
{
parent::__construct();
$this->addAsset('js', 'js/vuejs/alerts.js');
}
}

+ 2
- 1
backend/assets/VuejsDistributionIndexAsset.php Целия файл

@@ -51,7 +51,8 @@ class VuejsDistributionIndexAsset extends \common\components\MyAssetBundle
public $css = [];
public $js = [];
public $depends = [
'common\assets\CommonAsset'
'common\assets\CommonAsset',
'backend\assets\AppAsset',
];
public function __construct()

+ 64
- 0
backend/assets/VuejsDocumentFormAsset.php Целия файл

@@ -0,0 +1,64 @@
<?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 backend\assets;

use yii\web\AssetBundle;
use yii;

/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class VuejsDocumentFormAsset extends \common\components\MyAssetBundle
{
public $basePath = '@webroot';
public $baseUrl = '@web';
public $css = [];
public $js = [];
public $depends = [
'common\assets\CommonAsset',
'backend\assets\AppAsset',
'backend\assets\VuejsAlertsAsset',
];

public function __construct()
{
parent::__construct();
$this->addAsset('js', 'js/vuejs/document-form.js');
}
}

+ 63
- 0
backend/assets/VuejsUserFormAsset.php Целия файл

@@ -0,0 +1,63 @@
<?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 backend\assets;

use yii\web\AssetBundle;
use yii ;

/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class VuejsUserFormAsset extends \common\components\MyAssetBundle
{
public $basePath = '@webroot';
public $baseUrl = '@web';
public $css = [];
public $js = [];
public $depends = [
'common\assets\CommonAsset',
'backend\assets\AppAsset',
];
public function __construct()
{
parent::__construct() ;
$this->addAsset('js','js/vuejs/user-form.js') ;
}
}

+ 2
- 1
backend/controllers/AccessController.php Целия файл

@@ -38,6 +38,7 @@ termes.

namespace backend\controllers;

use common\helpers\GlobalParam;
use common\models\Producer ;
use common\models\User ;
use common\models\UserSearch ;
@@ -89,7 +90,7 @@ class AccessController extends BackendController
$usersAccessArray = User::find()
->where([
'id_producer' => Producer::getId(),
'id_producer' => GlobalParam::getCurrentProducerId(),
'status' => User::STATUS_PRODUCER
])
->all() ;

+ 85
- 0
backend/controllers/DeliveryNoteController.php Целия файл

@@ -0,0 +1,85 @@
<?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 backend\controllers;

use Yii;


class DeliveryNoteController extends DocumentController
{
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
],
],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['@'],
'matchCallback' => function ($rule, $action) {
return User::hasAccessBackend();
}
]
],
],
];
}

/**
* Liste les modèles Invoice.
*
* @return mixed
*/
public function actionIndex()
{
$searchModel = new DeliveryNoteSearch() ;
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}

}

+ 3
- 2
backend/controllers/DevelopmentController.php Целия файл

@@ -38,6 +38,7 @@ termes.

namespace backend\controllers;

use common\helpers\GlobalParam;
use Yii;
use common\models\User;
use common\models\Development;
@@ -172,12 +173,12 @@ class DevelopmentController extends Controller

if ($develpmentPriority) {
$develpmentPriority->priority = $priority;
$develpmentPriority->id_producer = Producer::getId();
$develpmentPriority->id_producer = GlobalParam::getCurrentProducerId();
} else {
$develpmentPriority = new DevelopmentPriority;
$develpmentPriority->id_development = $idDevelopment;
$develpmentPriority->priority = $priority;
$develpmentPriority->id_producer = Producer::getId();
$develpmentPriority->id_producer = GlobalParam::getCurrentProducerId();
}

$develpmentPriority->save();

+ 1048
- 907
backend/controllers/DistributionController.php
Файловите разлики са ограничени, защото са твърде много
Целия файл


+ 554
- 0
backend/controllers/DocumentController.php Целия файл

@@ -0,0 +1,554 @@
<?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 backend\controllers;

use common\models\DeliveryNote;
use common\models\Product;
use common\models\User;
use common\models\Document;
use common\helpers\GlobalParam;
use common\models\Order;
use yii\base\UserException;
use yii;

class DocumentController extends BackendController
{
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
],
],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['@'],
'matchCallback' => function ($rule, $action) {
return User::hasAccessBackend();
}
]
],
],
];
}

public function actionCreate()
{
$class = $this->getClass();
$model = new $class();

if ($model->load(Yii::$app->request->post())) {

$model->id_producer = GlobalParam::getCurrentProducerId();

if ($model->save()) {

$this->processInvoiceViaDeliveryNotes($model) ;

Yii::$app->getSession()->setFlash('success', $this->getFlashMessage('create', $model));
return $this->redirect(['/' . $this->getControllerUrl() . '/update', 'id' => $model->id]);
} else {
Yii::$app->getSession()->setFlash('error', 'Un problème est survenu lors de la création du document.');
}
}

return $this->render('/document/create', [
'title' => $this->getTitle('Ajouter'),
'typeDocument' => $this->getDocumentType(),
'model' => $model,
]);
}

public function processInvoiceViaDeliveryNotes($model)
{
if($model->getClass() == 'Invoice') {
if($model->deliveryNotes && is_array($model->deliveryNotes) && count($model->deliveryNotes)) {
foreach($model->deliveryNotes as $key => $idDeliveryNote) {
Order::updateAll([
'id_invoice' => $model->id
], [
'id_delivery_note' => $idDeliveryNote
]) ;
}
}
}
}

/**
* Modifie un modèle Produit existant.
* Si la modification réussit, le navigateur est redirigé vers la page 'index'.
*
* @param integer $id
* @return mixed
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);

if(!$model) {
throw new NotFoundHttpException('Le document n\'a pas été trouvé.');
}

if ($model->isStatusValid()) {
return $this->redirect(['download', 'id' => $id]) ;
}

if ($model && $model->load(Yii::$app->request->post()) && $model->save()) {
Yii::$app->getSession()->setFlash('success', $this->getFlashMessage('update', $model));
}

return $this->render('/document/update', [
'title' => $this->getTitle('Modifier'),
'typeDocument' => $this->getDocumentType(),
'model' => $model,
]);
}

public function actionDelete($id)
{
$model = $this->findModel($id);

if ($model->isStatusValid()) {
throw new UserException('Vous ne pouvez pas supprimer un document validé.');
}

$model->delete();

Order::updateAll([
'order.id_delivery_note' => null
], [
'order.id_delivery_note' => $id
]);

Yii::$app->getSession()->setFlash('success', $this->getFlashMessage('delete', $model));
$this->redirect([$this->getControllerUrl().'/index']);
}

public function actionDownload($id)
{
$document = $this->findModel($id);
return $document->generatePdf(Pdf::DEST_BROWSER) ;
}

public function actionSend($id)
{
$document = $this->findModel($id) ;
if($document->send()) {
Yii::$app->getSession()->setFlash('success', $this->getFlashMessage('send', $document));
}
else {
Yii::$app->getSession()->setFlash('danger', $this->getFlashMessage('send', $document));
}
$this->redirect([$this->getControllerUrl().'/index']);
}

public function actionAjaxUserInfos($typeAction, $idUser, $classDocument, $idDocument = false)
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

if ($idUser > 0) {
$user = User::searchOne([
'id' => $idUser
]);

if ($user) {

$document = null ;
if(Document::isValidClass($classDocument)) {
$document = $classDocument::searchOne([
'id' => $idDocument,
'id_user' => $idUser
]) ;
}

if($document && $document->id_user == $user->id) {
$address = $document->address ;
}
else {
$address = $user->getFullAddress() ;
}

$json = [
'return' => 'success',
'address' => $address
];

if($classDocument == 'Invoice') {
if($typeAction == 'create') {
$deliveryNotesArray = DeliveryNote::searchAll([
'id_user' => $user->id,
'status' => Document::STATUS_VALID
]) ;
}
elseif($typeAction == 'update' && $idDocument > 0) {
$deliveryNotesArray = DeliveryNote::searchAll([
'id_user' => $user->id,
'status' => Document::STATUS_VALID,
'order.id_invoice' => $idDocument
]) ;
}

if(isset($deliveryNotesArray)) {
$json['delivery_notes'] = [] ;

foreach($deliveryNotesArray as $deliveryNote) {
$json['delivery_notes'][] = array_merge(
$deliveryNote->getAttributes(),
[
'total' => $deliveryNote->getAmountWithTax()
]
) ;
}
}
}

return $json ;
}
}

return ['return' => 'error'];
}

public function actionValidate($id)
{
$classDocument = $this->getClass();

if ($id > 0 && Document::isValidClass($classDocument)) {
$document = $classDocument::searchOne([
'id' => $id
]);

if ($document) {
$document->changeStatus(Document::STATUS_VALID);
$document->save();
Yii::$app->getSession()->setFlash('success', $this->getFlashMessage('validate', $document));
return $this->redirect([$this->getControllerUrl().'/index']);
}
}

Yii::$app->getSession()->setFlash('danger', 'Une erreur est survenue lors de la validation du document.');
return $this->redirect([$this->getControllerUrl().'/index']);
}

public function actionAjaxValidateDocument($idDocument, $classDocument)
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

if ($idDocument > 0 && Document::isValidClass($classDocument)) {
$document = $classDocument::searchOne([
'id' => $idDocument
]);

if ($document) {
$document->changeStatus(Document::STATUS_VALID);
$document->save();
return [
'return' => 'success',
'alert' => [
'type' => 'success',
'message' => 'Document validé'
]
];
}
}

return [
'return' => 'error',
'alert' => [
'type' => 'danger',
'message' => 'Une erreur est survenue lors de la validation du document.'
]
];
}

public function actionAjaxInit($idDocument, $classDocument)
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

if ($idDocument > 0 && Document::isValidClass($classDocument)) {

$document = $classDocument::searchOne([
'id' => $idDocument
]);

if ($document) {

$productsArray = Product::searchAll();

$ordersArray = [];
foreach ($document->orders as $order) {
$order->init();
$productsOrderArray = [];
foreach ($order->productOrder as $productOrder) {
$productsOrderArray[$productOrder->id] = $productOrder->getAttributes();
}
$ordersArray[$order->id] = array_merge(
$order->getAttributes(),
[
'username' => $order->getUsername(),
'distribution_date' => isset($order->distribution) ? date('d/m/Y', strtotime($order->distribution->date)) : null,
'point_sale_name' => isset($order->pointSale) ? $order->pointSale->name : null,
'productOrder' => $productsOrderArray,
]
);
}

return [
'return' => 'success',
'tax_rate_producer' => GlobalParam::getCurrentProducer()->taxRate->value,
'document' => array_merge($document->getAttributes(), [
'html_label' => $document->getHtmlLabel(),
'class' => $document->getClass()
]),
'id_user' => $document->user->id,
'products' => ArrayHelper::map($productsArray, 'id', function ($product) {
return array_merge($product->getAttributes(), [
'price_with_tax' => $product->price_with_tax,
'wording_unit' => $product->wording_unit,
'tax_rate' => $product->taxRate->value
]);
}),
'orders' => $ordersArray,
'total' => $document->getAmount(Order::AMOUNT_TOTAL),
'total_with_tax' => $document->getAmountWithTax(Order::AMOUNT_TOTAL),
];
}
}

return ['return' => 'error'];
}

public function actionAjaxAddProduct($idDocument, $classDocument, $idProduct, $quantity, $price)
{

\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

if (Document::isValidClass($classDocument)) {
$document = $classDocument::searchOne([
'id' => $idDocument
]);
$product = Product::searchOne([
'id' => $idProduct
]);

if ($document && $product) {
if (count($document->orders) == 0) {
$order = new Order;
$order->id_user = $document->id_user;
$order->id_point_sale = null;
$order->id_distribution = null;
$order->status = 'tmp-order' ;
$order->origin = Order::ORIGIN_ADMIN;
$order->date = date('Y-m-d H:i:s');
$fieldIdDocument = 'id_' . $classDocument::tableName();
$order->$fieldIdDocument = $document->id;
$order->save();
} else {
$order = $document->orders[0];
}

if ($order) {

$productOrder = new ProductOrder;
$productOrder->id_order = $order->id;
$productOrder->id_product = $idProduct;
$quantity = $quantity / Product::$unitsArray[$product->unit]['coefficient'];
$productOrder->quantity = $quantity;
$productOrder->price = (float)$price;
$productOrder->unit = $product->unit;
$productOrder->step = $product->step;
$productOrder->id_tax_rate = $product->taxRate->id ;
$productOrder->save();

return [
'return' => 'success',
'alert' => [
'type' => 'success',
'message' => 'Produit ajouté'
]
];
}
}

}

return [
'return' => 'error',
'alert' => [
'type' => 'danger',
'message' => 'Une erreur est survenue lors de la suppression du produit.'
]
];
}

public function actionAjaxDeleteProductOrder($idProductOrder)
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

$productOrder = ProductOrder::searchOne([
'id' => $idProductOrder
]);

if ($productOrder) {
$productOrder->delete();

return [
'return' => 'success',
'alert' => [
'type' => 'danger',
'message' => 'Produit supprimé'
]
];
}

return [
'return' => 'error',
'alert' => [
'type' => 'danger',
'message' => 'Une erreur est survenue lors de la suppression du produit.'
]
];
}

public function getClass()
{
$class = get_class($this);
$class = str_replace('Controller', '', $class);
$class = str_replace('backend\controllers\\', '', $class);
return $class;
}

public function getDocumentType()
{
$class = $this->getClass();

if ($class == 'Invoice') {
$documentType = 'Facture';
} elseif ($class == 'DeliveryNote') {
$documentType = 'Bon de livraison';
} elseif ($class == 'Quotation') {
$documentType = 'Devis';
}

if (isset($documentType)) {
return $documentType;
}

return '';
}

public function getFlashMessage($type = 'create', $model)
{
$class = $this->getClass();

$message = $this->getDocumentType();
$message .= ' <strong>' . Html::encode($model->name) . '</strong> ';

if ($type == 'create') {
$message .= 'ajouté';
} elseif ($type == 'update') {
$message .= 'modifié';
} elseif ($type == 'delete') {
$message .= 'supprimé';
} elseif ($type == 'validate') {
$message .= 'validé';
} elseif ($type == 'send') {
$message .= 'envoyé';
}

if ($class == 'Invoice') {
$message .= 'e';
}

return $message;
}

protected function getTitle($prepend)
{
$class = $this->getClass();

switch ($class) {
case 'Invoice' :
$title = $prepend . ' une facture';
break;
case 'DeliveryNote' :
$title = $prepend . ' un bon de livraison';
break;
case 'Quotation' :
$title = $prepend . ' un devis';
break;
}

return $title;
}

public function getControllerUrl()
{
$path = strtolower($this->getClass());
$path = str_replace('deliverynote', 'delivery-note', $path);
return $path;
}

/**
* Recherche un Document en fonction de son ID.
*
* @param integer $id
* @return Document
* @throws NotFoundHttpException si le modèle n'est pas trouvé
*/
protected function findModel($id)
{
$class = $this->getClass();

$model = $class::searchOne([
'id' => $id
]);

if ($model) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}

}

+ 62
- 0
backend/controllers/InvoiceController.php Целия файл

@@ -0,0 +1,62 @@
<?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 backend\controllers;

use Yii;


class InvoiceController extends DocumentController
{
/**
* Liste les modèles Invoice.
*
* @return mixed
*/
public function actionIndex()
{
$searchModel = new InvoiceSearch() ;
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}

}

+ 1003
- 1004
backend/controllers/OrderController.php
Файловите разлики са ограничени, защото са твърде много
Целия файл


+ 1
- 1
backend/controllers/PointSaleController.php Целия файл

@@ -201,7 +201,7 @@ class PointSaleController extends BackendController
{
$pointSale = $this->findModel($id) ;
if($pointSale) {
PointSale::updateAll(['default' => 0], 'id_producer = :id_producer', [':id_producer' => Producer::getId()]) ;
PointSale::updateAll(['default' => 0], 'id_producer = :id_producer', [':id_producer' => GlobalParam::getCurrentProducerId()]) ;
if(!$pointSale->default) {
$pointSale->default = 1 ;
$pointSale->save() ;

+ 33
- 0
backend/controllers/ProducerAdminController.php Целия файл

@@ -47,6 +47,9 @@ use common\helpers\Upload;
use common\models\Producer;
use yii\data\ActiveDataProvider;
use common\models\Invoice;
use common\models\Product;
use common\models\Order;
use common\models\Subscription;

/**
* UserController implements the CRUD actions for User model.
@@ -176,6 +179,36 @@ class ProducerAdminController extends BackendController
'dataProviderInvoice' => $dataProviderInvoice,
]);
}
public function actionProducerInstallTaxUpdatePrices($idProducer)
{
// product
$productsArray = Product::searchAll([
'id_producer' => $idProducer
]) ;

$connection = Yii::$app->getDb();
foreach($productsArray as $product) {
$product->price = round($product->price / (1 + $product->taxRate->value), 2) ;
$product->save() ;

$command = $connection->createCommand("
UPDATE `product_order`
SET price = ROUND(price / (1 + :tax_value), 2),
id_tax_rate = :id_tax_rate
WHERE id_product = :id_product",
[
':id_product' => $product->id,
':tax_value' => $product->taxRate->value,
':id_tax_rate' => $product->taxRate->id,
]);

$result = $command->query();
}

echo 'ok' ;
}

/**
* Recherche un établissement.

+ 4
- 3
backend/controllers/ProducerController.php Целия файл

@@ -38,6 +38,7 @@ termes.

namespace backend\controllers;

use common\helpers\GlobalParam;
use Yii;
use common\models\User;
use backend\models\MailForm;
@@ -90,7 +91,7 @@ class ProducerController extends BackendController
public function actionUpdate()
{
$request = Yii::$app->request;
$model = $this->findModel(Producer::getId());
$model = $this->findModel(GlobalParam::getCurrentProducerId());
$model->secret_key_payplug = $model->getSecretKeyPayplug() ;
$logoFilenameOld = $model->logo;
@@ -136,14 +137,14 @@ class ProducerController extends BackendController
{
$datasInvoices = new ActiveDataProvider([
'query' => Invoice::find()
->where(['id_producer' => Producer::getId()])
->where(['id_producer' => GlobalParam::getCurrentProducerId()])
->orderBy('reference DESC'),
'pagination' => [
'pageSize' => 1000,
],
]);

$producer = Producer::findOne(Producer::getId());
$producer = Producer::findOne(GlobalParam::getCurrentProducerId());

if ($producer->load(Yii::$app->request->post())) {
$producer->save();

+ 5
- 2
backend/controllers/ProductController.php Целия файл

@@ -38,6 +38,7 @@ termes.

namespace backend\controllers;

use common\helpers\GlobalParam;
use common\models\ProductDistribution;
use Yii;
use yii\filters\AccessControl;
@@ -108,11 +109,13 @@ class ProductController extends BackendController
{
$model = new Product();
$model->active = 1;
$model->id_producer = Producer::getId();
$model->id_producer = GlobalParam::getCurrentProducerId();



if ($model->load(Yii::$app->request->post()) && $model->save()) {
$lastProductOrder = Product::find()->where('id_producer = :id_producer')->params([':id_producer' => Producer::getId()])->orderBy('order DESC')->one() ;
$lastProductOrder = Product::find()->where('id_producer = :id_producer')->params([':id_producer' => GlobalParam::getCurrentProducerId()])->orderBy('order DESC')->one() ;
if($lastProductOrder) {
$model->order = ++ $lastProductOrder->order ;
}

+ 85
- 0
backend/controllers/QuotationController.php Целия файл

@@ -0,0 +1,85 @@
<?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 backend\controllers;

use Yii;


class QuotationController extends DocumentController
{
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
],
],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['@'],
'matchCallback' => function ($rule, $action) {
return User::hasAccessBackend();
}
]
],
],
];
}

/**
* Liste les modèles Invoice.
*
* @return mixed
*/
public function actionIndex()
{
$searchModel = new QuotationSearch() ;
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}

}

+ 2
- 1
backend/controllers/ReportController.php Целия файл

@@ -38,6 +38,7 @@ termes.

namespace backend\controllers;

use common\helpers\GlobalParam;
use Yii;
use yii\filters\AccessControl;
use common\models\User;
@@ -135,7 +136,7 @@ class ReportController extends BackendController
$res = Yii::$app->db->createCommand("SELECT product.name, SUM(product_order.quantity) AS quantity, SUM(product_order.price * product_order.quantity) AS total
FROM `order`, product_order, product
WHERE `order`.id = product_order.id_order
AND product.id_producer = ".((int) Producer::getId())."
AND product.id_producer = ".((int) GlobalParam::getCurrentProducerId()) ."
AND product_order.id_product = product.id
AND `order`.date_delete IS NULL
".$conditionUsers."

+ 4
- 3
backend/controllers/SiteController.php Целия файл

@@ -38,6 +38,7 @@ termes.

namespace backend\controllers;

use common\helpers\GlobalParam;
use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
@@ -121,7 +122,7 @@ class SiteController extends BackendController
->with('order')
->where(['>=', 'distribution.date', date('Y-m-d')])
->andWhere([
'distribution.id_producer' => Producer::getId(),
'distribution.id_producer' => GlobalParam::getCurrentProducerId(),
'distribution.active' => 1
])
->orderBy('date ASC')
@@ -143,12 +144,12 @@ class SiteController extends BackendController
->limit(5)
->all();

$usersNegativeCredit = User::findBy(['id_producer' => Producer::getId()])
$usersNegativeCredit = User::findBy(['id_producer' => GlobalParam::getCurrentProducerId()])
->andWhere('user_producer.credit < 0')
->all();

// paramètres
$producer = Producer::getCurrent();
$producer = GlobalParam::getCurrentProducer();

$productsCount = Product::searchCount() ;
$pointsSaleCount = PointSale::searchCount() ;

+ 4
- 3
backend/controllers/StatsController.php Целия файл

@@ -38,6 +38,7 @@ termes.

namespace backend\controllers;

use common\helpers\GlobalParam;
use yii\web\Controller;
use yii\filters\AccessControl;
use Yii;
@@ -105,7 +106,7 @@ class StatsController extends BackendController
AND distribution.date >= :date_start
AND distribution.date <= :date_end
")
->bindValue(':id_producer', Producer::getId())
->bindValue(':id_producer',GlobalParam::getCurrentProducerId())
->bindValue(':date_start', date('Y-m-', $date->getTimestamp()).'01')
->bindValue(':date_end', date('Y-m-', $date->getTimestamp()).'31' )
->queryOne();
@@ -165,7 +166,7 @@ class StatsController extends BackendController
// Maximums
$resMaximums = Yii::$app->db->createCommand("SELECT product.name, SUM(IF(product_distribution.active, product_distribution.quantity_max,0)) AS total
FROM distribution, product_distribution, product
WHERE distribution.id_producer = ".Producer::getId()."
WHERE distribution.id_producer = ".GlobalParam::getCurrentProducerId()."
AND distribution.date >= :date_begin
AND distribution.date <= :date_end
AND distribution.id = product_distribution.id_distribution
@@ -190,7 +191,7 @@ class StatsController extends BackendController
$resOrders = Yii::$app->db->createCommand('
SELECT product.name, SUM(product_order.quantity) AS total
FROM `distribution`, `order`, `product_order`, `product`
WHERE distribution.id_producer = '.Producer::getId().'
WHERE distribution.id_producer = '.GlobalParam::getCurrentProducerId().'
AND distribution.date >= :date_begin
AND distribution.date <= :date_end
AND distribution.id = `order`.id_distribution

+ 13
- 9
backend/controllers/SubscriptionController.php Целия файл

@@ -37,6 +37,8 @@ termes.

namespace backend\controllers;

use common\helpers\Debug;
use common\helpers\GlobalParam;
use common\models\Order ;
use common\models\Product ;
use common\models\SubscriptionSearch ;
@@ -91,7 +93,7 @@ class SubscriptionController extends BackendController
// form
$model = new SubscriptionForm;
$model->isAdmin = true ;
$model->id_producer = Producer::getId();
$model->id_producer = GlobalParam::getCurrentProducerId();

if($idOrder) {
$order = Order::searchOne(['id' => $idOrder]);
@@ -266,7 +268,7 @@ class SubscriptionController extends BackendController
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$productsQuery = Product::find()
->where(['id_producer' => Producer::getId(),]) ;
->where(['id_producer' => GlobalParam::getCurrentProducerId(),]) ;
if($idSubscription) {
$productsQuery->joinWith(['productSubscription' => function($query) use($idSubscription) {
@@ -275,19 +277,21 @@ class SubscriptionController extends BackendController
}
$productsArray = $productsQuery->asArray()->orderBy('order ASC')->all() ;
/*Debug::dump($productsArray);*/
foreach($productsArray as &$theProduct) {
$theProduct['unit_save'] = $theProduct['unit'] ;
/*$theProduct['unit_save'] = $theProduct['unit'] ;
$theProduct['units'] = [] ;
$theProduct['units'][] = [
'unit' => $theProduct['unit'],
'wording_unit' => Product::strUnit($theProduct['unit'], 'wording_short'),
'step' => $theProduct['step'],
'price' => $theProduct['price']
] ;
] ;*/

$theProduct['wording_unit'] = Product::strUnit($theProduct['unit'], 'wording_short');

if(isset($theProduct['productSubscription'][0])) {
if($theProduct['productSubscription'][0]['unit'] != $theProduct['unit']) {
/*if($theProduct['productSubscription'][0]['unit'] != $theProduct['unit']) {
$theProduct['units'][] = [
'unit' => $theProduct['productSubscription'][0]['unit'],
'wording_unit' => Product::strUnit($theProduct['productSubscription'][0]['unit'], 'wording_short'),
@@ -297,7 +301,7 @@ class SubscriptionController extends BackendController
$theProduct['unit'] = $theProduct['productSubscription'][0]['unit'] ;
$theProduct['step'] = $theProduct['productSubscription'][0]['step'] ;
$theProduct['price'] = $theProduct['productSubscription'][0]['price'] ;
}
}*/
$theProduct['quantity'] = $theProduct['productSubscription'][0]['quantity'] * Product::$unitsArray[$theProduct['unit']]['coefficient'] ;
}
else {

+ 171
- 0
backend/controllers/TaxRateAdminController.php Целия файл

@@ -0,0 +1,171 @@
<?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 backend\controllers;

use common\models\TaxRate;
use Yii;
use common\models\User;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use common\helpers\Upload;
use common\models\Producer;
use yii\data\ActiveDataProvider;
use common\models\Invoice;

/**
* TaxRateAdminController implements the CRUD actions for TaxRate model.
*/
class TaxRateAdminController extends BackendController
{

public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'],
],
],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['@'],
'matchCallback' => function ($rule, $action) {
return User::getCurrentStatus() == USER::STATUS_ADMIN;
}
]
],
],
];
}

/**
* Liste les taxes.
*
* @return mixed
*/
public function actionIndex()
{
$dataProviderTaxRate = new ActiveDataProvider([
'query' => TaxRate::find()
]);

return $this->render('index', [
'dataProviderTaxRate' => $dataProviderTaxRate,
]);
}

/**
* Crée une taxe.
*
* @return mixed
*/
public function actionCreate()
{
$model = new TaxRate();

if ($model->load(Yii::$app->request->post()) && $model->save()) {
Yii::$app->getSession()->setFlash('success', 'Taxe créé.');
return $this->redirect(['index']);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}

/**
* Édition d'une taxe.
*
* @return mixed
*/
public function actionUpdate($id)
{


$model = $this->findModel($id);

if ($model->load(Yii::$app->request->post()) && $model->save()) {
Yii::$app->getSession()->setFlash('success', 'Taxe édité.');
return $this->redirect(['index']);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}

/**
* Supprime une commande récurrente.
*
* @param integer $id
*/
public function actionDelete($id)
{
$taxeRate = TaxRate::searchOne([
'id' => $id
]) ;
$taxeRate->delete();

Yii::$app->getSession()->setFlash('success', 'Taxe supprimé');
return $this->redirect(['tax-rate-admin/index']);
}


/**
* Finds the Developpement model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* @param integer $id
* @return Developpement the loaded model
* @throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = TaxRate::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}

}

+ 13
- 11
backend/controllers/UserController.php Целия файл

@@ -38,6 +38,7 @@ termes.

namespace backend\controllers;

use common\helpers\GlobalParam;
use common\models\User ;
use common\models\Producer ;
use common\models\Distribution ;
@@ -98,7 +99,7 @@ class UserController extends BackendController
]) ;
$producer = Producer::searchOne([
'id' => Producer::getId()
'id' => GlobalParam::getCurrentProducerId()
]) ;
$pointsSaleArray = PointSale::searchAll() ;
@@ -131,7 +132,7 @@ class UserController extends BackendController
// points de vente
$pointsSaleArray = PointSale::find()
->where([
'id_producer' => Producer::getId(),
'id_producer' => GlobalParam::getCurrentProducerId(),
])
->joinWith(['userPointSale' => function($query) use($model) {
if($model->id) {
@@ -156,8 +157,9 @@ class UserController extends BackendController

if ($model->load(Yii::$app->request->post()) && $model->validate() && YII_ENV != 'demo') {

// save use
// save user
$password = Password::generate();
$model->id_producer = 0 ;
$model->setPassword($password);
$model->generateAuthKey();
$model->username = $model->email;
@@ -170,7 +172,7 @@ class UserController extends BackendController
// liaison etablissement / user
$useProducer = new UserProducer();
$useProducer->id_user = $model->id;
$useProducer->id_producer = Producer::getId();
$useProducer->id_producer = GlobalParam::getCurrentProducerId();
$useProducer->credit = 0;
$useProducer->active = 1;
$useProducer->save();
@@ -202,7 +204,7 @@ class UserController extends BackendController
// Moodification du profil
$previousMail = $model->email ;
$user = User::find()->with('userProducer')->where(['id' => $model['id']])->one();
$userBelongToProducer = UserProducer::findOne(['id_user' => $id, 'id_producer' => Producer::getId()]);
$userBelongToProducer = UserProducer::findOne(['id_user' => $id, 'id_producer' => GlobalParam::getCurrentProducerId()]);
if (($userBelongToProducer && count($user->userProducer) == 1) || User::getCurrentStatus() == USER::STATUS_ADMIN) {
if ($model->load(Yii::$app->request->post()) && $model->save()) {
@@ -228,7 +230,7 @@ class UserController extends BackendController
$model->setPassword($password);
$model->save() ;
$producer = Producer::getCurrent();
$producer = GlobalParam::getCurrentProducer() ;
Yii::$app->mailer->compose();
$mail = Yii::$app->mailer->compose(
['html' => 'newPasswordUserAdmin-html', 'text' => 'newPasswordUserAdmin-text'], ['user' => $model, 'producer' => $producer, 'password' => $password]
@@ -282,7 +284,7 @@ class UserController extends BackendController
{
$userProducer = UserProducer::findOne([
'id_user' => $id,
'id_producer' => Producer::getId()
'id_producer' => GlobalParam::getCurrentProducerId()
]) ;
if($userProducer) {
$userProducer->active = 0 ;
@@ -319,7 +321,7 @@ class UserController extends BackendController
}
$users = User::findBy([
'id_producer' => Producer::getId(),
'id_producer' => GlobalParam::getCurrentProducerId(),
'id_point_sale' => $idPointSale,
'users_point_sale_link' => $usersPointSaleLink,
'users_point_sale_has_order' => $usersPointSaleHasOrder,
@@ -333,7 +335,7 @@ class UserController extends BackendController
$usersArray[] = $user['email'];
}
$pointsSaleArray = PointSale::find()->where(['id_producer' => Producer::getId()])->all() ;
$pointsSaleArray = PointSale::find()->where(['id_producer' => GlobalParam::getCurrentProducerId()])->all() ;
$pointSale = null ;
if($idPointSale) {
@@ -395,7 +397,7 @@ class UserController extends BackendController
public function actionCredit($id)
{
$user = User::find()->with('userProducer')->where(['id' => $id])->one();
$userProducer = UserProducer::findOne(['id_user' => $id, 'id_producer' => Producer::getId()]);
$userProducer = UserProducer::findOne(['id_user' => $id, 'id_producer' => GlobalParam::getCurrentProducerId()]);
if (($userProducer) || User::getCurrentStatus() == User::STATUS_ADMIN) {
@@ -410,7 +412,7 @@ class UserController extends BackendController
->with(['order', 'userAction'])
->where([
'id_user' => $user->id,
'id_producer' => Producer::getId(),
'id_producer' => GlobalParam::getCurrentProducerId(),
])
->orderBy('date DESC')
->all();

+ 2
- 1
backend/models/AccessUserProducerForm.php Целия файл

@@ -38,6 +38,7 @@ termes.

namespace backend\models;

use common\helpers\GlobalParam;
use Yii;
use yii\base\Model;
use common\models\User ;
@@ -80,7 +81,7 @@ class AccessUserProducerForm extends Model
]) ;
if($user) {
$user->id_producer = Producer::getId() ;
$user->id_producer = GlobalParam::getCurrentProducerId() ;
if($user->status != User::STATUS_PRODUCER && $user->status != User::STATUS_ADMIN) {
$user->status = User::STATUS_PRODUCER ;
}

+ 3
- 2
backend/models/CreditForm.php Целия файл

@@ -38,6 +38,7 @@ termes.

namespace backend\models;

use common\helpers\GlobalParam;
use Yii;
use yii\base\Model;
use common\models\CreditHistory ;
@@ -102,7 +103,7 @@ class CreditForm extends Model
$creditHistory = new CreditHistory;
$creditHistory->id_user = $this->id_user;
$creditHistory->id_user_action = Yii::$app->user->identity->id;
$creditHistory->id_producer = Producer::getId() ;
$creditHistory->id_producer = GlobalParam::getCurrentProducerId() ;
$creditHistory->type = $this->type ;
$creditHistory->comment = $this->comment ;
$creditHistory->amount = $this->amount ;
@@ -112,7 +113,7 @@ class CreditForm extends Model
// on prévient l'utilisateur que son compte vient d'être crédité
if($this->send_mail) {
$user = User::findOne($this->id_user) ;
$producer = Producer::getCurrent() ;
$producer = GlobalParam::getCurrentProducer() ;
$userProducer = UserProducer::searchOne([
'id_user' => $this->id_user
]);

+ 5
- 4
backend/models/MailForm.php Целия файл

@@ -38,6 +38,7 @@ termes.

namespace backend\models;

use common\helpers\GlobalParam;
use Yii;
use yii\base\Model;
use common\helpers\Price ;
@@ -105,7 +106,7 @@ class MailForm extends Model
if($distribution) {
$linkOrder = Yii::$app->urlManagerProducer->createAbsoluteUrl(['order/order','slug_producer' => Producer::getCurrent()->slug, 'date' => $distribution->date]) ;
$linkOrder = Yii::$app->urlManagerProducer->createAbsoluteUrl(['order/order','slug_producer' => GlobalParam::getCurrentProducer()->slug, 'date' => $distribution->date]) ;
$dateOrder = strftime('%A %d %B %Y', strtotime($distribution->date)) ;
$messageAutoHtml .= '<a href="'.$linkOrder.'">Passer ma commande du '.$dateOrder.'</a>' ;
$messageAutoText .= 'Suivez ce lien pour passer votre commande du '.$dateOrder.' :
@@ -113,7 +114,7 @@ class MailForm extends Model
$productsArray = Product::find()
->where([
'id_producer' => Producer::getId(),
'id_producer' => GlobalParam::getCurrentProducerId(),
])
->innerJoinWith(['productDistribution' => function($query) use($distribution) {
$query->andOnCondition([
@@ -150,8 +151,8 @@ Produits disponibles :
}
if($fromProducer) {
$producer = Producer::getCurrent() ;
$fromEmail = $producer->slug.'@opendistrib.net' ;
$producer = GlobalParam::getCurrentProducer() ;
$fromEmail = $producer->getEmailOpendistrib() ;
$fromName = $producer->name ;
}
else {

+ 145
- 0
backend/views/delivery-note/index.php Целия файл

@@ -0,0 +1,145 @@
<?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.
*/

$this->setTitle('Bons de livraison');
$this->addBreadcrumb($this->getTitle());
$this->addButton(['label' => 'Nouveau bon de livraison <span class="glyphicon glyphicon-plus"></span>', 'url' => ['distribution/index', 'message_generate_bl' => 1], 'class' => 'btn btn-primary']);

?>

<div class="delivery-note-index">
<?= GridView::widget([
'filterModel' => $searchModel,
'dataProvider' => $dataProvider,
'columns' => [
[
'attribute' => 'status',
'label' => 'Statut',
'filter' => [
'draft' => 'Brouillon',
'valid' => 'Valide',
],
'format' => 'raw',
'value' => function($model) {
return $model->getHtmlLabel() ;
}
],
[
'attribute' => 'reference',
'value' => function($model) {
if(strlen($model->reference) > 0) {
return $model->reference ;
}
return '' ;
}
],
'name',
[
'attribute' => 'date_distribution',
'header' => 'Jour de distribution',
'filter' => \yii\jui\DatePicker::widget([
'language' => 'fr',
'dateFormat' => 'dd/MM/yyyy',
'model' => $searchModel,
'attribute' => 'date_distribution',
'options' => ['class' => 'form-control']
]),
'value' => function($model) {
$distribution = $model->getDistribution() ;
if($distribution) {
return date('d/m/Y',strtotime($distribution->date)) ;
}
return '' ;
}
],
[
'attribute' => 'id_point_sale',
'header' => 'Point de vente',
'filter' => ArrayHelper::map(PointSale::searchAll([], ['as_array'=>true]), 'id', 'name'),
'format' => 'html',
'value' => function($model) {
$pointSale = $model->getPointSale() ;
if($pointSale) {
return Html::encode($pointSale->name);
}
return '' ;
}
],
[
'attribute' => 'amount',
'header' => 'Montant',
'value' => function($invoice) {
return $invoice->getAmountWithTax(Order::AMOUNT_TOTAL, true) ;
}
],
[
'class' => 'yii\grid\ActionColumn',
'template' => '{validate} {update} {delete} {send} {download}',
'headerOptions' => ['class' => 'column-actions'],
'contentOptions' => ['class' => 'column-actions'],
'buttons' => [
'send' => function($url, $model) {
return (!$model->isStatusDraft() ? Html::a('<span class="glyphicon glyphicon-send"></span>', $url, [
'title' => Yii::t('app', 'Envoyer'), 'class' => 'btn btn-default'
]) : '');
},
'download' => function($url, $model) {
return Html::a('<span class="glyphicon glyphicon-download-alt"></span>', $url, [
'title' => Yii::t('app', 'Télécharger'), 'class' => 'btn btn-default'
]);
},
'validate' => function ($url, $model) {
return ($model->isStatusDraft() ? Html::a('<span class="glyphicon glyphicon-ok"></span>', $url, [
'title' => Yii::t('app', 'Valider'), 'class' => 'btn btn-default'
]) : '');
},
'update' => function ($url, $model) {
return ($model->isStatusDraft() ? Html::a('<span class="glyphicon glyphicon-pencil"></span>', $url, [
'title' => Yii::t('app', 'Modifier'), 'class' => 'btn btn-default'
]) : '');
},
'delete' => function ($url, $model) {
return ($model->isStatusDraft() ? Html::a('<span class="glyphicon glyphicon-trash"></span>', $url, [
'title' => Yii::t('app', 'Supprimer'), 'class' => 'btn btn-default'
]) : '');
}
],
],
],
]); ?>
</div>

+ 164
- 157
backend/views/development/index.php Целия файл

@@ -1,40 +1,40 @@
<?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.
*/
/**
* 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.
*/

use yii\helpers\Html;
use yii\grid\GridView;
@@ -42,146 +42,153 @@ use common\models\Development;
use common\models\DevelopmentPriority;
use common\models\User;
use common\helpers\Url;
use common\helpers\GlobalParam;

$this->setTitle('Développement') ;
$this->addButton(['label' => 'Nouveau développement <span class="glyphicon glyphicon-plus"></span>', 'url' => ['development/create'], 'class' => 'btn btn-primary']) ;
$this->addBreadcrumb($this->getTitle()) ;
$this->setTitle('Développement');
$this->addButton(['label' => 'Nouveau développement <span class="glyphicon glyphicon-plus"></span>', 'url' => ['development/create'], 'class' => 'btn btn-primary']);
$this->addBreadcrumb($this->getTitle());

?>

<div class="development-index">
<div class="development-index">
<div class="well">
Cette page liste les besoins recencés auprès des producteurs utilisant la plateforme. N'hésitez pas à me <a href="<?= Yii::$app->urlManagerFrontend->createAbsoluteUrl(['site/contact']) ; ?>">contacter</a> pour la faire évoluer. Les remontées de bugs sont également bienvenues.<br />
Afin d'orienter de manière pertinente le développement de la plateforme, je vous invite à définir la priorité des évolutions qui vous intéressent.
Cette page liste les besoins recencés auprès des producteurs utilisant la plateforme. N'hésitez pas à me <a
href="<?= Yii::$app->urlManagerFrontend->createAbsoluteUrl(['site/contact']); ?>">contacter</a> pour la
faire évoluer. Les remontées de bugs sont également bienvenues.<br/>
Afin d'orienter de manière pertinente le développement de la plateforme, je vous invite à définir la priorité
des évolutions qui vous intéressent.
</div>
<ul id="tab-status-developments" class="nav nav-tabs" role="tablist">
<li role="presentation" class="<?php if($status == Development::STATUS_OPEN): ?>active<?php endif; ?>"><a href="<?= Yii::$app->urlManager->createUrl(['development/index','status' => Development::STATUS_OPEN]); ?>" id="" aria-controls="" role="tab">Ouvert</a></li>
<li role="presentation" class="<?php if($status == Development::STATUS_CLOSED): ?>active<?php endif; ?>"><a href="<?= Yii::$app->urlManager->createUrl(['development/index','status' => Development::STATUS_CLOSED]); ?>" id="" aria-controls="" role="tab">Fermé</a></li>
<li role="presentation" class="<?php if ($status == Development::STATUS_OPEN): ?>active<?php endif; ?>"><a
href="<?= Yii::$app->urlManager->createUrl(['development/index', 'status' => Development::STATUS_OPEN]); ?>"
id="" aria-controls="" role="tab">Ouvert</a></li>
<li role="presentation" class="<?php if ($status == Development::STATUS_CLOSED): ?>active<?php endif; ?>"><a
href="<?= Yii::$app->urlManager->createUrl(['development/index', 'status' => Development::STATUS_CLOSED]); ?>"
id="" aria-controls="" role="tab">Fermé</a></li>
</ul>
<?php
$columns = [
[
'header' => '#',
'value' => function($model) {
return '#'.$model->id ;
}
],
[
'attribute' => 'type',
'header' => 'Type',
'format' => 'raw',
'value' => function($model) {
if($model->type == Development::TYPE_EVOLUTION) {
return '<span class="label label-success">Évolution</span>' ;
}
else {
return '<span class="label label-danger">Anomalie</span>' ;
}
}
],
[ 'attribute' => 'sujet',
'format' => 'raw',
'value' => function($model) {
$html = '<strong>'.Html::encode($model->subject).'</strong>' ;
if(strlen($model->description))
$html .= '<br />'.nl2br(Html::encode($model->description)) ;
return $html ;
}],
[ 'attribute' => 'estimation_temps',
'header' => 'Estimation',
'format' => 'raw',
'value' => function($model) {
return intval($model->time_estimate).' h' ;
}],
[ 'attribute' => 'avancement',
'format' => 'raw',
'value' => function($model) {
if($model->progress)
return '<div class="progress">
<div class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="'.intval($model->progress).'" aria-valuemin="0" aria-valuemax="100" style="width: '.intval($model->progress).'%;">
<span class="sr-only">'.intval($model->progress).'% effectué</span>

<?php

$columns = [
[
'header' => '#',
'value' => function ($model) {
return '#' . $model->id;
}
],
[
'attribute' => 'type',
'header' => 'Type',
'format' => 'raw',
'value' => function ($model) {
if ($model->type == Development::TYPE_EVOLUTION) {
return '<span class="label label-success">Évolution</span>';
} else {
return '<span class="label label-danger">Anomalie</span>';
}
}
],
['attribute' => 'sujet',
'format' => 'raw',
'value' => function ($model) {
$html = '<strong>' . Html::encode($model->subject) . '</strong>';
if (strlen($model->description))
$html .= '<br />' . nl2br(Html::encode($model->description));
return $html;
}],
['attribute' => 'estimation_temps',
'header' => 'Estimation',
'format' => 'raw',
'value' => function ($model) {
return intval($model->time_estimate) . ' h';
}],
['attribute' => 'avancement',
'format' => 'raw',
'value' => function ($model) {
if ($model->progress)
return '<div class="progress">
<div class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="' . intval($model->progress) . '" aria-valuemin="0" aria-valuemax="100" style="width: ' . intval($model->progress) . '%;">
<span class="sr-only">' . intval($model->progress) . '% effectué</span>
</div>
</div> ' ;
else
return '' ;
}],
[ 'attribute' => 'date_delivery',
'format' => 'raw',
'value' => function($model) {
if(strlen($model->date_delivery))
return date('d/m/Y',strtotime($model->date_delivery)) ;
else
return '' ;
}],
] ;
if(User::hasAccessBackend()) {
$columns[] = [
'header' => 'Priorité',
'format' => 'raw',
'value' => function($model) {
$currentPriority = (isset($model->developmentPrioritYCurrentProducer)) ? $model->developmentPriorityCurrentProducer->getStrPriority() : 'Non' ;
$styleButton = (isset($model->developmentPriorityCurrentProducer)) ? $model->developmentPriorityCurrentProducer->getClassCssStyleButton() : 'default' ;
$html = '<div class="btn-group btn-group-priorite">
<button type="button" class="btn btn-priorite btn-sm btn-'.$styleButton.' dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
'.$currentPriority.' <span class="caret"></span>
</div> ';
else
return '';
}],
['attribute' => 'date_delivery',
'format' => 'raw',
'value' => function ($model) {
if (strlen($model->date_delivery))
return date('d/m/Y', strtotime($model->date_delivery));
else
return '';
}],
];
if (User::hasAccessBackend()) {
$columns[] = [
'header' => 'Priorité',
'format' => 'raw',
'value' => function ($model) {
$currentPriority = (isset($model->developmentPrioritYCurrentProducer)) ? $model->developmentPriorityCurrentProducer->getStrPriority() : 'Non';
$styleButton = (isset($model->developmentPriorityCurrentProducer)) ? $model->developmentPriorityCurrentProducer->getClassCssStyleButton() : 'default';
$html = '<div class="btn-group btn-group-priorite">
<button type="button" class="btn btn-priorite btn-sm btn-' . $styleButton . ' dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
' . $currentPriority . ' <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="'.Yii::$app->urlManager->createUrl(['development/priority','idDevelopment' => $model->id]).'">Non</a></li>
<li><a href="'.Yii::$app->urlManager->createUrl(['development/priority','idDevelopment' => $model->id, 'priority' => DevelopmentPriority::PRIORITY_LOW]).'">Basse</a></li>
<li><a href="'.Yii::$app->urlManager->createUrl(['development/priority','idDevelopment' => $model->id, 'priority' => DevelopmentPriority::PRIORITY_NORMAL]).'">Normale</a></li>
<li><a href="'.Yii::$app->urlManager->createUrl(['development/priority','idDevelopment' => $model->id, 'priority' => DevelopmentPriority::PRIORITY_HIGH]).'">Haute</a></li>
<li><a href="' . Yii::$app->urlManager->createUrl(['development/priority', 'idDevelopment' => $model->id]) . '">Non</a></li>
<li><a href="' . Yii::$app->urlManager->createUrl(['development/priority', 'idDevelopment' => $model->id, 'priority' => DevelopmentPriority::PRIORITY_LOW]) . '">Basse</a></li>
<li><a href="' . Yii::$app->urlManager->createUrl(['development/priority', 'idDevelopment' => $model->id, 'priority' => DevelopmentPriority::PRIORITY_NORMAL]) . '">Normale</a></li>
<li><a href="' . Yii::$app->urlManager->createUrl(['development/priority', 'idDevelopment' => $model->id, 'priority' => DevelopmentPriority::PRIORITY_HIGH]) . '">Haute</a></li>
</ul>
</div><br />' ;
if(isset($model->developmentPriority) && count($model->developmentPriority)) {
foreach($model->developmentPriority as $developmentPriority) {
if($developmentPriority->id_producer != Producer::getId())
$html .= '<div class="label label-priorite label-sm label-'.$developmentPriority->getClassCssStyleButton().'">'.Html::encode($developmentPriority->producer->name).'</div> ' ;
</div><br />';

if (isset($model->developmentPriority) && count($model->developmentPriority)) {
foreach ($model->developmentPriority as $developmentPriority) {
if ($developmentPriority->id_producer != GlobalParam::getCurrentProducerId())
$html .= '<div class="label label-priorite label-sm label-' . $developmentPriority->getClassCssStyleButton() . '">' . Html::encode($developmentPriority->producer->name) . '</div> ';
}
}

return $html;
}
}
return $html ;
}
] ;
];
}
if(User::getCurrentStatus() == USER::STATUS_ADMIN) {
$columns[] = [
'class' => 'yii\grid\ActionColumn',
'template' => '{update}',
'headerOptions' => ['class' => 'actions'],
'buttons' => [
'update' => function ($url, $model) {
return '<div class="btn-group">
<a href="'.$url.'" class="btn btn-default"><span class="glyphicon glyphicon-pencil"></span> Modifier</a>

if (User::getCurrentStatus() == USER::STATUS_ADMIN) {
$columns[] = [
'class' => 'yii\grid\ActionColumn',
'template' => '{update}',
'headerOptions' => ['class' => 'actions'],
'buttons' => [
'update' => function ($url, $model) {
return '<div class="btn-group">
<a href="' . $url . '" class="btn btn-default"><span class="glyphicon glyphicon-pencil"></span> Modifier</a>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu">
<li><a href="'.Yii::$app->urlManager->createUrl(['development/delete','id' => $model->id]).'" class=""><span class="glyphicon glyphicon-trash"></span> Supprimer</a></li>
<li><a href="' . Yii::$app->urlManager->createUrl(['development/delete', 'id' => $model->id]) . '" class=""><span class="glyphicon glyphicon-trash"></span> Supprimer</a></li>
</ul>
</div>' ;
},
],
] ;
}
?>
<?=
GridView::widget([
'id' => 'tab-developments',
'dataProvider' => $dataProvider,
'columns' => $columns
]);
?>
</div>';
},
],
];
}
?>
<?=
GridView::widget([
'id' => 'tab-developments',
'dataProvider' => $dataProvider,
'columns' => $columns
]);
?>
</div>

+ 136
- 77
backend/views/distribution/index.php Целия файл

@@ -1,38 +1,38 @@
<?php

/**
Copyright distrib (2018)
/**
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 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
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 de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
titulaire des de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
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 à
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é.
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
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.
*/
@@ -45,7 +45,7 @@ $this->setPageTitle('Distributions') ;
?>
<div id="app-distribution-index" class="app-vuejs">
<?php if(strlen($date)): ?>
<span id="distribution-date"><?= $date; ?></span>
<span id="distribution-date"><?= $date; ?></span>
<?php endif; ?>
<div id="loading" v-if="showLoading">
<img src="<?= Yii::$app->urlManagerBackend->getBaseUrl(); ?>/img/loader.gif" alt="Chargement ..." />
@@ -64,7 +64,7 @@ $this->setPageTitle('Distributions') ;
:theme-styles="calendar.themeStyles"
:attributes="calendar.attrs"
@dayclick='dayClicked'>
></v-date-picker>
></v-date-picker>
</div>
<div class="clr"></div>
</div>
@@ -86,7 +86,7 @@ $this->setPageTitle('Distributions') ;
</div>
</div>
</div>
<!-- produits -->
<div class="col-md-6">
<div class="info-box col-md-4">
@@ -120,13 +120,13 @@ $this->setPageTitle('Distributions') ;
<button class="btn btn-default" v-else data-active-product="0" :data-id-product="product.id" @click="productActiveClick"><span class="glyphicon glyphicon-remove"></span></button>
</td>
<td>{{ product.name }}</td>
<td class="quantity-ordered">{{ product.quantity_ordered ? product.quantity_ordered + ' '+ ((product.unit == 'piece') ? ' p.' : ' '+(product.unit == 'g' || product.unit == 'kg') ? 'kg' : 'litre(s)') : '&empty;' }}</td>
<td class="quantity-ordered">{{ product.quantity_ordered ? product.quantity_ordered + ' '+ ((product.unit == 'piece') ? ' p.' : ' '+(product.unit == 'g' || product.unit == 'kg') ? 'kg' : 'litre(s)') : '&empty;' }}</td>
<td class="quantity-max">
<div class="input-group">
<input type="text" class="form-control quantity-max" placeholder="&infin;" :data-id-product="product.id" v-model="product.productDistribution[0].quantity_max" @keyup="productQuantityMaxChange" />
<span class="input-group-addon">{{ (product.unit == 'piece') ? 'p.' : ' '+((product.unit == 'g' || product.unit == 'kg') ? 'kg' : 'litre(s)') }}</span>
</div>
</td>
</tr>
</tbody>
@@ -138,7 +138,7 @@ $this->setPageTitle('Distributions') ;
</div>
</div>
</modal>
<div class="col-md-6">
<div class="info-box col-md-4">
<span class="info-box-icon bg-yellow"><i class="fa fa-map-marker"></i></span>
@@ -174,13 +174,13 @@ $this->setPageTitle('Distributions') ;
</table>
</div>
</modal>
<div class="col-md-6">
<div id="summary-ca-weight" class="info-box col-md-4">
<span class="info-box-icon bg-yellow"><i class="fa fa-euro"></i></span>
<div class="info-box-content">
<span class="info-box-text">CA</span>
<span class="info-box-number">{{ distribution.revenues }} <span class="normal" v-if="distribution.potential_revenues != '0.00 €'">/ {{ distribution.potential_revenues }}</span></span>
<span class="info-box-text">CA (TTC)</span>
<span class="info-box-number">{{ distribution.revenues }} <span class="normal" v-if="distribution.potential_revenues != '0,00 €'">/ {{ distribution.potential_revenues }}</span></span>
<span class="info-box-text">Poids</span>
<span class="info-box-number">{{ distribution.weight }} kg <span class="normal" v-if="distribution.potential_weight > 0">/ {{ distribution.potential_weight }} kg</span></span>
</div>
@@ -217,45 +217,88 @@ $this->setPageTitle('Distributions') ;
<div class="panel-heading">
<h3 class="panel-title">Commandes <label class="label label-success" v-if="orders.length">{{ orders.length }}</label><label class="label label-danger" v-else>0</label></h3>
<div class="buttons">
<button id="btn-add-order" @click="showModalFormOrderCreate = true" class="btn btn-primary btn-xs"><span class="glyphicon glyphicon-plus"></span> Ajouter une commande</button>
<button id="btn-add-subscriptions" @click="addSubscriptions" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-plus"></span> Importer les abonnements</button>
<template v-if="producer.tiller == true">
<button v-if="tillerIsSynchro" id="btn-tiller" class="btn btn-xs btn-success" disabled><span class="glyphicon glyphicon-refresh"></span> Synchronisé avec Tiller</button>
<button v-else id="btn-tiller" class="btn btn-xs btn-default" @click="synchroTiller"><span class="glyphicon glyphicon-refresh"></span> Synchroniser avec Tiller</button>
</template>
</div>
</div>
<div class="panel-body">
<order-form
<order-form
v-if="showModalFormOrderCreate"
:date="date"
:order="orderCreate"
:points-sale="pointsSale"
:means-payment="meansPayment"
:users="users"
:users="users"
:products="products"
:producer="producer"
@close="showModalFormOrderCreate = false"
@ordercreatedupdated="orderCreatedUpdated"
></order-form>
<div id="wrapper-nav-points-sale">
<ul id="nav-points-sale">
<li data-id-point-sale="0" data-id-point-sale="0" v-if="countActivePointsSale > 1" @click="pointSaleClick">
<a class="btn btn-default btn-primary" v-if="idActivePointSale == 0">Tous <span class="label label-default">{{ orders.length }}</span> <span class="glyphicon glyphicon-triangle-bottom"></span></a>
<a class="btn btn-default" v-else>Tous <span class="label label-default">{{ orders.length }}</span><span class="glyphicon glyphicon-triangle-bottom"></span></a>
</li>
<li v-for="pointSale in pointsSale" :data-id-point-sale="pointSale.id" v-if="pointSale.pointSaleDistribution[0].delivery == 1" @click="pointSaleClick">
<a class="btn btn-default btn-primary" v-if="idActivePointSale == pointSale.id">{{ pointSale.name }} <span class="label label-default">{{ countOrdersByPointSale[pointSale.id] }}</span><span class="glyphicon glyphicon-triangle-bottom"></span></a>
<a class="btn btn-default" v-else>{{ pointSale.name }} <span class="label label-default">{{ countOrdersByPointSale[pointSale.id] }}</span><span class="glyphicon glyphicon-triangle-bottom"></span></a>
</li>
</ul>
<ul id="nav-points-sale">
<li data-id-point-sale="0" data-id-point-sale="0" v-if="countActivePointsSale > 1" @click="pointSaleClick">
<a class="btn btn-default btn-primary" v-if="idActivePointSale == 0">Tous <span class="label label-default">{{ orders.length }}</span> <span class="glyphicon glyphicon-triangle-bottom"></span></a>
<a class="btn btn-default" v-else>Tous <span class="label label-default">{{ orders.length }}</span><span class="glyphicon glyphicon-triangle-bottom"></span></a>
</li>
<li v-for="pointSale in pointsSale" :data-id-point-sale="pointSale.id" v-if="pointSale.pointSaleDistribution[0].delivery == 1" @click="pointSaleClick">
<a class="btn btn-default btn-primary" v-if="idActivePointSale == pointSale.id">{{ pointSale.name }} <span class="label label-default">{{ countOrdersByPointSale[pointSale.id] }}</span><span class="glyphicon glyphicon-triangle-bottom"></span></a>
<a class="btn btn-default" v-else>{{ pointSale.name }} <span class="label label-default">{{ countOrdersByPointSale[pointSale.id] }}</span><span class="glyphicon glyphicon-triangle-bottom"></span></a>
</li>
</ul>
<div class="clr"></div>
</div>

<div id="buttons-top-orders">
<div class="right">
<a v-if="idActivePointSale > 0" @click="generateDeliveryNote" href="javascript:void(0);" class="btn btn-default btn-xs">
<span class="glyphicon glyphicon-plus"></span>
<span v-if="deliveryNoteExist(idActivePointSale)">Regénérer le bon de livraison</span>
<span v-else>Générer un bon de livraison</span>
</a>
<button id="btn-add-subscriptions" @click="addSubscriptions" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-plus"></span> Importer les abonnements</button>
<template v-if="producer.tiller == true">
<button v-if="tillerIsSynchro" id="btn-tiller" class="btn btn-success btn-xs" disabled><span class="glyphicon glyphicon-refresh"></span> Synchronisé avec Tiller</button>
<button v-else id="btn-tiller" class="btn btn-xs btn-default" @click="synchroTiller"><span class="glyphicon glyphicon-refresh"></span> Synchroniser avec Tiller</button>
</template>
<button id="btn-add-order" @click="showModalFormOrderCreate = true" class="btn btn-xs btn-primary"><span class="glyphicon glyphicon-plus"></span> Ajouter une commande</button>
</div>
<div class="left">
<a v-if="deliveryNoteExist(idActivePointSale)" :href="UrlManager.getBaseUrl()+'delivery-note/update?id='+deliveryNotes[idActivePointSale].id" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-file"></span> Bon de livraison</a>
<!--<div v-if="idActivePointSale > 0" class="btn-group">
<button type="button" class="btn btn-success btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Action groupée <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a @click="generateDeliveryNote" href="javascript:void(0);">Générer un bon de livraison</a></li>
</ul>
</div>-->
</div>
<div class="clr"></div>
</div>

<table class="table table-condensed table-bordered table-hover" v-if="countOrdersByPointSale[idActivePointSale] > 0 || (idActivePointSale == 0 && orders.length > 0)">
<thead>
<tr>
<th v-if="idActivePointSale > 0">
<input type="checkbox" v-model="checkboxSelectAllOrders" @change="selectAllOrdersEvent" />
</th>
<th>Origine</th>
<th>État</th>
<th>Utilisateur</th>
<th v-if="idActivePointSale == 0">Point de vente</th>
<th>Montant</th>
<th>Paiement</th>
<th></th>
<th v-if="producer.tiller">Tiller</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<template v-for="(order, key, index) in orders" v-if="idActivePointSale == 0 || idActivePointSale == order.id_point_sale">
<tr>
<td v-if="idActivePointSale > 0">
<input type="checkbox" v-model="order.selected" />
</td>
<td>
<label class="label label-success" v-if="order.origin == 'user'">client</label>
<label class="label label-default" v-else-if="order.origin == 'auto'">auto</label>
@@ -276,12 +319,12 @@ $this->setPageTitle('Distributions') ;
</td>
<td>{{ order.amount.toFixed(2).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+'&nbsp;€' }}</td>
<td class="column-state-payment">
<div class="input-group">
<div class="input-group">
<span class="label label-success input-group-addon" v-if="order.amount_paid == order.amount">payé</span>
<span class="label label-default input-group-addon" v-else-if="order.amount_paid == 0">non réglé</span>
<span class="label label-default input-group-addon" v-else-if="order.amount_paid > order.amount">surplus</span>
<span class="label label-warning input-group-addon" v-else-if="order.amount_paid < order.amount">reste à payer</span>
<span class="glyphicon glyphicon-time" title="Paiement automatique" v-if="order.auto_payment && producer.credit && (order.amount_paid == 0 || order.amount_paid < order.amount)"></span>
</div>
</td>
@@ -299,7 +342,7 @@ $this->setPageTitle('Distributions') ;
<button class="btn btn-xs btn-default" v-else-if="order.amount_paid > order.amount" @click="orderPaymentClick" :data-id-order="order.id" data-type="refund" :data-amount="order.amount_surplus">
<span class="glyphicon glyphicon-euro"></span> Rembourser
</button>
<button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
@@ -316,26 +359,32 @@ $this->setPageTitle('Distributions') ;
</td>
<td class="column-actions">
<span v-if="order.oneProductUnactivated" class="glyphicon glyphicon-warning-sign" title="Contient un produit non activé"></span>
<button class="btn btn-default" :data-id-order="order.id" @click="orderViewClick"><span :class="'glyphicon ' + ((showViewProduct && idOrderView == order.id) ? 'glyphicon-eye-close' : 'glyphicon-eye-open')"></span></button>
<button class="btn btn-default" :data-id-order="order.id" @click="updateOrderClick"><span class="glyphicon glyphicon-pencil"></span></button>
<button class="btn btn-default" :data-id-order="order.id" @click="deleteOrderClick"><span class="glyphicon glyphicon-trash"></span></button>
<a class="btn btn-default" :href="baseUrl+'/subscription/update?id='+order.id_subscription" v-if="order.id_subscription > 0"><span class="glyphicon glyphicon-repeat"></span></a>
<a class="btn btn-default add-subscription" :href="baseUrl+'/subscription/create?idOrder='+order.id" v-else><span class="glyphicon glyphicon-plus"></span><span class="glyphicon glyphicon-repeat"></span></a>
<order-form

<button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Action <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="javascript:void(0);" class="" :data-id-order="order.id" @click="orderViewClick"><span :class="'glyphicon ' + ((showViewProduct && idOrderView == order.id) ? 'glyphicon-eye-close' : 'glyphicon-eye-open')"></span> Voir</a></li>
<li><a href="javascript:void(0);" class="" :data-id-order="order.id" @click="updateOrderClick"><span class="glyphicon glyphicon-pencil"></span> Modifier</a></li>
<li><a href="javascript:void(0);" class="" :data-id-order="order.id" @click="deleteOrderClick"><span class="glyphicon glyphicon-trash"></span> Supprimer</a></li>
<li v-if="order.id_subscription > 0"><a class="" :href="baseUrl+'/subscription/update?id='+order.id_subscription"><span class="glyphicon glyphicon-repeat"></span> Modifier l'abonnement associé</a></li>
<li v-else><a class="add-subscription" :href="baseUrl+'/subscription/create?idOrder='+order.id"><span class="glyphicon glyphicon-plus"></span><span class="glyphicon glyphicon-repeat"></span>Créer un abonnement sur cette base</a></li>
</ul>

<order-form
v-if="showModalFormOrderUpdate && idOrderUpdate == order.id"
:date="date"
:id-point-sale="idActivePointSale"
:points-sale="pointsSale"
:means-payment="meansPayment"
:users="users"
:users="users"
:products="products"
:order="ordersUpdate[key]"
:producer="producer"
@close="showModalFormOrderUpdate = false"
@ordercreatedupdated="orderCreatedUpdated"
></order-form>
<modal v-if="showModalPayment && idOrderPayment == order.id" class="modal-payment" @close="showModalPayment = false">
<h3 slot="header">
Commande du <strong>{{ dateFormat }}</strong> &gt;
@@ -354,11 +403,11 @@ $this->setPageTitle('Distributions') ;
<span class="label label-success" v-if="order.amount_paid == order.amount">payé</span>
<span class="label label-default" v-else-if="order.amount_paid == 0">non réglé</span>
<span class="label label-default" v-else-if="order.amount_paid > order.amount">surplus</span>
<span class="label label-warning" v-else-if="order.amount_paid < order.amount">reste à payer</span>
<span class="label label-warning" v-else-if="order.amount_paid < order.amount">reste à payer</span>
</span>
</div>
</div>
<div class="info-box">
<span :class="'info-box-icon ' +((order.user.credit > 0) ? 'bg-green' : 'bg-red')"><i class="fa fa-user"></i></span>
<div class="info-box-content">
@@ -366,44 +415,44 @@ $this->setPageTitle('Distributions') ;
<span class="info-box-number">{{ order.user.credit.toFixed(2).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}</span>
</div>
</div>
<button v-if="order.amount_paid == order.amount"
class="btn btn-default"
:data-amount="order.amount"
<button v-if="order.amount_paid == order.amount"
class="btn btn-default"
:data-amount="order.amount"
data-type="refund"
@click="orderPaymentClick" >
<span class="glyphicon glyphicon-chevron-right"></span>
<span class="glyphicon glyphicon-chevron-right"></span>
Rembourser {{ order.amount.toFixed(2).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}
</button>
<button v-else-if="order.amount_paid == 0"
class="btn btn-default"
:data-amount="order.amount"
<button v-else-if="order.amount_paid == 0"
class="btn btn-default"
:data-amount="order.amount"
data-type="payment"
@click="orderPaymentClick">
<span class="glyphicon glyphicon-chevron-right"></span>
<span class="glyphicon glyphicon-chevron-right"></span>
Payer {{ order.amount.toFixed(2).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}
</button>
<button v-else-if="order.amount_paid > order.amount"
<button v-else-if="order.amount_paid > order.amount"
class="btn btn-default"
:data-amount="order.amount_surplus"
:data-amount="order.amount_surplus"
data-type="refund"
@click="orderPaymentClick">
<span class="glyphicon glyphicon-chevron-right"></span>
<span class="glyphicon glyphicon-chevron-right"></span>
Rembourser {{ order.amount_surplus.toFixed(2).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}
</button>
<button v-else-if="order.amount_paid < order.amount"
class="btn btn-default"
:data-amount="order.amount_remaining"
class="btn btn-default"
:data-amount="order.amount_remaining"
data-type="payment"
@click="orderPaymentClick">
<span class="glyphicon glyphicon-chevron-right"></span>
<span class="glyphicon glyphicon-chevron-right"></span>
Payer le restant {{ order.amount_remaining.toFixed(2).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}
</button>
</div>
<div class="col-md-8">
<h4>Historique paiement</h4>
<table class="table table-condensed table-bordered table-hover">
@@ -427,10 +476,15 @@ $this->setPageTitle('Distributions') ;
</tbody>
</table>
</div>
</div>
</modal>

</td>
<td>
<a v-if="order.id_delivery_note" class="btn btn-default btn-xs" :href="UrlManager.getBaseUrl()+'delivery-note/update?id='+order.id_delivery_note">
<span class="glyphicon glyphicon-file"></span> BL
</a>
</td>
</tr>
<tr class="view" v-if="showViewProduct && idOrderView == order.id">
@@ -438,7 +492,7 @@ $this->setPageTitle('Distributions') ;
<strong><span class="glyphicon glyphicon-menu-right"></span> Produits</strong>
<ul>
<li v-for="product in products" v-if="order.productOrder[product.id].quantity > 0">
{{ product.name }} : {{ order.productOrder[product.id].quantity }} {{ order.productOrder[product.id].unit == 'piece' ? ' pièce(s)' : ' '+order.productOrder[product.id].unit }} <span v-if="product.productDistribution[0].active == 0" class="glyphicon glyphicon-warning-sign" title="Ce produit n'est pas activé"></span>
{{ product.name }} : {{ order.productOrder[product.id].quantity }} {{ order.productOrder[product.id].unit == 'piece' ? ' pièce(s)' : ' '+order.productOrder[product.id].unit }} <span v-if="product.productDistribution[0].active == 0" class="glyphicon glyphicon-warning-sign" title="Ce produit n'est pas activé"></span>
</li>
</ul>
<div v-if="order.comment && order.comment.length > 0" class="comment">
@@ -448,6 +502,11 @@ $this->setPageTitle('Distributions') ;
</td>
</tr>
</template>
<tr v-if="idActivePointSale > 0">
<td colspan="4"><strong>Total (TTC)</strong></td>
<td><strong>{{ totalActivePointSale() }}</strong></td>
<td colspan="3"></td>
</tr>
</tbody>
</table>
<div class="alert alert-warning" v-else>
@@ -528,7 +587,7 @@ $this->setPageTitle('Distributions') ;
<button class="btn btn-default btn-plus" type="button" @click="productQuantityClick(product.id, order.productOrder[product.id].unit == 'piece' ? 1 : parseFloat(product.step))"><span class="glyphicon glyphicon-plus"></span></button>
</span>
</div>
</td>
</td>
<td class="quantity-remaining infinite" v-if="product.quantity_remaining === null || order.productOrder[product.id].unit != product.unit">&infin;</td>
<td class="quantity-remaining negative" v-else-if="product.quantity_remaining <= 0">{{ product.quantity_remaining }} {{ order.productOrder[product.id].unit == 'piece' ? ' p.' : ' '+(order.productOrder[product.id].unit == 'g' || order.productOrder[product.id].unit == 'kg') ? 'kg' : 'litre(s)' }}</td>
<td class="quantity-remaining has-quantity" v-else>{{ product.quantity_remaining }} {{ order.productOrder[product.id].unit == 'piece' ? ' p.' : ' '+(order.productOrder[product.id].unit == 'g' || order.productOrder[product.id].unit == 'kg') ? 'kg' : 'litre(s)' }}</td>
@@ -541,7 +600,7 @@ $this->setPageTitle('Distributions') ;
<div class="actions-form">
<button class="modal-default-button btn btn-primary" @click="submitFormCreate" v-if="!order.id && order.id_user > 0" data-process-credit="1">Créer et payer</button>
<button class="modal-default-button btn btn-primary" @click="submitFormUpdate" v-if="order.id && order.id_user > 0" data-process-credit="1">Modifier et payer</button>
<button class="modal-default-button btn btn-primary" @click="submitFormUpdate" v-if="order.id">Modifier</button>
<button class="modal-default-button btn btn-primary" @click="submitFormCreate" v-else>Créer</button>


+ 1
- 1
backend/views/distribution/report.php Целия файл

@@ -106,7 +106,7 @@ foreach ($pointsSaleArray as $pointSale) {
$html .= '<td>'.$credit.'</td>' ;
}
$html .= '<td><strong>'.number_format($order->amount, 2) . ' € ';
$html .= '<td><strong>'.number_format($order->amount_with_tax, 2) . ' € ';

if($order->getPaymentStatus() == Order::PAYMENT_PAID)
{

+ 313
- 0
backend/views/document/_form.php Целия файл

@@ -0,0 +1,313 @@
<?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.
*/

use yii\helpers\Html;
use yii\widgets\ActiveForm;
use common\models\Product;
use yii\helpers\ArrayHelper;
use common\models\TaxRate;
use common\models\Producer;

\backend\assets\VuejsDocumentFormAsset::register($this);

?>

<div class="document-form" id="app-document-form" data-class-document="<?= $model->getClass() ?>"
data-id-document="<?= ($model->id > 0) ? $model->id : $model->id ?>">

<div class="<?= ($action == 'update') ? 'col-md-6' : '' ?>">
<div class="panel panel-default">
<div class="panel-heading">
Général
</div>
<div class="panel-body">
<?php $form = ActiveForm::begin(); ?>
<?= Html::hiddenInput('classDocument',$model->getClass(), ['id' => 'class-document']) ?>
<?= Html::hiddenInput('typeAction',$action, ['id' => 'type-action']) ?>
<?php if ($action == 'update'): ?>
<?= Html::hiddenInput('idDocument',$model->id, ['id' => 'id-document']) ?>
<?php endif; ?>
<?= $form->field($model, 'name')->label('Nom du document') ?>

<?php if($action == 'update'): ?>
<?= $form->field($model, 'id_user', [
'template' => '{label} <div>{input}</div>'.$model->user->getUsername(),
])->hiddenInput(); ?>
<?php else: ?>
<?php
$usersArray = User::findBy()->all();
?>
<?= $form->field($model, 'id_user', [
'template' => '{label} <a href="' . Yii::$app->urlManager->createUrl(['user/create']) . '" class="btn btn-xs btn-default">Nouvel utilisateur <span class="glyphicon glyphicon-plus"></span></a><div>{input}</div>{hint}',
])
->dropDownList(
ArrayHelper::map($usersArray, 'user_id', function ($model) {
if(isset($model['name_legal_person']) && strlen($model['name_legal_person'])) {
return $model['name_legal_person'] ;
}
else {
return $model['lastname'] . ' ' . $model['name'];
}
}),
[
'@change' => 'changeUser',
'prompt' => '--',
'v-model' => 'idUser',
]
); ?>
<?php endif; ?>


<?= $form->field($model, 'address')->textarea(['rows' => 2, 'v-model' => 'document.address']) ?>
<?php if ($action == 'update'): ?>
<?= $form->field($model, 'comment')->textarea(['rows' => 2])->hint('Affiché en bas de la facture') ?>
<?php endif; ?>

<?php if($model->getClass() == 'Invoice'): ?>
<template v-if="idUser > 0">
<strong>Bons de livraison</strong>
<table v-if="deliveryNotes && deliveryNotes.length > 0" class="table table-bordered">
<thead>
<tr>
<?php if($action == 'create'): ?><th></th><?php endif; ?>
<th>Libellé</th>
<th v-if="taxRateProducer != 0">Montant (TTC)</th>
<th v-else>Montant</th>
</tr>
</thead>
<tbody>
<tr v-for="deliveryNote in deliveryNotes">
<?php if($action == 'create'): ?>
<td><input type="checkbox" name="Invoice[deliveryNotes][]" :value="deliveryNote.id" /></td>
<?php endif; ?>
<td>{{ deliveryNote.name }}</td>
<td>{{ formatPrice(deliveryNote.total) }}</td>
</tr>
</tbody>
</table>
<div v-else class="alert alert-warning">Aucun bon de livraison pour cet utilisateur.</div>
</template>
<?php endif; ?>

<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Ajouter' : 'Modifier', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
</div>

<?php if ($action == 'update'): ?>

<div class="col-md-6">
<div id="" class="info-box">
<span class="info-box-icon bg-green"><i class="fa fa-sticky-note-o"></i></span>
<div class="info-box-content">
<span class="info-box-text"><?= $typeDocument ?> <span v-html="document.html_label"></span></span>
<span class="info-box-number">{{ document.reference }}</span>
<span class="info-box-text">Date</span>
<span class="info-box-number">{{ document.date }}</span>
</div>
</div>
<div id="" class="info-box">
<span class="info-box-icon bg-yellow"><i class="fa fa-euro"></i></span>
<div class="info-box-content">
<span class="info-box-text">Total<span v-if="taxRateProducer != 0"> (TTC)</span></span>
<span class="info-box-number">{{ formatPrice(total_with_tax) }}</span>
</div>
</div>
<div id="" class="info-box">
<span class="info-box-icon bg-blue"><i class="fa fa-download"></i></span>
<div class="info-box-content">
<a href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl().'/download', 'id' => $model->id]) ?>" class="btn btn-default"><span class="glyphicon glyphicon-download-alt"></span> Télécharger (PDF)</a>
</div>
</div>
<div v-if="document.status == 'draft'" id="" class="info-box">
<span class="info-box-icon bg-red"><i class="fa fa-flash"></i></span>
<div class="info-box-content">
<form action="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl().'/validate']) ?>">
<?= Html::hiddenInput('id', $model->id); ?>
<button class="btn btn-default"><span class="glyphicon glyphicon-ok"></span> Valider le document</button>
</form>
</div>
</div>
</div>
<div class="clr"></div>

<div class="">
<div class="panel panel-default" id="block-add-product">
<div class="panel-heading">
Ajouter un produit
</div>
<div class="panel-body">
<div class="col-md-3">
<strong>Produit</strong>
<select class="form-control" v-model="productAddId"
@change="changeProductAdd">
<option value="0" selected="selected">--</option>
<option v-for="product in productsArray" :value="product.id">
{{ product.name }}
</option>
</select>
</div>
<template v-if="productAddId > 0">
<div class="col-md-3">
<strong>Prix unitaire</strong>
<div class="input-group">
<input type="text" class="form-control input-price"
v-model="productAddPrice" @change="formatProductAddPrice"/>
<span class="input-group-addon"><span
class="glyphicon glyphicon-euro"></span> <span v-if="taxRateProducer != 0">TTC</span></span>
</div>
</div>
<div class="col-md-3">
<strong>Quantité</strong>
<div class="input-group input-group-quantity">
<span class="input-group-btn">
<button class="btn btn-default" type="button"
@click="changeQuantityProductAdd(-1)">-</button>
</span>
<input type="text" class="form-control input-quantity"
v-model="productAddQuantity" @change="formatProductAddQuantity"/>
<span class="input-group-addon">{{ productsArray[productAddId].wording_unit }}</span>
<span class="input-group-btn">
<button class="btn btn-default"
type="button"
@click="changeQuantityProductAdd(1)">+</button>
</span>
</div>
</div>
<div class="col-md-3 total">
<strong>Total</strong>
<div class="input-group">
<input type="text" class="form-control input-price" readonly
:value="formatPrice(productAddPrice * productAddQuantity)"/>
<span class="input-group-addon"><span
class="glyphicon glyphicon-euro"></span> <span v-if="taxRateProducer != 0">TTC</span></span>
</div>
<button class="btn btn-primary" value="Ajouter"
@click="submitProductAdd">Ajouter
</button>
<div class="clr"></div>
</div>
</template>
<div class="clr"></div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
Produits
</div>
<div class="panel-body">
<div id="block-list-products">
<table class="table table-bordered" v-if="total > 0">
<thead>
<tr>
<th>Nom</th>
<th>Prix (unité)</th>
<th>Quantité</th>
<th v-if="taxRateProducer != 0">TVA</th>
<th v-if="taxRateProducer != 0">Total TTC</th>
<th v-else>Total</th>
<th>Supprimer</th>
</tr>
</thead>
<tbody>
<template v-for="order in ordersArray">
<tr v-for="productOrder in order.productOrder">
<td class="col-md-4">
<div class="product-name">{{ productsArray[productOrder.id_product].name }}</div>
<ul class="product-order-meta">
<li>{{ order.username }}</li>
<li v-if="order.distribution_date">{{ order.distribution_date }}</li>
<li v-if="order.point_sale_name">{{ order.point_sale_name }}</li>
</ul>
</td>
<td class="col-md-2">{{ formatPrice(productOrder.price) }}</td>
<td class="col-md-2">{{ productOrder.quantity }}</td>
<td class="col-md-1" v-if="taxRateProducer != 0">
{{ productsArray[productOrder.id_product].tax_rate * 100 }} %
</td>
<td class="col-md-2">
{{ formatPrice(productOrder.quantity * productOrder.price) }}
</td>
<td class="col-md-1">
<a class="btn btn-default" @click="deleteProductOrder(productOrder.id)">
<span class="glyphicon glyphicon-trash"></span>
</a>
</td>
</tr>
</template>
<template v-if="taxRateProducer != 0">
<tr>
<td colspan="4"><strong>Total HT</strong></td>
<td><strong>{{ formatPrice(total) }} HT</strong></td>
<td></td>
</tr>
<tr>
<td colspan="4"><strong>Montant TVA</strong></td>
<td><strong>{{ formatPrice(total_with_tax - total) }}</strong></td>
<td></td>
</tr>
<tr>
<td colspan="4"><strong>Total TTC</strong></td>
<td><strong>{{ formatPrice(total_with_tax) }} TTC</strong></td>
<td></td>
</tr>
</template>
<template v-else>
<tr>
<td colspan="3"><strong>Total</strong></td>
<td><strong>{{ formatPrice(total) }}</strong></td>
<td></td>
</tr>
</template>

</tbody>
</table>
<div v-else class="alert alert-info">
Aucun produit.
</div>
</div>
</div>
</div>
</div>
<?php endif; ?>


</div>

+ 53
- 0
backend/views/document/create.php Целия файл

@@ -0,0 +1,53 @@
<?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.
*/

use yii\helpers\Html;

$this->setTitle($title) ;
$this->addBreadcrumb(['label' => $typeDocument.'s', 'url' => ['index']]) ;
$this->addBreadcrumb('Ajouter') ;

?>

<div class="document-create">
<?= $this->render('_form', [
'action' => 'create',
'model' => $model,
'typeDocument' => $typeDocument,
]) ?>
</div>

+ 129
- 0
backend/views/document/download.php Целия файл

@@ -0,0 +1,129 @@
<?php

?>

<div class="document-download">

<div id="block-addresses">
<div class="producer">
<?php if(strlen($producer->logo)) : ?>
<div class="logo"><?= $producer->getHtmlLogo() ; ?></div>
<?php endif; ?>
<div class="address"><?= $producer->getFullAddress(true) ; ?></div>
</div>
<div class="user">
<?= $document->user->getFullAddress(true) ; ?>
</div>
</div>

<div id="block-infos-document">
<div class="date">
Le <?= strftime('%d %B %Y', strtotime($document->date)) ?>
</div>
<div class="reference">
<?php if(strlen($document->reference)) : ?>
<?= $document->getType(); ?> N°<?= $document->reference ; ?>
<?php else: ?>
<div class="block-is-draft"><?= $document->getType(); ?> non validé<?= ($document->getType() == 'Facture') ? 'e' : '' ?></div>
<?php endif; ?>
</div>
<div class="name">
<strong>Libellé : </strong><?= $document->name ; ?>
</div>
</div>

<div id="block-products">
<?php if(count($document->orders) > 0) : ?>
<table class="table table-bordered">
<thead>
<tr>
<th class="align-left">Produit</th>
<?php if(Yii::$app->controller->getClass() != 'DeliveryNote'): ?>
<?php if(GlobalParam::getCurrentProducer()->taxRate->value == 0): ?>
<th>Prix unitaire</th>
<?php else: ?>
<th>Prix unitaire HT</th>
<?php endif; ?>
<?php endif; ?>
<th>Quantité</th>
<th>Unité</th>
<?php if(Yii::$app->controller->getClass() != 'DeliveryNote'): ?>
<?php if(GlobalParam::getCurrentProducer()->taxRate->value == 0): ?>
<th>Prix</th>
<?php else: ?>
<th>TVA</th>
<th>Prix HT</th>
<?php endif; ?>
<?php endif; ?>

</tr>
</thead>
<tbody>
<?php foreach($document->getProductsOrders() as $product): ?>
<?php foreach($product as $productOrder): ?>
<tr>
<td class="align-left"><?= Html::encode($productOrder->product->name) ?></td>
<?php if(Yii::$app->controller->getClass() != 'DeliveryNote'): ?>
<td class="align-center"><?= Price::format($productOrder->getPrice()) ?></td>
<?php endif; ?>
<td class="align-center"><?= $productOrder->quantity ?></td>
<td class="align-center"><?= Product::strUnit($productOrder->unit, 'wording') ?></td>
<?php if(Yii::$app->controller->getClass() != 'DeliveryNote'): ?>
<?php if(GlobalParam::getCurrentProducer()->taxRate->value != 0): ?>
<td class="align-center"><?= $productOrder->taxRate->value * 100 ?> %</td>
<?php endif; ?>
<td class="align-center"><?= Price::format($productOrder->getPrice() * $productOrder->quantity) ?></td>
<?php endif; ?>

</tr>
<?php endforeach; ?>
<?php endforeach; ?>
<?php if(Yii::$app->controller->getClass() != 'DeliveryNote'): ?>
<?php if(GlobalParam::getCurrentProducer()->taxRate->value != 0): ?>
<tr>
<td class="align-right" colspan="5"><strong>Total HT</strong></td>
<td class="align-center"><?= Price::format($document->getAmount()) ?></td>
</tr>
<tr>
<td class="align-right" colspan="5"><strong>TVA</strong></td>
<td class="align-center"><?= Price::format($document->getAmountWithTax() - $document->getAmount()) ?></td>
</tr>
<tr>
<td class="align-right" colspan="5"><strong>Total TTC</strong></td>
<td class="align-center"><?= Price::format($document->getAmountWithTax()) ?></td>
</tr>
<?php else: ?>
<tr>
<td class="align-right" colspan="4">
<strong>Total</strong><br />
TVA non applicable
</td>
<td class="align-center"><?= Price::format($document->getAmount()) ?></td>
</tr>
<?php endif; ?>
<?php endif; ?>
</tbody>
</table>
<?php else : ?>
<div id="block-no-product">
<strong>Aucun produit</strong>
</div>
<?php endif; ?>
</div>

<?php if(strlen($document->comment)): ?>
<div class="block-infos">
<strong>Commentaire</strong><br />
<?= Html::encode($document->comment) ?>
</div>
<?php endif; ?>

<?php
$fieldProducerDocumentInfo = 'document_infos_'.str_replace('deliverynote','delivery_note',strtolower($document->getClass())) ; ?>
<?php if(strlen($producer->$fieldProducerDocumentInfo)): ?>
<div class="block-infos">
<strong>Informations</strong><br />
<?= nl2br(Html::encode($producer->$fieldProducerDocumentInfo)) ?>
</div>
<?php endif; ?>
</div>

+ 54
- 0
backend/views/document/update.php Целия файл

@@ -0,0 +1,54 @@
<?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.
*/

use yii\helpers\Html;

$this->setTitle($title) ;
$this->addBreadcrumb(['label' => $typeDocument.($typeDocument == 'Facture' ? 's' : ''), 'url' => ['index']]) ;
$this->addBreadcrumb(['label' => $model->name, 'url' => ['update', 'id' => $model->id]]) ;
$this->addBreadcrumb('Modifier') ;

?>

<div class="product-update">
<?= $this->render('_form', [
'action' => 'update',
'model' => $model,
'typeDocument' => $typeDocument,
]) ?>
</div>

+ 135
- 0
backend/views/invoice/index.php Целия файл

@@ -0,0 +1,135 @@
<?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.
*/

use yii\helpers\Html;
use yii\grid\GridView;
use common\helpers\Url;
use common\models\Product;
use common\models\TaxRate;
use common\models\Producer;

$this->setTitle('Factures');
$this->addBreadcrumb($this->getTitle());
$this->addButton(['label' => 'Nouvelle facture <span class="glyphicon glyphicon-plus"></span>', 'url' => 'invoice/create', 'class' => 'btn btn-primary']);

?>

<div class="invoice-index">
<?= GridView::widget([
'filterModel' => $searchModel,
'dataProvider' => $dataProvider,
'columns' => [
[
'attribute' => 'status',
'label' => 'Statut',
'filter' => [
'draft' => 'Brouillon',
'valid' => 'Valide',
],
'format' => 'raw',
'value' => function($model) {
return $model->getHtmlLabel() ;
}
],
[
'attribute' => 'reference',
'value' => function($model) {
if(strlen($model->reference) > 0) {
return $model->reference ;
}
return '' ;
}
],
'name',
[
'attribute' => 'id_user',
'header' => 'Utilisateur',
'value' => function($model) {
return $model->user->getUsername() ;
}
],
[
'attribute' => 'date',
'header' => 'Date',
'value' => function($model) {
return date('d/m/Y',strtotime($model->date)) ;
}
],
[
'attribute' => 'amount',
'header' => 'Montant',
'value' => function($invoice) {
return $invoice->getAmountWithTax(Order::AMOUNT_TOTAL, true) ;
}
],
[
'class' => 'yii\grid\ActionColumn',
'template' => '{validate} {update} {delete} {send} {download}',
'headerOptions' => ['class' => 'column-actions'],
'contentOptions' => ['class' => 'column-actions'],
'buttons' => [
'validate' => function ($url, $model) {
return ($model->isStatusDraft() ? Html::a('<span class="glyphicon glyphicon-ok"></span>', $url, [
'title' => Yii::t('app', 'Valider'), 'class' => 'btn btn-default'
]) : '');
},
'send' => function($url, $model) {
return (!$model->isStatusDraft() ? Html::a('<span class="glyphicon glyphicon-send"></span>', $url, [
'title' => Yii::t('app', 'Envoyer'), 'class' => 'btn btn-default'
]) : '');
},
'download' => function($url, $model) {
return Html::a('<span class="glyphicon glyphicon-download-alt"></span>', $url, [
'title' => Yii::t('app', 'Télécharger'), 'class' => 'btn btn-default'
]);
},
'update' => function ($url, $model) {
return ($model->isStatusDraft() ? Html::a('<span class="glyphicon glyphicon-pencil"></span>', $url, [
'title' => Yii::t('app', 'Modifier'), 'class' => 'btn btn-default'
]) : '');
},
'delete' => function ($url, $model) {
return ($model->isStatusDraft() ? Html::a('<span class="glyphicon glyphicon-trash"></span>', $url, [
'title' => Yii::t('app', 'Supprimer'), 'class' => 'btn btn-default'
]) : '');
}
],
],
],
]); ?>
</div>

+ 12
- 1
backend/views/layouts/content.php Целия файл

@@ -278,4 +278,15 @@ use dmstr\widgets\Alert;
</aside><!-- /.control-sidebar -->
<!-- Add the sidebar's background. This div must be placed
immediately after the control sidebar -->
<div class='control-sidebar-bg'></div>
<div class='control-sidebar-bg'></div>

<!-- alerts -->
<div id="app-alerts">
<template v-for="alert in alerts">
<transition name="slide-fade">
<div v-if="alert.display == true" :class="'alert alert-'+alert.type">
{{ alert.message }}
</div>
</transition>
</template>
</div>

+ 207
- 190
backend/views/layouts/header.php Целия файл

@@ -1,57 +1,58 @@
<?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.
*/
/**
* 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.
*/

use yii\helpers\Html;
use common\models\Producer;
use common\models\User;
use yii\widgets\ActiveForm;
use yii\helpers\ArrayHelper;
use common\helpers\GlobalParam;

/* @var $this \yii\web\View */
/* @var $content string */

$producer = Producer::getCurrent() ;
$producer = GlobalParam::getCurrentProducer();

?>

<header class="main-header">

<?= Html::a('<span class="logo-mini"><img src="'.Yii::$app->urlManagerBackend->getBaseUrl().'/img/logo-distrib.png" /></span><span class="logo-lg"><img src="'.Yii::$app->urlManagerBackend->getBaseUrl().'/img/logo-distrib.png" /></span>', Yii::$app->homeUrl, ['class' => 'logo']) ?>
<?= Html::a('<span class="logo-mini"><img src="' . Yii::$app->urlManagerBackend->getBaseUrl() . '/img/logo-distrib.png" /></span><span class="logo-lg"><img src="' . Yii::$app->urlManagerBackend->getBaseUrl() . '/img/logo-distrib.png" /></span>', Yii::$app->homeUrl, ['class' => 'logo']) ?>

<nav class="navbar navbar-static-top" role="navigation">

@@ -60,202 +61,218 @@ $producer = Producer::getCurrent() ;
</a>

<div class="navbar-custom-menu">
<?php
$usersArray = User::findBy(['id_producer' => Producer::getId()])
->andWhere('CAST(FROM_UNIXTIME(user.created_at) AS date) > \''.date("Y-m-d", strtotime("-7 days")).'\'')
->orderBy('created_at DESC')
->all();
?>
<ul class="nav navbar-nav">
<?php
$pastDistributionsArray = Distribution::find()
->where(['<', 'distribution.date', date('Y-m-d')])
->andWhere([
'distribution.id_producer' => Producer::getId(),
'distribution.active' => 1
])
->orderBy('date DESC')
->limit(3)
->all();
$pastDistributionsArray = array_reverse($pastDistributionsArray) ;
$incomingDistributionsArray = Distribution::find()
->where(['>=', 'distribution.date', date('Y-m-d')])
->andWhere([
'distribution.id_producer' => Producer::getId(),
'distribution.active' => 1
])
->orderBy('date ASC')
->limit(20)
->all();
<?php

$usersArray = User::findBy(['id_producer' => GlobalParam::getCurrentProducerId()])
->andWhere('CAST(FROM_UNIXTIME(user.created_at) AS date) > \'' . date("Y-m-d", strtotime("-7 days")) . '\'')
->orderBy('created_at DESC')
->all();

?>

<ul class="nav navbar-nav">

<?php

$pastDistributionsArray = Distribution::find()
->where(['<', 'distribution.date', date('Y-m-d')])
->andWhere([
'distribution.id_producer' => GlobalParam::getCurrentProducerId(),
'distribution.active' => 1
])
->orderBy('date DESC')
->limit(3)
->all();

$pastDistributionsArray = array_reverse($pastDistributionsArray);

$incomingDistributionsArray = Distribution::find()
->where(['>=', 'distribution.date', date('Y-m-d')])
->andWhere([
'distribution.id_producer' => GlobalParam::getCurrentProducerId(),
'distribution.active' => 1
])
->orderBy('date ASC')
->limit(20)
->all();
?>

<li class="dropdown distributions-menu notifications-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-calendar"></i>
</a>
<ul class="dropdown-menu">
<?php if(count($pastDistributionsArray)): ?>
<li class="header">3 dernières distributions :</li>
<li>
<ul class="menu">
<?php foreach($pastDistributionsArray as $distribution): ?>

<?php if (count($pastDistributionsArray)): ?>
<li class="header">3 dernières distributions :</li>
<li>
<a href="<?= Yii::$app->urlManagerBackend->createUrl(['distribution/index','date' => $distribution->date]) ; ?>">
<h5><?= strftime('%A %d %B', strtotime($distribution->date)) ?></h5>
</a>
<ul class="menu">
<?php foreach ($pastDistributionsArray as $distribution): ?>
<li>
<a href="<?= Yii::$app->urlManagerBackend->createUrl(['distribution/index', 'date' => $distribution->date]); ?>">
<h5><?= strftime('%A %d %B', strtotime($distribution->date)) ?></h5>
</a>
</li>
<?php endforeach; ?>
</ul>
</li>
<?php endforeach; ?>
</ul>
</li>
<?php endif; ?>
<?php if(count($incomingDistributionsArray)): ?>
<li class="header">Prochaines distributions :</li>
<li>
<ul class="menu">
<?php foreach($incomingDistributionsArray as $distribution): ?>
<?php endif; ?>

<?php if (count($incomingDistributionsArray)): ?>
<li class="header">Prochaines distributions :</li>
<li>
<a href="<?= Yii::$app->urlManagerBackend->createUrl(['distribution/index','date' => $distribution->date]) ; ?>">
<h5><?= strftime('%A %d %B', strtotime($distribution->date)) ?></h5>
</a>
<ul class="menu">
<?php foreach ($incomingDistributionsArray as $distribution): ?>
<li>
<a href="<?= Yii::$app->urlManagerBackend->createUrl(['distribution/index', 'date' => $distribution->date]); ?>">
<h5><?= strftime('%A %d %B', strtotime($distribution->date)) ?></h5>
</a>
</li>
<?php endforeach; ?>
</ul>
</li>
<?php endforeach; ?>
</ul>
</li>
<?php else: ?>
<li class="header">
Aucune distribution prévue.<br />
<a class="btn btn-default" href="<?= Yii::$app->urlManagerBackend->createUrl(['distribution/index']) ; ?>">Gérer mes distributions</a>
</li>
<?php endif; ?>
<?php else: ?>
<li class="header">
Aucune distribution prévue.<br/>
<a class="btn btn-default"
href="<?= Yii::$app->urlManagerBackend->createUrl(['distribution/index']); ?>">Gérer
mes distributions</a>
</li>
<?php endif; ?>
</ul>
</li>
<li class="dropdown users-menu notifications-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-user-plus"></i>
<?php if(count($usersArray)): ?><span class="label label-success"><?= count($usersArray) ?></span>
<?php else: ?><span class="label label-warning">0</span><?php endif; ?>
<?php if (count($usersArray)): ?><span
class="label label-success"><?= count($usersArray) ?></span>
<?php else: ?><span class="label label-warning">0</span><?php endif; ?>
</a>
<ul class="dropdown-menu">
<?php if(count($usersArray)): ?>
<li class="header">Inscriptions des 7 derniers jours</li>
<li>
<ul class="menu">
<?php foreach($usersArray as $user): ?>
<?php if (count($usersArray)): ?>
<li class="header">Inscriptions des 7 derniers jours</li>
<li>
<a href="<?= Yii::$app->urlManagerBackend->createUrl(['user/update','id' => $user['user_id']]) ; ?>">
<h5><?= Html::encode($user['name'].' '.$user['lastname']) ; ?> <small><i class="fa fa-clock-o"></i> <?= date('d/m/Y à H:i',$user['created_at']); ?></small></h5>
</a>
<ul class="menu">
<?php foreach ($usersArray as $user): ?>
<li>
<a href="<?= Yii::$app->urlManagerBackend->createUrl(['user/update', 'id' => $user['user_id']]); ?>">
<h5><?= Html::encode((isset($user['name_legal_person']) && strlen($user['name_legal_person'])) ? $user['name_legal_person'] : $user['name'] . ' ' . $user['lastname']); ?>
<small>
<i class="fa fa-clock-o"></i> <?= date('d/m/Y à H:i', $user['created_at']); ?>
</small>
</h5>
</a>
</li>
<?php endforeach; ?>
</ul>
</li>
<?php endforeach; ?>
</ul>
</li>
<?php else: ?>
<li class="header">Aucun nouvel inscrit ces 7 derniers jours.</li>
<?php endif; ?>
<?php else: ?>
<li class="header">Aucun nouvel inscrit ces 7 derniers jours.</li>
<?php endif; ?>
</ul>
</li>
<?php
$usersNegativeCreditArray = User::findBy(['id_producer' => Producer::getId()])
->andWhere('user_producer.credit < 0')
->orderBy('lastname, name ASC')
->all();

?>
<?php

$usersNegativeCreditArray = User::findBy(['id_producer' => GlobalParam::getCurrentProducerId()])
->andWhere('user_producer.credit < 0')
->orderBy('lastname, name ASC')
->all();

?>

<li class="dropdown users-negative-credit-menu notifications-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-euro"></i>
<?php if(count($usersNegativeCreditArray)): ?><span class="label label-warning"><?= count($usersNegativeCreditArray) ?></span>
<?php else: ?><span class="label label-success">0</span><?php endif; ?>
<?php if (count($usersNegativeCreditArray)): ?><span
class="label label-warning"><?= count($usersNegativeCreditArray) ?></span>
<?php else: ?><span class="label label-success">0</span><?php endif; ?>
</a>
<ul class="dropdown-menu">
<?php if(count($usersNegativeCreditArray)): ?>
<li class="header">Utilisateurs au crédit négatif</li>
<li>
<ul class="menu">
<?php foreach($usersNegativeCreditArray as $user): ?>
<?php if (count($usersNegativeCreditArray)): ?>
<li class="header">Utilisateurs au crédit négatif</li>
<li>
<a href="<?= Yii::$app->urlManagerBackend->createUrl(['user/credit','id' => $user['user_id']]) ; ?>">
<h5><?= Html::encode($user['name'].' '.$user['lastname']) ; ?> <small><i class="fa fa-euro"></i> <?= Price::format($user['credit']); ?></small></h5>
</a>
<ul class="menu">
<?php foreach ($usersNegativeCreditArray as $user): ?>
<li>
<a href="<?= Yii::$app->urlManagerBackend->createUrl(['user/credit', 'id' => $user['user_id']]); ?>">
<h5><?= Html::encode($user['name'] . ' ' . $user['lastname']); ?>
<small>
<i class="fa fa-euro"></i> <?= Price::format($user['credit']); ?>
</small>
</h5>
</a>
</li>
<?php endforeach; ?>
</ul>
</li>
<?php endforeach; ?>
</ul>
</li>
<?php else: ?>
<li class="header">Aucun de vos utilisateurs n'a de crédit négatif.</li>
<?php endif; ?>
</ul>
</li>
<?php if (User::isCurrentProducer() || User::isCurrentAdmin()): ?>
<li class="dropdown producer-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<?php if($producer->active): ?>
<i class="fa fa-home"></i>
<?php else: ?>
<span class="label label-danger">Hors-ligne</span>
<li class="header">Aucun de vos utilisateurs n'a de crédit négatif.</li>
<?php endif; ?>
<span><?= Html::encode(Yii::$app->user->identity->getNameProducer()); ?></span>
<i class="fa fa-caret-down"></i>
</a>
<ul class="dropdown-menu">
<?php if(User::isCurrentAdmin()): ?>
<li>
<a href="<?= Yii::$app->urlManagerProducer->createAbsoluteUrl(['site/index','slug_producer' => Producer::getCurrent()->slug]); ?>">
<i class="fa fa-th-large"></i>
<span class="hidden-xs">Espace du producteur</span>
</a>
</li>
<li class="header">&nbsp;<strong>Autres producteurs</strong></li>
<?php $producersArray = Producer::find()->orderBy('name ASC')->all(); ?>
<?php foreach($producersArray as $producer): ?>
<li><a href="<?= Yii::$app->urlManagerBackend->createUrl(['site/change-producer', 'id' => $producer->id]); ?>"><?= Html::encode($producer->name) ?></a></li>
<?php endforeach; ?>
<?php else: ?>
<li>
<a href="<?= Yii::$app->urlManagerProducer->createAbsoluteUrl(['site/index','slug_producer' => Producer::getCurrent()->slug]); ?>">
<i class="fa fa-th-large"></i>
<span class="hidden-xs">Mon espace</span>
</a>
</li>
<?php endif; ?>
</ul>
</li>
<?php endif; ?>
</ul>

</li>

<?php if (User::isCurrentProducer() || User::isCurrentAdmin()): ?>
<li class="dropdown producer-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">

<?php if ($producer->active): ?>
<i class="fa fa-home"></i>
<?php else: ?>
<span class="label label-danger">Hors-ligne</span>
<?php endif; ?>
<span><?= Html::encode(Yii::$app->user->identity->getNameProducer()); ?></span>
<i class="fa fa-caret-down"></i>
</a>

<ul class="dropdown-menu">
<?php if (User::isCurrentAdmin()): ?>
<li>
<a href="<?= Yii::$app->urlManagerProducer->createAbsoluteUrl(['site/index', 'slug_producer' => GlobalParam::getCurrentProducer()->slug]); ?>">
<i class="fa fa-th-large"></i>
<span class="hidden-xs">Espace du producteur</span>
</a>
</li>
<li class="header">&nbsp;<strong>Autres producteurs</strong></li>
<?php $producersArray = Producer::find()->orderBy('name ASC')->all(); ?>
<?php foreach ($producersArray as $producer): ?>
<li>
<a href="<?= Yii::$app->urlManagerBackend->createUrl(['site/change-producer', 'id' => $producer->id]); ?>"><?= Html::encode($producer->name) ?></a>
</li>
<?php endforeach; ?>
<?php else: ?>
<li>
<a href="<?= Yii::$app->urlManagerProducer->createAbsoluteUrl(['site/index', 'slug_producer' => GlobalParam::getCurrentProducer()->slug]); ?>">
<i class="fa fa-th-large"></i>
<span class="hidden-xs">Mon espace</span>
</a>
</li>
<?php endif; ?>
</ul>
</li>
<?php endif; ?>

<li class="dropdown user user-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-user"></i>
<span class="hidden-xs"><?= Html::encode(User::getCurrent()->name.' '.User::getCurrent()->lastname) ; ?></span>
<span class="hidden-xs"><?= Html::encode(User::getCurrent()->name . ' ' . User::getCurrent()->lastname); ?></span>
<i class="fa fa-caret-down"></i>
</a>
<ul class="dropdown-menu">
<li><a href="<?= Yii::$app->urlManagerFrontend->createAbsoluteUrl(['user/update']); ?>"><i class="fa fa-user"></i> Profil</a></li>
<li><a href="<?= Yii::$app->urlManagerBackend->createUrl(['site/logout']); ?>"><i class="fa fa-sign-out"></i> Déconnexion</a></li>
<li><a href="<?= Yii::$app->urlManagerFrontend->createAbsoluteUrl(['user/update']); ?>"><i
class="fa fa-user"></i> Profil</a></li>
<li><a href="<?= Yii::$app->urlManagerBackend->createUrl(['site/logout']); ?>"><i
class="fa fa-sign-out"></i> Déconnexion</a></li>
</ul>
</li>

<li class="link-control-sidebar">
<a href="#" data-toggle="control-sidebar"><i class="fa fa-gears"></i></a>
</li>
</ul>
</div>
</nav>

+ 11
- 0
backend/views/layouts/left.php Целия файл

@@ -64,12 +64,23 @@ termes.
['label' => 'Produits','icon' => 'table','url' => ['/stats/products'], 'visible' => User::isCurrentProducer()],
],
],
[
'label' => 'Documents',
'icon' => 'clone',
'url' => '#',
'items' => [
['label' => 'Devis','icon' => 'sticky-note-o','url' => ['/quotation/index'], 'visible' => User::isCurrentProducer()],
['label' => 'Bons de livraison','icon' => 'sticky-note-o','url' => ['/delivery-note/index'], 'visible' => User::isCurrentProducer()],
['label' => 'Factures','icon' => 'sticky-note-o','url' => ['/invoice/index'], 'visible' => User::isCurrentProducer()],
],
],
['label' => 'Développement','icon' => 'wrench','url' => ['/development/index'], 'visible' => User::isCurrentProducer(), 'active' => Yii::$app->controller->id == 'development'],
['label' => 'Mon abonnement','icon' => 'euro','url' => ['/producer/billing'], 'visible' => User::isCurrentProducer()],
['label' => 'Accès','icon' => 'lock','url' => ['/access/index'], 'visible' => User::isCurrentProducer()],
['label' => 'Administration', 'options' => ['class' => 'header'], 'visible' => User::isCurrentAdmin()],
['label' => 'Producteurs','icon' => 'th-list','url' => ['/producer-admin/index'], 'visible' => User::isCurrentAdmin()],
['label' => 'Taxes','icon' => 'eur','url' => ['/tax-rate-admin/index'], 'visible' => User::isCurrentAdmin()],
['label' => 'Communiquer','icon' => 'bullhorn','url' => ['/communicate-admin/index'], 'visible' => User::isCurrentAdmin()],
['label' => 'Outils', 'options' => ['class' => 'header'], 'visible' => User::isCurrentAdmin()],

+ 215
- 207
backend/views/layouts/main-old.php Целия файл

@@ -1,40 +1,40 @@
<?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.
*/
/**
* 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.
*/

use yii\helpers\Html;
use yii\bootstrap\Nav;
@@ -45,6 +45,7 @@ use common\models\User;
use yii\widgets\ActiveForm;
use yii\helpers\ArrayHelper;
use common\helpers\Url;
use common\helpers\GlobalParam;

/* @var $this \yii\web\View */
/* @var $content string */
@@ -52,239 +53,246 @@ use common\helpers\Url;
\common\assets\CommonAsset::register($this);
\backend\assets\AppAsset::register($this);

$producer = null ;
if(!Yii::$app->user->isGuest) {
$producer = Producer::findOne(Producer::getId()) ;
$producer = null;
if (!Yii::$app->user->isGuest) {
$producer = Producer::findOne(GlobalParam::getCurrentProducerId());
}

?>
<?php $this->beginPage() ?>
<!DOCTYPE html>
<html lang="<?= Yii::$app->language ?>">
<head>
<meta charset="<?= Yii::$app->charset ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="baseurl" content="<?= Yii::$app->urlManagerBackend->baseUrl ; ?>">
<meta name="baseurl-absolute" content="<?= Yii::$app->urlManagerBackend->getHostInfo().Yii::$app->urlManagerBackend->baseUrl; ?>">
<link rel="icon" type="image/png" href="<?php echo Yii::$app->urlManager->getBaseUrl(); ?>/img/favicon3.png" />
<head>
<meta charset="<?= Yii::$app->charset ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="baseurl" content="<?= Yii::$app->urlManagerBackend->baseUrl; ?>">
<meta name="baseurl-absolute"
content="<?= Yii::$app->urlManagerBackend->getHostInfo() . Yii::$app->urlManagerBackend->baseUrl; ?>">
<link rel="icon" type="image/png" href="<?php echo Yii::$app->urlManager->getBaseUrl(); ?>/img/favicon3.png"/>
<?= Html::csrfMetaTags() ?>
<title><?= Html::encode($this->title) ?> - distrib</title>
<?php $this->head() ?>
</head>
<body>
<?php $this->beginBody() ?>
<div class="wrap">
<?php
NavBar::begin([
<title><?= Html::encode($this->title) ?> - distrib</title>
<?php $this->head() ?>
</head>
<body>
<?php $this->beginBody() ?>
<div class="wrap">
<?php
NavBar::begin([
'brandLabel' => '<img class="logo" src="' . Yii::$app->urlManager->getBaseUrl() . '/img/laboulange3.png" />',
'brandUrl' => Yii::$app->homeUrl,
'innerContainerOptions' => ['class' => 'container-fluid'],
'options' => [
'class' => 'navbar-inverse navbar-fixed-top nav-header',
'class' => 'navbar-inverse navbar-fixed-top nav-header',
],
]);
]);

$menuItems = [
$menuItems = [
[
'label' => '<span class="glyphicon glyphicon-home"></span> Tableau de bord',
'url' => ['/site/index'],
'visible' => !Yii::$app->user->isGuest
'label' => '<span class="glyphicon glyphicon-home"></span> Tableau de bord',
'url' => ['/site/index'],
'visible' => !Yii::$app->user->isGuest
],
[
'label' => '<span class="glyphicon glyphicon-calendar"></span> Commandes',
'url' => ['/order/index'],
'visible' => !Yii::$app->user->isGuest,
'items' => [
[
'label' => '<span class="glyphicon glyphicon-calendar"></span> Toutes les commandes',
'url' => ['/order/index'],
'visible' => !Yii::$app->user->isGuest
],
[
'label' => '<span class="glyphicon glyphicon-repeat"></span> Abonnements',
'url' => ['/subscription/index'],
'visible' => !Yii::$app->user->isGuest
],
]
'label' => '<span class="glyphicon glyphicon-calendar"></span> Commandes',
'url' => ['/order/index'],
'visible' => !Yii::$app->user->isGuest,
'items' => [
[
'label' => '<span class="glyphicon glyphicon-calendar"></span> Toutes les commandes',
'url' => ['/order/index'],
'visible' => !Yii::$app->user->isGuest
],
[
'label' => '<span class="glyphicon glyphicon-repeat"></span> Abonnements',
'url' => ['/subscription/index'],
'visible' => !Yii::$app->user->isGuest
],
]
],
[
'label' => '<span class="glyphicon glyphicon-grain"></span> Produits',
'url' => ['/product/index'],
'visible' => !Yii::$app->user->isGuest
'label' => '<span class="glyphicon glyphicon-grain"></span> Produits',
'url' => ['/product/index'],
'visible' => !Yii::$app->user->isGuest
],
[
'label' => '<span class="glyphicon glyphicon-map-marker"></span> Points de vente',
'url' => ['/point-sale/index'],
'visible' => !Yii::$app->user->isGuest
'label' => '<span class="glyphicon glyphicon-map-marker"></span> Points de vente',
'url' => ['/point-sale/index'],
'visible' => !Yii::$app->user->isGuest
],
[
'label' => '<span class="glyphicon glyphicon-user"></span> Clients',
'url' => ['/user/index'],
'visible' => !Yii::$app->user->isGuest
'label' => '<span class="glyphicon glyphicon-user"></span> Clients',
'url' => ['/user/index'],
'visible' => !Yii::$app->user->isGuest
],
[
'label' => '<span class="glyphicon glyphicon-plus"></span>',
'url' => ['/producer/update'],
'visible' => !Yii::$app->user->isGuest,
'items' => [
[
'label' => '<span class="glyphicon glyphicon-cog"></span> Paramètres',
'url' => ['/producer/update'],
'visible' => !Yii::$app->user->isGuest
],
[
'label' => '<span class="glyphicon glyphicon-bullhorn"></span> Communiquer',
'url' => ['/communicate/index'],
'visible' => !Yii::$app->user->isGuest
],
[
'label' => '<span class="glyphicon glyphicon-euro"></span> Mon abonnement',
'url' => ['/producer/billing'],
'visible' => !Yii::$app->user->isGuest,
],
[
'label' => '<span class="glyphicon glyphicon-stats"></span> Statistiques',
'url' => ['/stats/index'],
'visible' => !Yii::$app->user->isGuest,
],
[
'label' => '<span class="glyphicon glyphicon-stats"></span> Statistiques produits',
'url' => ['/stats/products'],
'visible' => !Yii::$app->user->isGuest,
],
[
'label' => '<span class="glyphicon glyphicon-wrench"></span> Développement',
'url' => ['/development/index'],
'visible' => !Yii::$app->user->isGuest
'label' => '<span class="glyphicon glyphicon-plus"></span>',
'url' => ['/producer/update'],
'visible' => !Yii::$app->user->isGuest,
'items' => [
[
'label' => '<span class="glyphicon glyphicon-cog"></span> Paramètres',
'url' => ['/producer/update'],
'visible' => !Yii::$app->user->isGuest
],
[
'label' => '<span class="glyphicon glyphicon-bullhorn"></span> Communiquer',
'url' => ['/communicate/index'],
'visible' => !Yii::$app->user->isGuest
],
[
'label' => '<span class="glyphicon glyphicon-euro"></span> Mon abonnement',
'url' => ['/producer/billing'],
'visible' => !Yii::$app->user->isGuest,
],
[
'label' => '<span class="glyphicon glyphicon-stats"></span> Statistiques',
'url' => ['/stats/index'],
'visible' => !Yii::$app->user->isGuest,
],
[
'label' => '<span class="glyphicon glyphicon-stats"></span> Statistiques produits',
'url' => ['/stats/products'],
'visible' => !Yii::$app->user->isGuest,
],
[
'label' => '<span class="glyphicon glyphicon-wrench"></span> Développement',
'url' => ['/development/index'],
'visible' => !Yii::$app->user->isGuest
],
],
],
]
];
];

if (Yii::$app->user->isGuest) {
if (Yii::$app->user->isGuest) {
$menuItems[] = ['label' => 'Connexion', 'url' => ['/site/login']];
} else {
} else {

if (Yii::$app->user->identity->status == USER::STATUS_ADMIN) {
$menuItems[] = [
'label' => '<span class="glyphicon glyphicon-asterisk"></span>',
'url' => '#',
'items' => [
[
'label' => '<span class="glyphicon glyphicon-th-list"></span> Producteurs',
'url' => ['producer-admin/index'],
'visible' => !Yii::$app->user->isGuest,
],
[
'label' => '<span class="glyphicon glyphicon-euro"></span> Facturation',
'url' => ['producer-admin/billing'],
'visible' => false,
],
]
];
$menuItems[] = [
'label' => '<span class="glyphicon glyphicon-asterisk"></span>',
'url' => '#',
'items' => [
[
'label' => '<span class="glyphicon glyphicon-th-list"></span> Producteurs',
'url' => ['producer-admin/index'],
'visible' => !Yii::$app->user->isGuest,
],
[
'label' => '<span class="glyphicon glyphicon-euro"></span> Facturation',
'url' => ['producer-admin/billing'],
'visible' => false,
],
]
];
}

$menuItems[] = [
'label' => '<span class="glyphicon glyphicon-off"></span>',
'url' => ['/site/logout'],
'linkOptions' => ['data-method' => 'post', 'title' => 'Déconnexion']
'label' => '<span class="glyphicon glyphicon-off"></span>',
'url' => ['/site/logout'],
'linkOptions' => ['data-method' => 'post', 'title' => 'Déconnexion']
];

$menuItems[] = [
'label' => '<span class="retour-site">Retour sur le site</span>',
'url' => Yii::$app->urlManagerProducer->createAbsoluteUrl(['site/index','slug_producer' => $producer->slug]),
'label' => '<span class="retour-site">Retour sur le site</span>',
'url' => Yii::$app->urlManagerProducer->createAbsoluteUrl(['site/index', 'slug_producer' => $producer->slug]),
];
}
echo Nav::widget([
}
echo Nav::widget([
'options' => ['class' => 'navbar-nav navbar-right'],
'items' => $menuItems,
'encodeLabels' => false
]);
NavBar::end();
?>
]);
NavBar::end();
?>

<div class="container-fluid container-body">
<?php if (YII_ENV == 'dev' || YII_ENV == 'demo'): ?>
<div id="env-dev"><?php if (YII_ENV == 'dev'): ?>Dév.<?php elseif (YII_ENV == 'demo'): ?>Démo<?php endif; ?></div>
<?php endif; ?>
<?php if (!Yii::$app->user->isGuest): ?>
<div class="name-producer">
<div class="container-fluid container-body">
<?php if (YII_ENV == 'dev' || YII_ENV == 'demo'): ?>
<div id="env-dev"><?php if (YII_ENV == 'dev'): ?>Dév.<?php elseif (YII_ENV == 'demo'): ?>Démo<?php endif; ?></div>
<?php endif; ?>
<?php if (!Yii::$app->user->isGuest): ?>
<div class="name-producer">
<?php if (User::getCurrentStatus() == User::STATUS_PRODUCER): ?>
<span><?= Html::encode(Yii::$app->user->identity->getNameProducer()); ?></span>
<?php elseif (User::getCurrentStatus() == User::STATUS_ADMIN): ?>
<?php $form = ActiveForm::begin(['id' => 'select-producer']); ?>
<?=
Html::dropDownList('select_producer', Producer::getId(), ArrayHelper::map(Producer::find()->orderBy('name ASC')->all(), 'id', function($model, $defaultValue) {
return $model->name;
}));
?>
<?php ActiveForm::end(); ?>
<?php $form = ActiveForm::begin(['id' => 'select-producer']); ?>
<?=
Html::dropDownList('select_producer', GlobalParam::getCurrentProducerId(), ArrayHelper::map(Producer::find()->orderBy('name ASC')->all(), 'id', function ($model, $defaultValue) {
return $model->name;
}));
?>
<?php ActiveForm::end(); ?>
<?php endif; ?>

<?php
$producer = Producer::findOne(Producer::getId());
$producer = Producer::findOne(GlobalParam::getCurrentProducerId());
if (!$producer->active):
?>
<span class="label label-danger" data-toggle="tooltip" data-placement="bottom" data-original-title="Activez votre établissement quand vous le souhaitez afin de la rendre visible à vos clients.">
?>
<span class="label label-danger" data-toggle="tooltip" data-placement="bottom"
data-original-title="Activez votre établissement quand vous le souhaitez afin de la rendre visible à vos clients.">
<?= Html::a('Hors-ligne', ['producer/update']); ?>
</span>
<?php endif; ?>

<div class="clr"></div>
</div>
<?php endif; ?>
<div class="clr"></div>
</div>
<?php endif; ?>

<?php if (YII_ENV == 'demo'): ?>
<div id="block-demo">
<div class="container-fluid">
<span class="glyphicon glyphicon-eye-open"></span> <strong>Espace de démonstration</strong> :
Testez la plateforme sans avoir à vous inscrire. Les données sont réinitialisées quotidiennement &bull; <?= Html::a('Retour', Url::env('prod', 'frontend')) ?>
</div>
<?php if (YII_ENV == 'demo'): ?>
<div id="block-demo">
<div class="container-fluid">
<span class="glyphicon glyphicon-eye-open"></span> <strong>Espace de démonstration</strong> :
Testez la plateforme sans avoir à vous inscrire. Les données sont réinitialisées quotidiennement
&bull; <?= Html::a('Retour', Url::env('prod', 'frontend')) ?>
</div>
<?php endif; ?>
</div>
<?php endif; ?>

<?=
Breadcrumbs::widget([
<?=
Breadcrumbs::widget([
'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
])
?>
<?= $content ?>
</div>
</div>
])
?>
<?= $content ?>
</div>
</div>

<div id="alerts-fixed"></div>
<div id="alerts-fixed"></div>

<footer class="footer">
<div class="container-fluid">
<p class="pull-left">
<a href="<?php echo Url::frontend('site/contact'); ?>">Contact</a> &bull;
<a href="<?php echo Url::frontend('site/mentions'); ?>">Mentions légales</a> &bull;
<a href="<?php echo Url::frontend('site/cgv'); ?>">CGS</a>
<a id="code-source" href="https://framagit.org/guillaume-bourgeois/laboiteapain">Code source <img src="<?php echo Yii::$app->urlManager->getBaseUrl(); ?>/img/logo-framagit.png" alt="Hébergé par Framasoft" /> <img src="<?php echo Yii::$app->urlManager->getBaseUrl(); ?>/img/logo-gitlab.png" alt="Propulsé par Gitlab" /></a>
</p>
<p class="pull-right"><?= Yii::powered() ?></p>
</div>
</footer>
<footer class="footer">
<div class="container-fluid">
<p class="pull-left">
<a href="<?php echo Url::frontend('site/contact'); ?>">Contact</a> &bull;
<a href="<?php echo Url::frontend('site/mentions'); ?>">Mentions légales</a> &bull;
<a href="<?php echo Url::frontend('site/cgv'); ?>">CGS</a>
<a id="code-source" href="https://framagit.org/guillaume-bourgeois/laboiteapain">Code source <img
src="<?php echo Yii::$app->urlManager->getBaseUrl(); ?>/img/logo-framagit.png"
alt="Hébergé par Framasoft"/> <img
src="<?php echo Yii::$app->urlManager->getBaseUrl(); ?>/img/logo-gitlab.png"
alt="Propulsé par Gitlab"/></a>
</p>
<p class="pull-right"><?= Yii::powered() ?></p>
</div>
</footer>

<?php $this->endBody() ?>

<!-- analytics -->
<script>
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
<!-- analytics -->
<script>
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');

ga('create', 'UA-86917043-1', 'auto');
ga('send', 'pageview');
</script>
</body>
ga('create', 'UA-86917043-1', 'auto');
ga('send', 'pageview');
</script>
</body>
</html>
<?php $this->endPage() ?>

+ 2
- 1
backend/views/layouts/main.php Целия файл

@@ -56,6 +56,7 @@ if (Yii::$app->controller->action->id === 'login') {
\dmstr\web\AdminLteAsset::register($this);
\common\assets\CommonAsset::register($this);
\backend\assets\AppAsset::register($this);
\backend\assets\VuejsAlertsAsset::register($this);

$directoryAsset = Yii::$app->assetManager->getPublishedUrl('@vendor/almasaeed2010/adminlte/dist');
?>
@@ -96,7 +97,7 @@ if (Yii::$app->controller->action->id === 'login') {

<?php $this->endBody() ?>
<?= $this->render('@common/views/_analytics.php'); ?>
</body>
</html>
<?php $this->endPage() ?>

+ 131
- 115
backend/views/point-sale/_form.php Целия файл

@@ -1,45 +1,45 @@
<?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.
*/
/**
* 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.
*/

use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\helpers\ArrayHelper ;
use common\models\Producer ;
use yii\helpers\ArrayHelper;
use common\models\Producer;

/* @var $this yii\web\View */
/* @var $model backend\models\PointVente */
@@ -48,88 +48,104 @@ use common\models\Producer ;

<div class="point-sale-form">

<?php $form = ActiveForm::begin(); ?>
<?php $form = ActiveForm::begin(); ?>

<div class="col-md-8">

<?= $form->field($model, 'name')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'locality')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'address')->textarea(['rows' => 6]) ?>
<?= $form->field($model, 'id_user', [
'template' => '{label} <a href="' . Yii::$app->urlManager->createUrl(['user/create']) . '" class="btn btn-xs btn-default">Nouvel utilisateur <span class="glyphicon glyphicon-plus"></span></a><div>{input}</div>{hint}',
])
->dropDownList(
ArrayHelper::map(User::findBy()->all(), 'user_id', function ($model) {
if(strlen($model['name_legal_person'])) {
return $model['name_legal_person'] ;
}
else {
return $model['lastname'] . ' ' . $model['name'];
}
}),
[
'prompt' => '--',
]
)->hint('Utilisé lors de la facturation'); ?>

<?php
$addHintCredit = '';
if (!Producer::getConfig('credit')):
$addHintCredit = '<br /><strong>Attention, le système de Crédit est désactivé au niveau des ' . Html::a('paramètres globaux', ['producer/update']) . '.</strong>';
endif;

<div class="col-md-8">
<?= $form->field($model, 'name')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'locality')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'address')->textarea(['rows' => 6]) ?>

<?php
$addHintCredit = '' ;
if(!Producer::getConfig('credit')):
$addHintCredit = '<br /><strong>Attention, le système de Crédit est désactivé au niveau des '.Html::a('paramètres globaux',['producer/update']).'.</strong>' ;
endif;
echo $form->field($model, 'credit')
->checkbox()
->hint('Cochez cette case si le client peut régler ses commandes via son compte <strong>Crédit</strong> pour ce point de vente.'
.$addHintCredit);
?>
<?= $form->field($model, 'credit_functioning')
->dropDownList([
'' => 'Paramètres globaux ('.Producer::$creditFunctioningArray[Producer::getConfig('credit_functioning')].')',
Producer::CREDIT_FUNCTIONING_OPTIONAL => Producer::$creditFunctioningArray[Producer::CREDIT_FUNCTIONING_OPTIONAL],
Producer::CREDIT_FUNCTIONING_MANDATORY => Producer::$creditFunctioningArray[Producer::CREDIT_FUNCTIONING_MANDATORY],
Producer::CREDIT_FUNCTIONING_USER => Producer::$creditFunctioningArray[Producer::CREDIT_FUNCTIONING_USER],
], [])->hint(Producer::HINT_CREDIT_FUNCTIONING) ; ?>

<div id="delivery-days">
<h2>Jours de livraison</h2>
<?= $form->field($model, 'delivery_monday')->checkbox() ?>
<?= $form->field($model, 'delivery_tuesday')->checkbox() ?>
<?= $form->field($model, 'delivery_wednesday')->checkbox() ?>
<?= $form->field($model, 'delivery_thursday')->checkbox() ?>
<?= $form->field($model, 'delivery_friday')->checkbox() ?>
<?= $form->field($model, 'delivery_saturday')->checkbox() ?>
<?= $form->field($model, 'delivery_sunday')->checkbox() ?>
->checkbox()
->hint('Cochez cette case si le client peut régler ses commandes via son compte <strong>Crédit</strong> pour ce point de vente.'
. $addHintCredit);
?>

<?= $form->field($model, 'credit_functioning')
->dropDownList([
'' => 'Paramètres globaux (' . Producer::$creditFunctioningArray[Producer::getConfig('credit_functioning')] . ')',
Producer::CREDIT_FUNCTIONING_OPTIONAL => Producer::$creditFunctioningArray[Producer::CREDIT_FUNCTIONING_OPTIONAL],
Producer::CREDIT_FUNCTIONING_MANDATORY => Producer::$creditFunctioningArray[Producer::CREDIT_FUNCTIONING_MANDATORY],
Producer::CREDIT_FUNCTIONING_USER => Producer::$creditFunctioningArray[Producer::CREDIT_FUNCTIONING_USER],
], [])->hint(Producer::HINT_CREDIT_FUNCTIONING); ?>


<div id="delivery-days">
<h2>Jours de livraison</h2>
<?= $form->field($model, 'delivery_monday')->checkbox() ?>
<?= $form->field($model, 'delivery_tuesday')->checkbox() ?>
<?= $form->field($model, 'delivery_wednesday')->checkbox() ?>
<?= $form->field($model, 'delivery_thursday')->checkbox() ?>
<?= $form->field($model, 'delivery_friday')->checkbox() ?>
<?= $form->field($model, 'delivery_saturday')->checkbox() ?>
<?= $form->field($model, 'delivery_sunday')->checkbox() ?>
</div>
<div class="clr"></div>

<h2>Informations</h2>
<?= $form->field($model, 'infos_monday')->textarea(['rows' => 3]) ?>
<?= $form->field($model, 'infos_tuesday')->textarea(['rows' => 3]) ?>
<?= $form->field($model, 'infos_wednesday')->textarea(['rows' => 3]) ?>
<?= $form->field($model, 'infos_thursday')->textarea(['rows' => 3]) ?>
<?= $form->field($model, 'infos_friday')->textarea(['rows' => 3]) ?>
<?= $form->field($model, 'infos_saturday')->textarea(['rows' => 3]) ?>
<?= $form->field($model, 'infos_sunday')->textarea(['rows' => 3]) ?>
</div>
<div class="clr"></div>
<h2>Informations</h2>
<?= $form->field($model, 'infos_monday')->textarea(['rows' => 3]) ?>
<?= $form->field($model, 'infos_tuesday')->textarea(['rows' => 3]) ?>
<?= $form->field($model, 'infos_wednesday')->textarea(['rows' => 3]) ?>
<?= $form->field($model, 'infos_thursday')->textarea(['rows' => 3]) ?>
<?= $form->field($model, 'infos_friday')->textarea(['rows' => 3]) ?>
<?= $form->field($model, 'infos_saturday')->textarea(['rows' => 3]) ?>
<?= $form->field($model, 'infos_sunday')->textarea(['rows' => 3]) ?>
<div class="col-md-4">

<?= $form->field($model, 'code')
->label('Code d\'accès')
->hint('Renseignez ce champs si vous souhaitez protéger ce point de vente par un code.')
?>


<?= $form->field($model, 'restricted_access')
->checkbox()
->hint('Cochez cette case si seulement un groupe restreint d\'utilisateurs peuvent accéder à ce point de vente.<br />'
. 'Dans le cas des boîtes à pain, il vous est possible de spécifier un commentaire pour chaque utilisateur sélectionné afin de lui renseigner son numéro de boîte ou son code.') ?>
<div id="users">
<?= Html::activeCheckboxList($model, 'users', ArrayHelper::map($users, 'user_id', function ($model_user, $defaultValue) use ($model) {
return Html::encode($model_user['lastname'] . ' ' . $model_user['name']) . '<br />'
. Html::activeTextInput(
$model,
'users_comment[' . $model_user['user_id'] . ']',
[
'class' => 'form-control commentaire',
'placeholder' => 'Commentaire',
'value' => (isset($model->users_comment[$model_user['user_id']])) ? Html::encode($model->users_comment[$model_user['user_id']]) : ''
]);
}), ['encode' => false, 'class' => '']) ?>
</div>
</div>
<div class="col-md-4">
<?= $form->field($model, 'code')
->label('Code d\'accès')
->hint('Renseignez ce champs si vous souhaitez protéger ce point de vente par un code.')
?>
<?= $form->field($model, 'restricted_access')
->checkbox()
->hint('Cochez cette case si seulement un groupe restreint d\'utilisateurs peuvent accéder à ce point de vente.<br />'
. 'Dans le cas des boîtes à pain, il vous est possible de spécifier un commentaire pour chaque utilisateur sélectionné afin de lui renseigner son numéro de boîte ou son code.') ?>
<div id="users">
<?= Html::activeCheckboxList($model, 'users', ArrayHelper::map($users, 'user_id', function($model_user, $defaultValue) use ($model) {
return Html::encode($model_user['lastname'].' '.$model_user['name']).'<br />'
.Html::activeTextInput(
$model,
'users_comment['.$model_user['user_id'].']',
[
'class' => 'form-control commentaire',
'placeholder' => 'Commentaire',
'value' => (isset($model->users_comment[$model_user['user_id']])) ? Html::encode($model->users_comment[$model_user['user_id']]) : ''
]);
} ), ['encode' => false, 'class' => '']) ?>
<div class="clr"></div>

<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Ajouter' : 'Modifier', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
</div>
<div class="clr"></div>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Ajouter' : 'Modifier', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>

<?php ActiveForm::end(); ?>

<?php ActiveForm::end(); ?>

</div>

+ 29
- 1
backend/views/producer/update.php Целия файл

@@ -76,8 +76,10 @@ $this->addBreadcrumb($this->getTitle()) ;
<?= $form->field($model, 'name') ?>
<?= $form->field($model, 'type') ?>
<?= $form->field($model, 'description')
->textarea(['rows' => 6])
->textarea(['rows' => 4])
->hint('Affiché sur la page d\'accueil') ?>
<?= $form->field($model, 'address')
->textarea(['rows' => 4]) ?>
<?= $form->field($model, 'postcode') ?>
<?= $form->field($model, 'city') ?>

@@ -245,6 +247,32 @@ $this->addBreadcrumb($this->getTitle()) ;
<?= $form->field($model, 'tiller_restaurant_token') ; ?>
</div>
</div>
<div v-show="currentSection == 'facturation'" class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Facturation</h3>
</div>
<div class="panel-body">
<?= $form->field($model, 'id_tax_rate_default')
->dropDownList(ArrayHelper::map(TaxRate::find()->all(), 'id', function($model) { return $model->name; }))
->label('TVA à appliquer par défaut'); ?>
<?= $form->field($model, 'document_quotation_prefix') ; ?>
<?= $form->field($model, 'document_quotation_first_reference') ; ?>
<?= $form->field($model, 'document_quotation_duration') ; ?>
<?= $form->field($model, 'document_invoice_prefix') ; ?>
<?= $form->field($model, 'document_invoice_first_reference') ; ?>
<?= $form->field($model, 'document_delivery_note_prefix') ; ?>
<?= $form->field($model, 'document_delivery_note_first_reference') ; ?>
<?= $form->field($model, 'document_infos_bottom')
->textarea(['rows' => 15]) ?>
<?= $form->field($model, 'document_infos_quotation')
->textarea(['rows' => 15]) ?>
<?= $form->field($model, 'document_infos_invoice')
->textarea(['rows' => 15]) ?>
<?= $form->field($model, 'document_infos_delivery_note')
->textarea(['rows' => 15]) ?>
</div>
</div>
<div class="form-group">

+ 125
- 81
backend/views/product/_form.php Целия файл

@@ -1,45 +1,48 @@
<?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.
*/
/**
* 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.
*/

use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use common\models\Product;
use yii\helpers\ArrayHelper ;
use yii\helpers\ArrayHelper;
use common\models\TaxRate;
use common\models\Producer;
use common\helpers\GlobalParam;

/* @var $this yii\web\View */
/* @var $model app\models\Produit */
@@ -48,69 +51,110 @@ use yii\helpers\ArrayHelper ;

<div class="product-form">

<?php $form = ActiveForm::begin([
'enableClientValidation' => false,
'options' => ['enctype' => 'multipart/form-data']
]); ?>
<?php $form = ActiveForm::begin([
'enableClientValidation' => false,
'options' => ['enctype' => 'multipart/form-data']
]); ?>

<div>
<div class="col-md-8">
<?= $form->field($model, 'active')->radioList([1 => 'Oui',0 => 'Non' ]) ?>
<?= $form->field($model, 'name')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'description')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'recipe')->textarea()->label('Description longue') ?>
<?= $form->field($model, 'unit')
->dropDownList(ArrayHelper::map(Product::$unitsArray, 'unit', 'wording'))
->label('Unité (pièce, poids ou volume)'); ?>
<?= $form->field($model, 'price',[
'inputTemplate' => '<div class="input-group">{input}<span class="input-group-addon"><span class="glyphicon glyphicon-euro"></span></span></div>',
]) ?>
<?= $form->field($model, 'step')->textInput()->hint('Définit ce qui est ajouté ou enlevé lors des changements de quantité.') ?>
<?= $form->field($model, 'weight')->textInput()->label('Poids (g)') ?>
<?= $form->field($model, 'quantity_max')
->hint('Renseignez ce champs si vous souhaitez limiter la quantité commandable pour une distribution.')
->textInput() ?>
<?php
if(!$model->isNewRecord) {
echo $form->field($model, 'apply_distributions')
->checkbox()
->hint('Sélectionnez cette option si vous souhaitez que ces modifications (actif / non actif, quantité max) soient répercutées dans les distributions à venir déjà initialisées.');
<?= $form->field($model, 'active')->radioList([1 => 'Oui', 0 => 'Non']) ?>
<?= $form->field($model, 'name')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'description')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'recipe')->textarea()->label('Description longue') ?>

<?= $form->field($model, 'unit')
->dropDownList(ArrayHelper::map(Product::$unitsArray, 'unit', 'wording'))
->label('Unité (pièce, poids ou volume)'); ?>


<?php

//Récupère la tva par défaut du producteur courant
$producer = \common\helpers\GlobalParam::getCurrentProducer();
$taxRateDefault = $producer->taxRate;

$taxRateNamesArray = array_merge(array(0 => 'Tva par défaut'), ArrayHelper::map(TaxRate::find()->all(), 'id', function ($model) {
return $model->name;
}));
$taxRateValuesArray = array_merge(array(0 => $taxRateDefault->value), ArrayHelper::map(TaxRate::find()->all(), 'id', function ($model) {
return $model->value;
}));
foreach ($taxRateValuesArray as $key => $taxRateValue) {
$taxRateValuesArrayFormatted[$key] = array('data-tax-rate-value' => $taxRateValue);
}
?>

?>

<?php if($taxRateDefault->value != 0): ?>
<?= $form->field($model, 'id_tax_rate')->dropDownList($taxRateNamesArray, ['options' => $taxRateValuesArrayFormatted])->label('Taxe'); ?>
<?php endif; ?>

<?= $form->field($model, 'price', [
'template' => '
<div class="row">
<div class="col-xs-6">
<label for="product-price" class="control-label without-tax"></label>
<div class="input-group">
{input}<span class="input-group-addon"><span class="glyphicon glyphicon-euro"></span></span>
</div>
</div>
<div class="col-xs-6">
<label for="product-price-with-tax" class="control-label with-tax"></label>
<div class="input-group">
<input type="text" id="product-price-with-tax" class="form-control" name="" value="">
<span class="input-group-addon"><span class="glyphicon glyphicon-euro"></span></span>
</div>
</div>
</div>
',
]) ?>
<?= $form->field($model, 'step')->textInput()->hint('Définit ce qui est ajouté ou enlevé lors des changements de quantité.') ?>

<?= $form->field($model, 'weight')->textInput()->label('Poids (g)') ?>
<?= $form->field($model, 'quantity_max')
->hint('Renseignez ce champs si vous souhaitez limiter la quantité commandable pour une distribution.')
->textInput() ?>
<?php
if (!$model->isNewRecord) {
echo $form->field($model, 'apply_distributions')
->checkbox()
->hint('Sélectionnez cette option si vous souhaitez que ces modifications (actif / non actif, quantité max) soient répercutées dans les distributions à venir déjà initialisées.');
}
?>
</div>
<div class="col-md-4">
<?= $form->field($model, 'photo')->fileInput() ?>
<?php
if(strlen($model->photo)) {
$url = Yii::$app->urlManagerProducer->getHostInfo().'/'.Yii::$app->urlManagerProducer->baseUrl ;
echo '<img class="photo-product" src="'.$url.'/uploads/'.$model->photo.'" width="200px" /><br />' ;
echo '<input type="checkbox" name="delete_photo" id="delete_photo" /> <label for="delete_photo">Supprimer la photo</label><br /><br />' ;
<?= $form->field($model, 'photo')->fileInput() ?>
<?php
if (strlen($model->photo)) {
$url = Yii::$app->urlManagerProducer->getHostInfo() . '/' . Yii::$app->urlManagerProducer->baseUrl;
echo '<img class="photo-product" src="' . $url . '/uploads/' . $model->photo . '" width="200px" /><br />';
echo '<input type="checkbox" name="delete_photo" id="delete_photo" /> <label for="delete_photo">Supprimer la photo</label><br /><br />';
}
?>
?>

<div id="days-production">
<h2>Jours de distribution</h2>
<?= $form->field($model, 'monday')->checkbox() ?>
<?= $form->field($model, 'tuesday')->checkbox() ?>
<?= $form->field($model, 'wednesday')->checkbox() ?>
<?= $form->field($model, 'thursday')->checkbox() ?>
<?= $form->field($model, 'friday')->checkbox() ?>
<?= $form->field($model, 'saturday')->checkbox() ?>
<?= $form->field($model, 'sunday')->checkbox() ?>
<?= $form->field($model, 'monday')->checkbox() ?>
<?= $form->field($model, 'tuesday')->checkbox() ?>
<?= $form->field($model, 'wednesday')->checkbox() ?>
<?= $form->field($model, 'thursday')->checkbox() ?>
<?= $form->field($model, 'friday')->checkbox() ?>
<?= $form->field($model, 'saturday')->checkbox() ?>
<?= $form->field($model, 'sunday')->checkbox() ?>
</div>
<div class="clr"></div>
</div>
<div class="clr"></div>
</div>
<?= $form->field($model, 'id_producer')->hiddenInput()->label('') ?>
<?= $form->field($model, 'id_producer')->hiddenInput()->label('') ?>

<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Ajouter' : 'Modifier', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
<?= Html::submitButton($model->isNewRecord ? 'Ajouter' : 'Modifier', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>

<?php ActiveForm::end(); ?>
<?php ActiveForm::end(); ?>

</div>

+ 132
- 114
backend/views/product/index.php Целия файл

@@ -1,128 +1,146 @@
<?php

/**
Copyright distrib (2018)
/**
* 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.
*/

contact@opendistrib.net
use yii\helpers\Html;
use yii\grid\GridView;
use common\helpers\Url;
use common\models\Product;
use common\models\TaxRate;
use common\models\Producer;
use common\helpers\GlobalParam;

Ce logiciel est un programme informatique servant à aider les producteurs
à distribuer leur production en circuits courts.
$this->setTitle('Produits');
$this->addBreadcrumb($this->getTitle());
$this->addButton(['label' => 'Nouveau produit <span class="glyphicon glyphicon-plus"></span>', 'url' => 'product/create', 'class' => 'btn btn-primary']);

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é.
<span style="display: none;" id="page-size"><?= $dataProvider->pagination->pageSize; ?></span>
<div class="product-index">
<?= GridView::widget([
'filterModel' => $searchModel,
'dataProvider' => $dataProvider,
'columns' => [
[
'attribute' => 'order',
'headerOptions' => ['class' => 'order'],
'format' => 'raw',
'filter' => '',
'value' => function ($model) {
return '<a class="btn-order btn btn-default" href="javascript:void(0);"><span class="glyphicon glyphicon-resize-vertical"></span></a>';
}
],
[
'attribute' => 'photo',
'format' => 'raw',
'headerOptions' => ['class' => 'td-photo'],
'filter' => '',
'value' => function ($model) {
if (strlen($model->photo)) {
$url = Yii::$app->urlManagerProducer->getHostInfo() . '/' . Yii::$app->urlManagerProducer->baseUrl;
return '<img class="photo-product" src="' . $url . '/uploads/' . $model->photo . '" />';
}
return '';
}
],
'name',
'description',
[
'attribute' => 'id_tax_rate',
'value' => function ($model) {
if ($model->id_tax_rate == 0 || $model->id_tax_rate == null) {

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.
*/
//Récupère la tva par défaut du producteur courant
$taxRateDefault = GlobalParam::getCurrentProducer()->taxRate;

use yii\helpers\Html;
use yii\grid\GridView;
use common\helpers\Url ;
use common\models\Product ;
$return = $taxRateDefault->name;
} else {

$this->setTitle('Produits') ;
$this->addBreadcrumb($this->getTitle()) ;
$this->addButton(['label' => 'Nouveau produit <span class="glyphicon glyphicon-plus"></span>', 'url' => 'product/create', 'class' => 'btn btn-primary']) ;
$return = $model->taxRate->name;
}
return $return;
}
],
[
'attribute' => 'price',
'value' => function ($model) {
$return = '';
if ($model->price) {
$return = Price::format($model->getPriceWithTax()) . ' (' . Product::strUnit($model->unit, 'wording_unit', true) . ')';
}

?>
return $return;
}
],
[
'attribute' => 'active',
'headerOptions' => ['class' => 'active'],
'contentOptions' => ['class' => 'center'],
'format' => 'raw',
'filter' => [0 => 'Non', 1 => 'Oui'],
'value' => function ($model) {
if ($model->active) {
return '<span class="label label-success">oui</span>';
} else {
return '<span class="label label-danger">non</span>';
}
}
],

<span style="display: none;" id="page-size"><?= $dataProvider->pagination->pageSize; ?></span>
<div class="product-index">
<?= GridView::widget([
'filterModel' => $searchModel,
'dataProvider' => $dataProvider,
'columns' => [
[
'attribute' => 'order',
'headerOptions' => ['class' => 'order'],
'format' => 'raw',
'filter' => '',
'value' => function($model) {
return '<a class="btn-order btn btn-default" href="javascript:void(0);"><span class="glyphicon glyphicon-resize-vertical"></span></a>' ;
}
],
[
'attribute' => 'photo',
'format' => 'raw',
'headerOptions' => ['class' => 'td-photo'],
'filter' => '',
'value' => function($model) {
if(strlen($model->photo)) {
$url = Yii::$app->urlManagerProducer->getHostInfo().'/'.Yii::$app->urlManagerProducer->baseUrl ;
return '<img class="photo-product" src="'.$url.'/uploads/'.$model->photo.'" />' ;
}
return '' ;
}
],
'name',
'description',
[
'attribute' => 'price',
'value' => function($model) {
$return = '' ;
if($model->price) {
$return = Price::format($model->price).' ('.Product::strUnit($model->unit, 'wording_unit', true).')' ;
}
return $return ;
}
],
[
'attribute' => 'active',
'headerOptions' => ['class' => 'active'],
'contentOptions' => ['class' => 'center'],
'format' => 'raw',
'filter' => [0 => 'Non', 1 => 'Oui'],
'value' => function($model) {
if($model->active)
{
return '<span class="label label-success">oui</span>' ;
}
else {
return '<span class="label label-danger">non</span>' ;
}
}
],
[
'class' => 'yii\grid\ActionColumn',
'template' => '{update} {delete}',
'headerOptions' => ['class' => 'column-actions'],
'contentOptions' => ['class' => 'column-actions'],
'buttons' => [
'update' => function ($url, $model) {
return Html::a('<span class="glyphicon glyphicon-pencil"></span>', $url, [
'title' => Yii::t('app', 'Modifier'), 'class' => 'btn btn-default'
]);
},
'delete' => function ($url, $model) {
return Html::a('<span class="glyphicon glyphicon-trash"></span>', $url, [
'title' => Yii::t('app', 'Supprimer'), 'class' => 'btn btn-default'
]);
}
[
'class' => 'yii\grid\ActionColumn',
'template' => '{update} {delete}',
'headerOptions' => ['class' => 'column-actions'],
'contentOptions' => ['class' => 'column-actions'],
'buttons' => [
'update' => function ($url, $model) {
return Html::a('<span class="glyphicon glyphicon-pencil"></span>', $url, [
'title' => Yii::t('app', 'Modifier'), 'class' => 'btn btn-default'
]);
},
'delete' => function ($url, $model) {
return Html::a('<span class="glyphicon glyphicon-trash"></span>', $url, [
'title' => Yii::t('app', 'Supprimer'), 'class' => 'btn btn-default'
]);
}
],
],
],
],
],
]); ?>
]); ?>
</div>

+ 128
- 0
backend/views/quotation/index.php Целия файл

@@ -0,0 +1,128 @@
<?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.
*/

$this->setTitle('Devis');
$this->addBreadcrumb($this->getTitle());
$this->addButton(['label' => 'Nouveau devis <span class="glyphicon glyphicon-plus"></span>', 'url' => 'quotation/create', 'class' => 'btn btn-primary']);

?>

<div class="quotation-index">
<?= GridView::widget([
'filterModel' => $searchModel,
'dataProvider' => $dataProvider,
'columns' => [
[
'attribute' => 'status',
'label' => 'Statut',
'filter' => [
'draft' => 'Brouillon',
'valid' => 'Valide',
],
'format' => 'raw',
'value' => function($model) {
return $model->getHtmlLabel() ;
}
],
[
'attribute' => 'reference',
'value' => function($model) {
if(strlen($model->reference) > 0) {
return $model->reference ;
}
return '' ;
}
],
'name',
[
'attribute' => 'id_user',
'header' => 'Utilisateur',
'value' => function($model) {
return $model->user->getUsername() ;
}
],
[
'attribute' => 'date',
'header' => 'Date',
'value' => function($model) {
return date('d/m/Y',strtotime($model->date)) ;
}
],
[
'attribute' => 'amount',
'header' => 'Montant',
'value' => function($invoice) {
return $invoice->getAmountWithTax(Order::AMOUNT_TOTAL, true) ;
}
],
[
'class' => 'yii\grid\ActionColumn',
'template' => '{validate} {update} {delete} {send} {download}',
'headerOptions' => ['class' => 'column-actions'],
'contentOptions' => ['class' => 'column-actions'],
'buttons' => [
'validate' => function ($url, $model) {
return ($model->isStatusDraft() ? Html::a('<span class="glyphicon glyphicon-ok"></span>', $url, [
'title' => Yii::t('app', 'Valider'), 'class' => 'btn btn-default'
]) : '');
},
'send' => function($url, $model) {
return (!$model->isStatusDraft() ? Html::a('<span class="glyphicon glyphicon-send"></span>', $url, [
'title' => Yii::t('app', 'Envoyer'), 'class' => 'btn btn-default'
]) : '');
},
'download' => function($url, $model) {
return Html::a('<span class="glyphicon glyphicon-download-alt"></span>', $url, [
'title' => Yii::t('app', 'Télécharger'), 'class' => 'btn btn-default'
]);
},
'update' => function ($url, $model) {
return ($model->isStatusDraft() ? Html::a('<span class="glyphicon glyphicon-pencil"></span>', $url, [
'title' => Yii::t('app', 'Modifier'), 'class' => 'btn btn-default'
]) : '');
},
'delete' => function ($url, $model) {
return ($model->isStatusDraft() ? Html::a('<span class="glyphicon glyphicon-trash"></span>', $url, [
'title' => Yii::t('app', 'Supprimer'), 'class' => 'btn btn-default'
]) : '');
}
],
],
],
]); ?>
</div>

+ 1
- 1
backend/views/site/index.php Целия файл

@@ -174,7 +174,7 @@ $this->title = 'Tableau de bord';
</td>
<td><?= $order->getCartSummary() ; ?></td>
<td><?= $order->getPointSaleSummary() ; ?></td>
<td><?= $order->getAmount(Order::AMOUNT_TOTAL, true) ; ?></td>
<td><?= $order->getAmountWithTax(Order::AMOUNT_TOTAL, true) ; ?></td>
<td class="history"><?= $order->getStrHistory() ; ?></td>
</tr>
<?php endforeach; ?>

+ 5
- 10
backend/views/subscription/_form.php Целия файл

@@ -41,6 +41,7 @@ use yii\widgets\ActiveForm;
use yii\helpers\ArrayHelper ;
use common\models\User ;
use common\models\PointSale ;
use common\helpers\GlobalParam ;

\backend\assets\VuejsSubscriptionFormAsset::register($this);

@@ -52,7 +53,7 @@ use common\models\PointSale ;
<?= $form->field($model, 'id')->hiddenInput() ?>
<?php endif; ?>
<div class="col-md-5" id="bloc-select-user">
<?= $form->field($model, 'id_user')->dropDownList( ArrayHelper::map(User::find()->joinWith('userProducer')->where('user_producer.id_producer = '.Producer::getId())->andWhere('user_producer.active = 1')->orderBy('lastname ASC, name ASC')->all(), 'id', function($model, $defaultValue) {
<?= $form->field($model, 'id_user')->dropDownList( ArrayHelper::map(User::find()->joinWith('userProducer')->where('user_producer.id_producer = '.GlobalParam::getCurrentProducerId())->andWhere('user_producer.active = 1')->orderBy('lastname ASC, name ASC')->all(), 'id', function($model, $defaultValue) {
return $model['lastname'].' '.$model['name'];
}), ['prompt' => '--','class' => 'form-control user-id', ]) ?>
</div>
@@ -65,7 +66,7 @@ use common\models\PointSale ;
<div class="clr"></div>
<?= $form->field($model, 'id_producer')->hiddenInput() ?>
<?= $form->field($model, 'id_point_sale')->dropDownList(ArrayHelper::map(PointSale::find()->where('id_producer = '.Producer::getId())->all(), 'id', function($model, $defaultValue) {
<?= $form->field($model, 'id_point_sale')->dropDownList(ArrayHelper::map(PointSale::find()->where('id_producer = '.GlobalParam::getCurrentProducerId())->all(), 'id', function($model, $defaultValue) {
return $model['name'];
}), ['prompt' => '--','class' => 'form-control user-id']) ?>
<?= $form->field($model, 'date_begin') ?>
@@ -108,11 +109,8 @@ use common\models\PointSale ;
</span>
<input v-model="product.quantity" :name="'SubscriptionForm[products][product_'+product.id+']'" class="form-control input-quantity" />
<div class="input-group-addon">
<select class="form-control select-unit" :name="'product_unit_'+product.id" v-model="product.unit" v-if="product.units.length > 1" @change="changeUnitProductSubscription" :data-id-product="product.id">
<option v-for="unit in product.units" :value="unit.unit">{{ unit.wording_unit }}</option>
</select>
<span v-else>
{{ product.units[0].wording_unit }}
<span>
{{ product.wording_unit }}
</span>
</div>
<span class="input-group-btn">
@@ -120,9 +118,6 @@ use common\models\PointSale ;
</span>
</div>
</td>
<td>
<span v-if="product.units.length > 1 && product.unit != product.unit_save" class="glyphicon glyphicon-warning-sign" title="Unité différente du produit"></span>
</td>
</tr>
</table>
</div>

+ 6
- 21
backend/views/subscription/index.php Целия файл

@@ -39,6 +39,7 @@ termes.
use yii\helpers\Html;
use yii\grid\GridView;
use common\models\Product ;
use common\helpers\GlobalParam ;


$this->setTitle('Abonnements') ;
@@ -46,22 +47,11 @@ $this->addBreadcrumb($this->getTitle()) ;
$this->addButton(['label' => 'Nouvel abonnement <span class="glyphicon glyphicon-plus"></span>', 'url' => 'subscription/create', 'class' => 'btn btn-primary']) ;

$subscriptionsArray = Subscription::searchAll() ;
$hasUnitsNotMatch = false ;
foreach($subscriptionsArray as $subscription) {
if($subscription->hasUnitsNotMatch()) {
$hasUnitsNotMatch = true ;
}
}



?>
<div class="subscription-index">

<?php if($hasUnitsNotMatch) : ?>
<div class="alert alert-warning">
<span class="glyphicon glyphicon-warning-sign"></span> Attention, des unités ne correspondent pas entre vos produits et vos abonnements.<br />
Veuillez modifier vos abonnements et ajuster les unités / quantités pour régler le problème.
</div>
<?php endif; ?>
<?= GridView::widget([
'filterModel' => $searchModel,
@@ -92,7 +82,7 @@ foreach($subscriptionsArray as $subscription) {
foreach($model->productSubscription as $productSubscription)
{
if(isset($productSubscription->product)) {
$html .= Html::encode($productSubscription->product->name).' ('.($productSubscription->quantity * Product::$unitsArray[$productSubscription->unit]['coefficient']).'&nbsp;'.Product::strUnit($productSubscription->unit, 'wording_short').')<br />' ;
$html .= Html::encode($productSubscription->product->name).' ('.($productSubscription->quantity * Product::$unitsArray[$productSubscription->product->unit]['coefficient']).'&nbsp;'.Product::strUnit($productSubscription->product->unit, 'wording_short').')<br />' ;
}
else {
$html .= 'Produit non défini<br />' ;
@@ -104,12 +94,7 @@ foreach($subscriptionsArray as $subscription) {
{
$html .= '<span class="glyphicon glyphicon-warning-sign"></span> Aucun produit<br />' ;
}
// des unités ne correspondent pas
if($model->hasUnitsNotMatch()) {
$html .= '<span class="glyphicon glyphicon-warning-sign" title="Des unités ne correspondent pas"></span>' ;
}

return $html ;
}
],
@@ -117,7 +102,7 @@ foreach($subscriptionsArray as $subscription) {
'attribute' => 'id_point_sale',
'label' => 'Point de vente',
'format' => 'raw',
'filter' => ArrayHelper::map(PointSale::find()->where(['id_producer' => Producer::getId()])->asArray()->all(), 'id', 'name'),
'filter' => ArrayHelper::map(PointSale::find()->where(['id_producer' => GlobalParam::getCurrentProducerId()])->asArray()->all(), 'id', 'name'),
'value' => function($model) {
return Html::encode($model->pointSale->name) ;
}

+ 58
- 0
backend/views/tax-rate-admin/create.php Целия файл

@@ -0,0 +1,58 @@
<?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.
*/

use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\helpers\ArrayHelper ;
use common\models\Producer ;

$this->setTitle('Ajouter une taxe') ;
$this->addBreadcrumb(['label' => 'taxe', 'url' => ['index']]) ;
$this->addBreadcrumb('Ajouter') ;

?>

<div class="tax-create">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'name') ?>
<?= $form->field($model, 'value') ?>
<div class="form-group">
<?= Html::submitButton('Ajouter', ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>

+ 80
- 0
backend/views/tax-rate-admin/index.php Целия файл

@@ -0,0 +1,80 @@
<?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.
*/

use yii\helpers\Html;
use yii\grid\GridView;
use common\models\User;
use common\models\Producer;
use common\models\Distribution;

$this->setTitle('Taxes');
$this->addBreadcrumb($this->getTitle());
$this->addButton(['label' => 'Nouvelle taxe <span class="glyphicon glyphicon-plus"></span>', 'url' => 'tax-rate-admin/create', 'class' => 'btn btn-primary']);

?>

<?= GridView::widget([
'dataProvider' => $dataProviderTaxRate,
'columns' => [
'name',
[
'attribute' => 'value',
'value' => function ($model) {
return $model->value . '%';
}
],
[
'class' => 'yii\grid\ActionColumn',
'template' => '{update} {delete}',
'headerOptions' => ['class' => 'column-actions'],
'contentOptions' => ['class' => 'column-actions'],
'buttons' => [
'update' => function ($url, $model) {
return Html::a('<span class="glyphicon glyphicon-pencil"></span>', $url, [
'title' => Yii::t('app', 'Modifier'), 'class' => 'btn btn-default'
]);
},
'delete' => function ($url, $model) {
return Html::a('<span class="glyphicon glyphicon-trash"></span>', $url, [
'title' => Yii::t('app', 'Supprimer'), 'class' => 'btn btn-default'
]);
}
],
],
],
]); ?>

+ 58
- 0
backend/views/tax-rate-admin/update.php Целия файл

@@ -0,0 +1,58 @@
<?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.
*/

use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\helpers\ArrayHelper ;
use common\models\Producer ;

$this->setTitle('Éditer une taxe') ;
$this->addBreadcrumb(['label' => 'taxe', 'url' => ['index']]) ;
$this->addBreadcrumb('Éditer') ;

?>

<div class="tax-create">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'name') ?>
<?= $form->field($model, 'value') ?>
<div class="form-group">
<?= Html::submitButton('Ajouter', ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>

+ 81
- 71
backend/views/user/_form.php Целия файл

@@ -1,85 +1,95 @@
<?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.
*/
/**
* 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.
*/

use yii\helpers\Html;
use yii\widgets\ActiveForm;

/* @var $this yii\web\View */
/* @var $model common\models\User */
/* @var $form yii\widgets\ActiveForm */
\backend\assets\VuejsUserFormAsset::register($this);

?>

<div class="user-form">
<div class="user-form" id="app-user-form">

<div class="col-md-8">
<?php $form = ActiveForm::begin([
'enableClientValidation' => false
]); ?>

<div class="col-md-8">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'lastname')->textInput() ?>
<?= $form->field($model, 'name')->textInput() ?>
<?= $form->field($model, 'phone')->textInput() ?>
<?= $form->field($model, 'email')->textInput() ?>
<?= $form->field($model, 'address')->textarea() ?>
<?= $form->field($model, 'points_sale')->checkboxlist(
ArrayHelper::map($pointsSaleArray, 'id',function($pointSale) use ($model) {
$commentUserPointSale = isset($pointSale->userPointSale[0]) ? $pointSale->userPointSale[0]->comment : '' ;
$html = Html::encode($pointSale->name);
if($pointSale->restricted_access) {
$html .= '<input type="text" placeholder="Commentaire" class="form-control" name="User[comment_point_sale_'.$pointSale->id.']" value="'.(($model->id) ? Html::encode($commentUserPointSale) : '').'" />' ;
}
return $html ;
}), [
'encode' => false
]);
?>
<?= $form->field($model, 'type')
->dropDownList([
User::TYPE_INDIVIDUAL => 'Particulier',
User::TYPE_LEGAL_PERSON => 'Personne morale'
], [
'v-model' => 'type'
]) ; ?>
<?= $form->field($model, 'name_legal_person', ['options' => ['v-show' => "type == 'legal-person'"]])->textInput() ?>
<?= $form->field($model, 'lastname')->textInput() ?>
<?= $form->field($model, 'name')->textInput() ?>
<?= $form->field($model, 'phone')->textInput() ?>
<?= $form->field($model, 'email')->textInput() ?>
<?= $form->field($model, 'address')->textarea() ?>
<?= $form->field($model, 'points_sale')->checkboxlist(
ArrayHelper::map($pointsSaleArray, 'id', function ($pointSale) use ($model) {
$commentUserPointSale = isset($pointSale->userPointSale[0]) ? $pointSale->userPointSale[0]->comment : '';
$html = Html::encode($pointSale->name);
if ($pointSale->restricted_access) {
$html .= '<input type="text" placeholder="Commentaire" class="form-control" name="User[comment_point_sale_' . $pointSale->id . ']" value="' . (($model->id) ? Html::encode($commentUserPointSale) : '') . '" />';
}
return $html;
}), [
'encode' => false
]);
?>

<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Ajouter' : 'Modifier', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Ajouter' : 'Modifier', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>

<?php ActiveForm::end(); ?>
</div>

<?php ActiveForm::end(); ?>
</div>
<div class="col-md-4">
<h2>Mot de passe</h2>
<?php $form = ActiveForm::begin(); ?>
<div class="form-group">
<?= Html::submitButton('Envoyer un nouveau mot de passe', ['class' => 'btn btn-primary', 'name' => 'submit_new_password', 'value' => 1]) ?>
<div class="col-md-4">
<h2>Mot de passe</h2>
<?php $form = ActiveForm::begin(); ?>
<div class="form-group">
<?= Html::submitButton('Envoyer un nouveau mot de passe', ['class' => 'btn btn-primary', 'name' => 'submit_new_password', 'value' => 1]) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
<?php ActiveForm::end(); ?>
</div>

</div>

+ 2
- 1
backend/views/user/credit.php Целия файл

@@ -40,6 +40,7 @@ use yii\helpers\Html;
use yii\widgets\ActiveForm;
use common\models\CreditHistory;
use common\models\Producer;
use common\helpers\GlobalParam;

$this->setTitle('Créditer <small>'.Html::encode($user->lastname.' '.$user->name).'</small>', 'Créditer '.Html::encode($user->lastname.' '.$user->name)) ;
$this->addBreadcrumb(['label' => 'Utilisateurs', 'url' => ['index']]) ;
@@ -52,7 +53,7 @@ $this->addBreadcrumb('Créditer') ;
<?php
$producer = Producer::searchOne([
'id' => Producer::getId()
'id' => GlobalParam::getCurrentProducerId()
]);
if(!$producer->credit)

+ 6
- 1
backend/views/user/index.php Целия файл

@@ -67,7 +67,12 @@ $this->render('_menu',[
'attribute' => 'username',
'label' => 'Nom',
'value' => function($model) {
return $model['lastname'].' '.$model['name'] ;
if(isset($model['name_legal_person'])) {
return $model['name_legal_person'] ;
}
else {
return $model['lastname'].' '.$model['name'] ;
}
}
],
[

+ 105
- 0
backend/web/css/document/download.css Целия файл

@@ -0,0 +1,105 @@
/* line 5, ../../sass/document/download.scss */
.document-download {
font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
/* line 9, ../../sass/document/download.scss */
.document-download #block-addresses .producer {
text-align: left;
margin-bottom: 20px;
}
/* line 13, ../../sass/document/download.scss */
.document-download #block-addresses .producer .logo {
margin-bottom: 20px;
}
/* line 20, ../../sass/document/download.scss */
.document-download #block-addresses .user {
text-align: right;
}
/* line 25, ../../sass/document/download.scss */
.document-download #block-infos-document {
padding-top: 30px;
}
/* line 28, ../../sass/document/download.scss */
.document-download #block-infos-document .date {
padding-bottom: 10px;
}
/* line 31, ../../sass/document/download.scss */
.document-download #block-infos-document .reference {
padding-bottom: 10px;
font-size: 15px;
font-weight: bold;
}
/* line 36, ../../sass/document/download.scss */
.document-download #block-infos-document .reference .block-is-draft {
border: solid 2px black;
padding: 10px;
text-transform: uppercase;
}
/* line 47, ../../sass/document/download.scss */
.document-download #block-no-product {
font-weight: bold;
border: solid 2px black;
text-transform: uppercase;
padding: 10px;
}
/* line 54, ../../sass/document/download.scss */
.document-download #block-products {
padding-top: 20px;
}
/* line 57, ../../sass/document/download.scss */
.document-download #block-products table {
width: 100%;
padding: 0px;
margin: 0px;
border-bottom: solid 1px #c0c0c0;
border-right: solid 1px #c0c0c0;
border-collapse: collapse;
}
/* line 65, ../../sass/document/download.scss */
.document-download #block-products table td, .document-download #block-products table th {
padding: 5px;
border-top: solid 1px #c0c0c0;
border-left: solid 1px #c0c0c0;
font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
/* line 71, ../../sass/document/download.scss */
.document-download #block-products table td.align-left, .document-download #block-products table th.align-left {
text-align: left;
}
/* line 74, ../../sass/document/download.scss */
.document-download #block-products table td.align-center, .document-download #block-products table th.align-center {
text-align: center;
}
/* line 77, ../../sass/document/download.scss */
.document-download #block-products table td.align-right, .document-download #block-products table th.align-right {
text-align: right;
}
/* line 84, ../../sass/document/download.scss */
.document-download .block-infos {
margin-top: 20px;
padding: 10px;
border: solid 1px #c0c0c0;
}
/* line 89, ../../sass/document/download.scss */
.document-download .block-infos strong {
font-size: 12px;
}

/* line 95, ../../sass/document/download.scss */
#footer {
font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
text-align: center;
padding-top: 20px;
border-top: solid 1px gray;
}
/* line 101, ../../sass/document/download.scss */
#footer .infos-bottom {
padding-bottom: 20px;
margin-bottom: 40px;
font-size: 12px;
line-height: 18px;
}
/* line 107, ../../sass/document/download.scss */
#footer .reference-document {
font-weight: bold;
}

+ 119
- 26
backend/web/css/screen.css Целия файл

@@ -1699,6 +1699,37 @@ body.login-page .login-box .login-box-body a:hover {
color: #ff8c1a;
}

/* line 2, ../sass/_alerts.scss */
#app-alerts {
position: fixed;
bottom: 30px;
right: 15px;
width: 300px;
height: auto;
}
/* line 9, ../sass/_alerts.scss */
#app-alerts .slide-fade-enter-active {
-moz-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
-webkit-transition: all 0.3s ease;
transition: all 0.3s ease;
}
/* line 12, ../sass/_alerts.scss */
#app-alerts .slide-fade-leave-active {
-moz-transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1);
-o-transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1);
-webkit-transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1);
transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1);
}
/* line 15, ../sass/_alerts.scss */
#app-alerts .slide-fade-enter, #app-alerts .slide-fade-leave-to {
-moz-transform: translateX(10px);
-ms-transform: translateX(10px);
-webkit-transform: translateX(10px);
transform: translateX(10px);
opacity: 0;
}

/* line 4, ../sass/site/_index.scss */
.site-index #distributions .info-box {
border: solid 1px #e0e0e0;
@@ -1983,11 +2014,25 @@ termes.
-webkit-border-radius: 10px;
border-radius: 10px;
}
/* line 207, ../sass/distribution/_index.scss */
/* line 204, ../sass/distribution/_index.scss */
.distribution-index #orders #buttons-top-orders {
background-color: #F5F5F5;
padding: 10px 20px;
border: solid 1px #e0e0e0;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
margin-bottom: 20px;
}
/* line 215, ../sass/distribution/_index.scss */
.distribution-index #orders #buttons-top-orders .right {
float: right;
}
/* line 222, ../sass/distribution/_index.scss */
.distribution-index #orders table td.tiller {
width: 60px;
}
/* line 210, ../sass/distribution/_index.scss */
/* line 225, ../sass/distribution/_index.scss */
.distribution-index #orders table td.tiller label {
font-size: 12px;
cursor: pointer;
@@ -1995,73 +2040,78 @@ termes.
top: -2px;
font-weight: normal;
}
/* line 219, ../sass/distribution/_index.scss */
/* line 234, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-actions {
position: relative;
text-align: right;
width: 230px;
}
/* line 223, ../sass/distribution/_index.scss */
/* line 238, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-actions .dropdown-menu {
top: 0px;
right: 0px;
}
/* line 243, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-actions .modal-form-order,
.distribution-index #orders table td.column-actions .modal-payment {
text-align: left;
}
/* line 228, ../sass/distribution/_index.scss */
/* line 248, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-actions .add-subscription {
position: relative;
}
/* line 230, ../sass/distribution/_index.scss */
/* line 250, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-actions .add-subscription .glyphicon-plus {
position: absolute;
top: 4px;
right: 4px;
font-size: 7px;
}
/* line 239, ../sass/distribution/_index.scss */
/* line 259, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-state-payment {
width: 120px;
}
/* line 244, ../sass/distribution/_index.scss */
/* line 264, ../sass/distribution/_index.scss */
.distribution-index #orders table td.column-payment div.btn-group {
width: 125px;
}
/* line 250, ../sass/distribution/_index.scss */
/* line 270, ../sass/distribution/_index.scss */
.distribution-index #orders table tr.view ul {
list-style-type: none;
margin-left: 0px;
padding-left: 15px;
}
/* line 259, ../sass/distribution/_index.scss */
/* line 279, ../sass/distribution/_index.scss */
.distribution-index #orders table tr.view .comment {
margin-top: 20px;
}
/* line 268, ../sass/distribution/_index.scss */
/* line 288, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order .btn-credit {
float: right;
}
/* line 274, ../sass/distribution/_index.scss */
/* line 294, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products .product-ordered td {
background-color: #e9e9e9;
}
/* line 278, ../sass/distribution/_index.scss */
/* line 298, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products .product-ordered input {
font-size: 16px;
font-weight: bold;
}
/* line 284, ../sass/distribution/_index.scss */
/* line 304, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity {
width: 165px;
}
/* line 287, ../sass/distribution/_index.scss */
/* line 307, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity input {
text-align: center;
color: black;
}
/* line 291, ../sass/distribution/_index.scss */
/* line 311, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity .form-control {
border-right: 0px none;
padding-right: 4px;
}
/* line 295, ../sass/distribution/_index.scss */
/* line 315, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity .input-group-addon {
padding: 5px;
padding-left: 0px;
@@ -2069,35 +2119,35 @@ termes.
border-left: 0px none;
border-right: 0px none;
}
/* line 303, ../sass/distribution/_index.scss */
/* line 323, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity-remaining {
text-align: right;
}
/* line 306, ../sass/distribution/_index.scss */
/* line 326, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity-remaining.quantity-remaining, .distribution-index .modal-form-order table.table-products td.quantity-remaining.infinite {
color: #00A65A;
}
/* line 310, ../sass/distribution/_index.scss */
/* line 330, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity-remaining.negative {
color: #DD4B39;
}
/* line 314, ../sass/distribution/_index.scss */
/* line 334, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order table.table-products td.quantity-remaining.infinite, .distribution-index .modal-form-order table.table-products td.quantity-remaining.empty {
font-size: 18px;
}
/* line 321, ../sass/distribution/_index.scss */
/* line 341, ../sass/distribution/_index.scss */
.distribution-index .modal-form-order .actions-form button {
margin-left: 15px;
}
/* line 329, ../sass/distribution/_index.scss */
/* line 349, ../sass/distribution/_index.scss */
.distribution-index .modal-payment .info-box .info-box-icon {
width: 50px;
}
/* line 331, ../sass/distribution/_index.scss */
/* line 351, ../sass/distribution/_index.scss */
.distribution-index .modal-payment .info-box .info-box-icon i {
font-size: 30px;
}
/* line 335, ../sass/distribution/_index.scss */
/* line 355, ../sass/distribution/_index.scss */
.distribution-index .modal-payment .info-box .info-box-content {
margin-left: 50px;
}
@@ -2265,3 +2315,46 @@ termes.
.report-index #report .section .comma:last-child {
display: none;
}

/* line 4, ../sass/document/_form.scss */
.document-form .info-box .info-box-text {
font-size: 13px;
}
/* line 7, ../sass/document/_form.scss */
.document-form .info-box .info-box-number {
font-size: 15px;
}
/* line 12, ../sass/document/_form.scss */
.document-form #block-add-product .input-price {
text-align: center;
}
/* line 16, ../sass/document/_form.scss */
.document-form #block-add-product .input-group-quantity .input-quantity {
text-align: center;
}
/* line 22, ../sass/document/_form.scss */
.document-form #block-add-product .total .input-group {
margin-bottom: 10px;
}
/* line 25, ../sass/document/_form.scss */
.document-form #block-add-product .total .btn {
float: right;
}
/* line 32, ../sass/document/_form.scss */
.document-form #block-list-products ul.product-order-meta {
padding: 0px;
margin: 0px;
padding-left: 20px;
}
/* line 37, ../sass/document/_form.scss */
.document-form #block-list-products ul.product-order-meta li {
color: gray;
font-size: 11px;
}

/* line 7, ../sass/document/_index.scss */
.quotation-index .content-wrapper .content table.table .column-actions,
.delivery-note-index .content-wrapper .content table.table .column-actions,
.invoice-index .content-wrapper .content table.table .column-actions {
width: 200px;
}

+ 37
- 5
backend/web/js/backend.js Целия файл

@@ -35,7 +35,7 @@ termes.
*/

$(document).ready(function() {
opendistrib_datepicker() ;
opendistrib_datepicker() ;
$('button[data-toggle=popover]').popover() ;
opendistrib_commandeauto() ;
opendistrib_points_vente_acces() ;
@@ -67,12 +67,39 @@ function opendistrib_confirm_delete() {
function opendistrib_products() {
if($('.product-create').size() || $('.product-update').size()) {
opendistrib_products_event_unit(false) ;

$('#product-unit').change(function() {
opendistrib_products_event_unit(true) ;
}) ;


opendistrib_products_event_price_with_tax() ;

$('#product-price').change(opendistrib_products_event_price_with_tax);
$('#product-price-with-tax').change(opendistrib_products_event_price);
$('#product-id_tax_rate').change(opendistrib_products_event_price_with_tax);

}
}

function opendistrib_products_event_price_with_tax() {
taxRateSelected = $('#product-id_tax_rate').find('option:selected').data('tax-rate-value');
if(typeof taxRateSelected == 'undefined') {
taxRateSelected = 0 ;
}
$('#product-price-with-tax').val(getPriceWithTax($('#product-price').val(), taxRateSelected));
//formattage des prix
$('#product-price').val(parseFloat($('#product-price').val()).toFixed(2));
}
function opendistrib_products_event_price(){
taxRateSelected = $('#product-id_tax_rate').find('option:selected').data('tax-rate-value');
$('#product-price').val(getPrice($('#product-price-with-tax').val(), taxRateSelected));

//formattage des prix
$('#product-price-with-tax').val(parseFloat($('#product-price-with-tax').val()).toFixed(2));
}


function opendistrib_products_event_unit(change) {
var unit = $('#product-unit').val() ;
if(unit == 'piece') {
@@ -84,21 +111,25 @@ function opendistrib_products_event_unit(change) {
$('.field-product-weight').hide() ;
}
var label_price = $('.field-product-price .control-label') ;
var label_price_ttc = $('.field-product-price .control-label.with-tax') ;
var label_price_ht = $('.field-product-price .control-label.without-tax') ;
var label_step = $('.field-product-step .control-label') ;
var label_quantity_max = $('.field-product-quantity_max .control-label') ;
if(unit == 'piece') {
label_price.html('Prix (la pièce)') ;
label_price_ttc.html('Prix (la pièce) TTC') ;
label_price_ht.html('Prix (la pièce) HT') ;
label_quantity_max.html('Quantité max par défaut (pièces)') ;
}
else if(unit == 'g' || unit == 'kg') {
label_price.html('Prix (au kg)') ;
label_price_ttc.html('Prix (au kg) TTC') ;
label_price_ht.html('Prix (au kg) HT') ;
label_quantity_max.html('Quantité max par défaut (kg)') ;
label_step.html('Pas ('+unit+')') ;
}
else if(unit == 'mL' || unit == 'L') {
label_price.html('Prix (au litre)') ;
label_price_ttc.html('Prix (au litre) TTC') ;
label_price_ht.html('Prix (au litre) HT') ;
label_quantity_max.html('Quantité max par défaut (litres)') ;
label_step.html('Pas ('+unit+')') ;
}
@@ -244,3 +275,4 @@ function opendistrib_datepicker() {
return datepicker.regional['fr'];

}));


+ 39
- 0
backend/web/js/vuejs/alerts.js Целия файл

@@ -0,0 +1,39 @@

var appAlerts = new Vue({
el: '#app-alerts',
data: {
alerts: [
]
},
mounted: function() {

},
methods: {
alertResponse: function(response) {
if(response.data.alert) {
this.alert(response.data.alert.type, response.data.alert.message) ;
}
},
alert: function(type, message, timeout) {
var app = this ;
var index = this.alerts.length ;
this.alerts.splice(index, 0, {
display: false,
type: type,
message: message
});

var functionDisplayAlert = function(app, index, display) {
app.alerts[index].display = display ;
} ;

if(!timeout) {
timeout = 3000 ;
}

setTimeout(functionDisplayAlert, 500, app, index, true) ;
setTimeout(functionDisplayAlert, timeout, app, index, false) ;

}
}
});

+ 75
- 3
backend/web/js/vuejs/distribution-index.js Целия файл

@@ -38,6 +38,7 @@ termes.
var app = new Vue({
el: '#app-distribution-index',
data: {
UrlManager: UrlManager,
baseUrl: $('meta[name=baseurl]').attr('content'),
date: null,
dateFormat: null,
@@ -59,6 +60,7 @@ var app = new Vue({
ordersUpdate: [],
countOrders: 0,
users: [],
deliveryNotes: [],
showModalProducts: false,
showModalPointsSale: false,
showModalFormOrderCreate: false,
@@ -71,6 +73,8 @@ var app = new Vue({
idOrderPayment: 0,
showLoading: false,
tillerIsSynchro: false,
checkboxSelectAllOrders: false,
messageGenerateDeliveryNoteDisplayed: false,
calendar: {
mode: 'single',
attrs: [],
@@ -150,7 +154,6 @@ var app = new Vue({
app.products = response.data.products ;
app.initCountActiveProducts() ;
app.meansPayment = response.data.means_payment ;
app.oneDistributionWeekActive = response.data.one_distribution_week_active ;
app.countOrders = 0 ;
@@ -184,7 +187,11 @@ var app = new Vue({
if(response.data.users) {
app.users = response.data.users ;
}

if(response.data.delivery_notes) {
app.deliveryNotes = response.data.delivery_notes ;
}

app.tillerIsSynchro = response.data.tiller_is_synchro ;
app.calendar.attrs = [] ;
@@ -203,7 +210,14 @@ var app = new Vue({
}
}
app.showLoading = false ;
app.showLoading = false ;
app.checkboxSelectAllOrders = false ;

let searchParams = new URLSearchParams(window.location.search) ;
if(searchParams.has('message_generate_bl') && !app.messageGenerateDeliveryNoteDisplayed) {
appAlerts.alert('info','Pour générer un bon de livraison, sélectionnez tout d\'abord un jour et un lieu de distribution.', 6000) ;
app.messageGenerateDeliveryNoteDisplayed = true ;
}
}) ;
},
initCountActiveProducts: function() {
@@ -413,6 +427,15 @@ var app = new Vue({
app.init(app.idActivePointSale) ;
}) ;
},
totalActivePointSale: function() {
var total = 0 ;
for(var i = 0; i < this.orders.length ; i++) {
if(this.orders[i].id_point_sale == this.idActivePointSale) {
total += this.orders[i].amount ;
}
}
return formatPrice(total) ;
},
changeSynchroTiller: function(event) {
var app = this ;
var idOrder = event.currentTarget.getAttribute('data-id-order') ;
@@ -424,6 +447,55 @@ var app = new Vue({
app.init() ;
}) ;
},
selectAllOrdersEvent: function(event) {
var bool = event.currentTarget.checked ;
this.selectAllOrders(bool) ;
},
selectAllOrders: function(bool) {
for(var key in this.orders) {
if(this.orders[key].id_point_sale == this.idActivePointSale) {
this.orders[key].selected = bool ;
}
}
},
oneOrderSelected: function() {
for(var key in this.orders) {
if(this.orders[key].selected == true) {
return true ;
}
}
return false ;
},
generateDeliveryNote: function() {

if(!this.oneOrderSelected()) {
this.selectAllOrders(true) ;
}

if(this.oneOrderSelected()) {
var app = this ;
var idOrders = {} ;
for(var key in this.orders) {
if(this.orders[key].selected == true) {
idOrders[key] = this.orders[key].id ;
}
}
axios.get(UrlManager.getBaseUrlAbsolute()+"distribution/ajax-generate-delivery-note",{params: {
idOrders: JSON.stringify(idOrders)
}})
.then(function(response) {
appAlerts.alertResponse(response) ;
app.init(app.idActivePointSale) ;
}) ;
}
else {
appAlerts.alert('danger','Veuillez sélectionner au moins une commande pour générer un bon de livraison') ;
}

},
deliveryNoteExist: function(idPointSale) {
return typeof this.deliveryNotes[this.idActivePointSale] != 'undefined' ;
}
},
});


+ 180
- 0
backend/web/js/vuejs/document-form.js Целия файл

@@ -0,0 +1,180 @@

/**
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.
*/

var app = new Vue({
el: '#app-document-form',
data: {
taxRateProducer: null,
document: [],
deliveryNotes: [],
idDocument: 0,
typeDocument: '',
idUser: '',
productsArray: [],
productAddId: 0,
productAddPrice: '',
productAddQuantity: 1,
ordersArray: [],
total: 0,
total_with_tax: 0
},
mounted: function() {
this.init() ;
},
methods: {
formatPrice: formatPrice,
init: function() {
if(this.getDocumentId()) {
var app = this ;
axios.get(UrlManager.getBaseUrlAbsolute()+"document/ajax-init",{params: {
idDocument: this.getDocumentId(),
classDocument: this.getDocumentClass()
}})
.then(function(response) {
if(response.data.return == 'success') {
app.document = response.data.document ;
app.taxRateProducer = response.data.tax_rate_producer ;
app.idUser = response.data.id_user ;
app.productsArray = response.data.products ;
app.ordersArray = response.data.orders ;
app.total = response.data.total ;
app.total_with_tax = response.data.total_with_tax ;

if(app.idUser > 0) {
app.changeUser() ;
}
}
}) ;
}
},
getDocumentId: function() {
var documentId = $('#app-document-form').attr('data-id-document') ;
return documentId ;
},
getDocumentClass: function() {
var documentClass = $('#app-document-form').attr('data-class-document') ;
return documentClass ;
},
changeUser: function() {
var app = this ;
axios.get(UrlManager.getBaseUrlAbsolute()+"document/ajax-user-infos",{params: {
idUser: app.idUser,
classDocument: app.getDocumentClass(),
idDocument: app.getDocumentId(),
typeAction: $('#type-action').val(),
}})
.then(function(response) {
if(response.data.return == 'success') {
Vue.set(app.document, 'address', response.data.address);
app.deliveryNotes = response.data.delivery_notes ;
}
else {
app.document.address = '' ;
}
}) ;
},
formatPrice: formatPrice,
validateDocument: function() {
var app = this ;
axios.get(UrlManager.getBaseUrlAbsolute()+"document/ajax-validate-document",{params: {
idDocument: app.getDocumentId(),
classDocument: app.getDocumentClass(),
}})
.then(function(response) {
appAlerts.alertResponse(response) ;
app.init() ;
}) ;
},
getStepProductAdd: function() {
return parseInt(this.productsArray[this.productAddId].step) ;
},
changeProductAdd: function(event) {
var idProduct = event.currentTarget.value ;
this.productAddId = idProduct ;
this.productAddPrice = parseFloat(this.productsArray[idProduct].price_with_tax).toFixed(2) ;
this.productAddQuantity = this.getStepProductAdd() ;
},
changeQuantityProductAdd: function(quantity) {
var step = this.getStepProductAdd() ;
quantity = quantity * step ;
this.productAddQuantity += quantity ;
if(this.productAddQuantity < 1) {
this.productAddQuantity = step ;
}
},
submitProductAdd: function() {
var app = this ;
axios.get(UrlManager.getBaseUrlAbsolute()+"document/ajax-add-product",{params: {
idDocument: this.getDocumentId(),
classDocument: this.getDocumentClass(),
idProduct: app.productAddId,
quantity: app.productAddQuantity,
price: app.productAddPrice,
}})
.then(function(response) {
appAlerts.alertResponse(response) ;
app.productAddId = 0 ;
app.init() ;
}) ;
},
deleteProductOrder: function(idProductOrder) {
var app = this ;
axios.get(UrlManager.getBaseUrlAbsolute()+"document/ajax-delete-product-order",{params: {
idProductOrder: idProductOrder
}})
.then(function(response) {
appAlerts.alertResponse(response) ;
app.init() ;
}) ;
},
formatProductAddPrice: function() {
this.productAddPrice = Number(this.productAddPrice).toFixed(2).replace(',', '.');
if(isNaN(this.productAddPrice)) {
this.productAddPrice = 0 ;
}
},
formatProductAddQuantity: function() {
this.productAddQuantity = parseInt(this.productAddQuantity) ;
if(isNaN(this.productAddQuantity)) {
this.productAddQuantity = 1 ;
}
}
}
});



+ 4
- 0
backend/web/js/vuejs/producer-update.js Целия файл

@@ -63,6 +63,10 @@ var app = new Vue({
{
name: 'logiciels-caisse',
nameDisplay: 'Logiciels de caisse'
},
{
name: 'facturation',
nameDisplay: 'Facturation'
}
]
},

+ 1
- 16
backend/web/js/vuejs/subscription-form.js Целия файл

@@ -40,8 +40,7 @@ var app = new Vue({
data: {
showLoading: false,
loading: true,
products: [],
units: []
products: []
},
mounted: function() {
@@ -57,23 +56,9 @@ var app = new Vue({
axios.get("ajax-infos",{params: {idSubscription: $('#subscriptionform-id').val()}})
.then(function(response) {
app.products = response.data.products ;
app.units = response.data.units ;
app.showLoading = false ;
}) ;
},
changeUnitProductSubscription: function(event) {
for(var i = 0; i < this.products.length ; i++) {
if(this.products[i].id == event.currentTarget.getAttribute('data-id-product')) {
this.products[i].quantity = '' ;
for(var j = 0; j < this.products[i].units.length ; j ++) {
if(this.products[i].unit == this.products[i].units[j].unit) {
this.products[i].step = this.products[i].units[j].step ;
this.products[i].price = this.products[i].units[j].price ;
}
}
}
}
},
changeQuantityProductSubscription: function(increase, product) {
var step = step ? parseFloat(product.step) : 1 ;
if(!product.quantity) product.quantity = 0 ;

+ 49
- 0
backend/web/js/vuejs/user-form.js Целия файл

@@ -0,0 +1,49 @@

/**
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.
*/

var app = new Vue({
el: '#app-user-form',
data: {
type: $('#user-type').val(),
},
mounted: function() {
},
methods: {
}
});



+ 20
- 0
backend/web/sass/_alerts.scss Целия файл

@@ -0,0 +1,20 @@

#app-alerts {
position: fixed ;
bottom: 30px ;
right: 15px ;
width: 300px ;
height: auto ;

.slide-fade-enter-active {
@include transition(all .3s ease);
}
.slide-fade-leave-active {
@include transition(all .3s cubic-bezier(1.0, 0.5, 0.8, 1.0));
}
.slide-fade-enter, .slide-fade-leave-to {
@include transform(translateX(10px));
opacity: 0;
}
}


+ 23
- 3
backend/web/sass/distribution/_index.scss Целия файл

@@ -200,7 +200,22 @@ termes.
}
}
}

#buttons-top-orders {
background-color: #F5F5F5 ;
padding: 10px 20px ;
border: solid 1px #e0e0e0 ;
@include border-radius(5px) ;
margin-bottom: 20px ;

.left {

}

.right {
float: right ;
}
}
table {
@@ -217,9 +232,14 @@ termes.
}
td.column-actions {
position: relative ;
text-align: right ;
width: 230px ;

.dropdown-menu {
top: 0px ;
right: 0px ;
}

.modal-form-order,
.modal-payment {
text-align: left ;

+ 43
- 0
backend/web/sass/document/_form.scss Целия файл

@@ -0,0 +1,43 @@

.document-form {
.info-box {
.info-box-text {
font-size: 13px ;
}
.info-box-number {
font-size: 15px ;
}
}
#block-add-product {
.input-price {
text-align: center ;
}
.input-group-quantity {
.input-quantity {
text-align: center ;
}
}

.total {
.input-group {
margin-bottom: 10px ;
}
.btn {
float: right ;
}
}
}

#block-list-products {
ul.product-order-meta {
padding: 0px ;
margin: 0px ;
padding-left: 20px ;

li {
color: gray ;
font-size: 11px ;
}
}
}
}

+ 12
- 0
backend/web/sass/document/_index.scss Целия файл

@@ -0,0 +1,12 @@

.quotation-index,
.delivery-note-index,
.invoice-index {
.content-wrapper .content {
table.table {
.column-actions {
width: 200px;
}
}
}
}

+ 110
- 0
backend/web/sass/document/download.scss Целия файл

@@ -0,0 +1,110 @@

$font-family: 'Source Sans Pro','Helvetica Neue',Helvetica,Arial,sans-serif ;
$border-color: #c0c0c0 ;

.document-download {
font-family: $font-family ;

#block-addresses {
.producer {
text-align: left ;
margin-bottom: 20px ;

.logo {
margin-bottom: 20px ;
}
.address {

}
}
.user {
text-align: right ;
}
}

#block-infos-document {
padding-top: 30px ;

.date {
padding-bottom: 10px ;
}
.reference {
padding-bottom: 10px ;
font-size: 15px ;
font-weight: bold ;

.block-is-draft {
border: solid 2px black ;
padding: 10px ;
text-transform: uppercase ;
}
}
.name {

}
}

#block-no-product {
font-weight: bold ;
border: solid 2px black ;
text-transform: uppercase ;
padding: 10px ;
}

#block-products {
padding-top: 20px ;

table {
width: 100% ;
padding: 0px ;
margin: 0px ;
border-bottom: solid 1px $border-color ;
border-right: solid 1px $border-color ;
border-collapse: collapse ;

td, th {
padding: 5px ;
border-top: solid 1px $border-color ;
border-left: solid 1px $border-color ;
font-family: $font-family ;

&.align-left {
text-align: left ;
}
&.align-center {
text-align: center ;
}
&.align-right {
text-align: right ;
}
}
}
}

.block-infos {
margin-top: 20px ;
padding: 10px ;
border: solid 1px $border-color ;

strong {
font-size: 12px ;
}
}
}

#footer {
font-family: $font-family ;
text-align: center ;
padding-top: 20px ;
border-top: solid 1px gray ;

.infos-bottom {
padding-bottom: 20px ;
margin-bottom: 40px ;
font-size: 12px ;
line-height: 18px ;
}
.reference-document {
font-weight: bold ;
}
}

+ 4
- 1
backend/web/sass/screen.scss Целия файл

@@ -1468,6 +1468,7 @@ a.btn, button.btn {
}

@import "_adminlte.scss" ;
@import "_alerts.scss" ;
@import "site/_index.scss" ;
@import "subscription/_index.scss" ;
@import "subscription/_form.scss" ;
@@ -1480,4 +1481,6 @@ a.btn, button.btn {
@import "user/_form.scss" ;
@import "producer/_update.scss" ;
@import "point_sale/_index.scss" ;
@import "report/_index.scss" ;
@import "report/_index.scss" ;
@import "document/_form.scss" ;
@import "document/_index.scss" ;

+ 1
- 0
common/assets/CommonAsset.php Целия файл

@@ -71,5 +71,6 @@ class CommonAsset extends \common\components\MyAssetBundle
$this->addAsset('js','js/axios/axios.min.js');
$this->addAsset('js','js/vuejs/vue.js');
$this->addAsset('js','js/vuejs/vcalendar/vcalendar.min.js') ;
$this->addAsset('js','js/utils.js') ;
}
}

+ 194
- 198
common/components/ActiveRecordCommon.php Целия файл

@@ -1,213 +1,209 @@
<?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\components ;
/**
* 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\components;

use common\helpers\GlobalParam;

class ActiveRecordCommon extends \yii\db\ActiveRecord
{
const SEARCH_ALL = 'all' ;
const SEARCH_ONE = 'one' ;
const SEARCH_COUNT = 'count' ;
/**
* Méthode générique de recherche utilisée pour tous les modèles. Elle a
* pour but de construire la requête et de retourner le résultat.
*
* @param array $params
* @param array $options
* @return mixed
* @throws NotFoundHttpException
*/
public static function searchBy($params = [], $options = [])
{
$class = get_called_class() ;
if(is_callable([$class, 'defaultOptionsSearch'])) {
$default_options = $class::defaultOptionsSearch() ;
}
else {
throw new \ErrorException('La méthode "defaultOptionsSearch" n\'est '
. 'pas définie dans la classe "'.$class.'"');
}
$options = array_merge($default_options, $options) ;
$pk = $class::primaryKey() ;
$pk = $class::tableName().'.'.$pk[0] ;
if (isset($options['attribute_id_producer']) && strlen($options['attribute_id_producer'])
&& !isset($params[$options['attribute_id_producer']]) && !Yii::$app->user->isGuest)
const SEARCH_ALL = 'all';
const SEARCH_ONE = 'one';
const SEARCH_COUNT = 'count';

/**
* Méthode générique de recherche utilisée pour tous les modèles. Elle a
* pour but de construire la requête et de retourner le résultat.
*
* @param array $params
* @param array $options
* @return mixed
* @throws NotFoundHttpException
*/
public static function searchBy($params = [], $options = [])
{
$params[$options['attribute_id_producer']] = Producer::getId() ;
}
if(!isset($options['type_search'])) {
$options['type_search'] = self::SEARCH_ALL ;
}
$records = $class::find() ;
// With
if(is_array($options['with']) && count($options['with'])) {
$records = $records->with($options['with']) ;
}
// Join with
if(is_array($options['join_with']) && count($options['join_with'])) {
$records = $records->joinWith($options['join_with']) ;
}
// Conditions
if(isset($options['conditions'])) {
if(is_array($options['conditions'])) {
if(count($options['conditions'])) {
foreach($options['conditions'] as $condition) {
$records = $records->andWhere($condition);
}
$class = get_called_class();

if (is_callable([$class, 'defaultOptionsSearch'])) {
$default_options = $class::defaultOptionsSearch();
} else {
throw new \ErrorException('La méthode "defaultOptionsSearch" n\'est '
. 'pas définie dans la classe "' . $class . '"');
}

$options = array_merge($default_options, $options);

$pk = $class::primaryKey();
$pk = $class::tableName() . '.' . $pk[0];

if (isset($options['attribute_id_producer']) && strlen($options['attribute_id_producer'])
&& !isset($params[$options['attribute_id_producer']]) && !Yii::$app->user->isGuest) {
$params[$options['attribute_id_producer']] = GlobalParam::getCurrentProducerId();
}
}
else {
if(strlen($options['conditions'])) {
$records = $records->andWhere($options['conditions']);

if (!isset($options['type_search'])) {
$options['type_search'] = self::SEARCH_ALL;
}
}
}
// Params
if(isset($options['params']) && is_array($options['params']) && count($options['params'])) {
$records = $records->params($options['params']) ;
}
// Paramètres
if(is_array($params) && count($params)) {
foreach($params as $key => $val) {
if(strpos($key, '.') === false) {
unset($params[$key]) ;
$key = $class::tableName().'.'.$key ;
$params[$key] = $val ;

$records = $class::find();

// With
if (is_array($options['with']) && count($options['with'])) {
$records = $records->with($options['with']);
}
$records = $records->andWhere([$key => $val]);
}
}
if(!isset($params[$pk])) {
// Orderby
if (isset($options['orderby']) && strlen($options['orderby'])) {
$records = $records->orderBy($options['orderby']);
}
// Limit
if (isset($options['limit']) && is_numeric($options['limit'])
&& $options['limit'] > 0)
{
$records = $records->limit($options['limit']);
}

// Join with
if (is_array($options['join_with']) && count($options['join_with'])) {
$records = $records->joinWith($options['join_with']);
}

// Conditions
if (isset($options['conditions'])) {
if (is_array($options['conditions'])) {
if (count($options['conditions'])) {
foreach ($options['conditions'] as $condition) {
$records = $records->andWhere($condition);
}
}
} else {
if (strlen($options['conditions'])) {
$records = $records->andWhere($options['conditions']);
}
}
}

// Params
if (isset($options['params']) && is_array($options['params']) && count($options['params'])) {
$records = $records->params($options['params']);
}

// Paramètres
if (is_array($params) && count($params)) {
foreach ($params as $key => $val) {
if (strpos($key, '.') === false) {
unset($params[$key]);
$key = $class::tableName() . '.' . $key;
$params[$key] = $val;
}
$records = $records->andWhere([$key => $val]);
}
}

if (!isset($params[$pk])) {
// Orderby
if (isset($options['orderby']) && strlen($options['orderby'])) {
$records = $records->orderBy($options['orderby']);
}
// Limit
if (isset($options['limit']) && is_numeric($options['limit'])
&& $options['limit'] > 0) {
$records = $records->limit($options['limit']);
}
}

if (isset($options['as_array'])) {
$records = $records->asArray();
}

if ($options['type_search'] == self::SEARCH_ALL) {
return $records->all();
} elseif ($options['type_search'] == self::SEARCH_ONE) {
$record = $records->one();
if ($record) {
return $record;
}
} elseif ($options['type_search'] == self::SEARCH_COUNT) {
return $records->count();
}

return false;
}
if(isset($options['as_array'])) {
$records = $records->asArray() ;

/**
* Recherche un enregistrement.
*
* @param array $params
* @param array $options
* @return mixed
*/
public static function searchOne($params = [], $options = [])
{
$options['type_search'] = self::SEARCH_ONE;
return self::searchDispatch($params, $options);
}
if($options['type_search'] == self::SEARCH_ALL) {
return $records->all();

/**
* Recherche tous les enregistrements.
*
* @param array $params
* @param array $options
* @return mixed
*/
public static function searchAll($params = [], $options = [])
{
$options['type_search'] = self::SEARCH_ALL;
return self::searchDispatch($params, $options);
}
elseif($options['type_search'] == self::SEARCH_ONE) {
$record = $records->one();
if($record) {
return $record ;
}

/**
* Recherche et compte le nombre de résultats.
*
* @param array $params
* @param array $options
* @return integer
*/
public static function searchCount($params = [], $options = [])
{
$options['type_search'] = self::SEARCH_COUNT;
return self::searchDispatch($params, $options);
}
elseif($options['type_search'] == self::SEARCH_COUNT) {
return $records->count() ;

/**
* Appelle la méthode 'search' de la classe appellante.
*
* @param array $params
* @param array $options
* @return mixed
*/
public static function searchDispatch($params = [], $options = [])
{
$class = get_called_class();
return $class::searchBy($params, $options);
}
return false ;
}
/**
* Recherche un enregistrement.
*
* @param array $params
* @param array $options
* @return mixed
*/
public static function searchOne($params = [], $options = [])
{
$options['type_search'] = self::SEARCH_ONE ;
return self::searchDispatch($params, $options) ;
}
/**
* Recherche tous les enregistrements.
*
* @param array $params
* @param array $options
* @return mixed
*/
public static function searchAll($params = [], $options = [])
{
$options['type_search'] = self::SEARCH_ALL ;
return self::searchDispatch($params, $options) ;
}
/**
* Recherche et compte le nombre de résultats.
*
* @param array $params
* @param array $options
* @return integer
*/
public static function searchCount($params = [], $options = [])
{
$options['type_search'] = self::SEARCH_COUNT ;
return self::searchDispatch($params, $options) ;
}
/**
* Appelle la méthode 'search' de la classe appellante.
*
* @param array $params
* @param array $options
* @return mixed
*/
public static function searchDispatch($params = [], $options = [])
{
$class = get_called_class() ;
return $class::searchBy($params, $options) ;
}

}

+ 112
- 109
common/config/main.php Целия файл

@@ -1,116 +1,119 @@
<?php

/**
Copyright distrib (2018)
/**
* 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.
*/

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.
*/

$serverName = $_SERVER['SERVER_NAME'] ;
$serverName = $_SERVER['SERVER_NAME'];

return [
'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
'on beforeRequest' => function () {
if(method_exists(Yii::$app->request, 'getAbsoluteUrl')) {
$url = Yii::$app->request->getAbsoluteUrl();
if ($_SERVER['SERVER_NAME'] != 'localhost' && !empty($url) && substr($url, -1) == '/' && substr($url, -5) != '.net/') {
$url = substr($url, 0, strlen($url) - 1);
Yii::$app->getResponse()->redirect($url, 301);
Yii::$app->end();
}
}
},
'components' => [
'user' => [
'class' => 'yii\web\User',
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
'identityCookie' => [
'name' => 'distrib',
'domain' => (($serverName != 'localhost') ? '.' : '') . Yii::getAlias('@domainName'),
'path' => '/',
]
],
'session' => [
'class' => 'yii\web\Session',
'name' => 'PHPDISTRIBSESSID',
'cookieParams' => [
'domain' => (($serverName != 'localhost') ? '.' : '') . Yii::getAlias('@domainName'),
'httpOnly' => true,
],
],
'cache' => [
'class' => 'yii\caching\FileCache',
],
'image' => [
'class' => 'yii\image\ImageDriver',
'driver' => 'GD', //GD or Imagick
],
'urlManagerProducer' => [
'class' => 'producer\components\UrlManagerProducer',
'subDomain' => Yii::getAlias('@producerSubdomain'),
'domainName' => Yii::getAlias('@domainName'),
'baseUrl' => Yii::getAlias('@baseUrl').Yii::getAlias('@baseUrlProducer'),
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => false,
'rules' => [
'<slug_producer:\w+>' => 'site/index',
'<slug_producer:\w+>/<controller>/<action>' => '<controller>/<action>',
],
],
'urlManagerFrontend' => [
'class' => 'common\components\UrlManagerCommon',
'subDomain' => Yii::getAlias('@frontendSubdomain'),
'domainName' => Yii::getAlias('@domainName'),
'baseUrl' => Yii::getAlias('@baseUrl').Yii::getAlias('@baseUrlFrontend'),
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => false,
'rules' => [
],
],
'urlManagerBackend' => [
'class' => 'common\components\UrlManagerCommon',
'subDomain' => Yii::getAlias('@backendSubdomain'),
'domainName' => Yii::getAlias('@domainName'),
'baseUrl' => Yii::getAlias('@baseUrl').Yii::getAlias('@baseUrlBackend'),
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => false,
'rules' => [
],
'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
'on beforeRequest' => function () {
if (method_exists(Yii::$app->request, 'getAbsoluteUrl')) {
$url = Yii::$app->request->getAbsoluteUrl();
if ($_SERVER['SERVER_NAME'] != 'localhost' && !empty($url) && substr($url, -1) == '/' && substr($url, -5) != '.net/') {
$url = substr($url, 0, strlen($url) - 1);
Yii::$app->getResponse()->redirect($url, 301);
Yii::$app->end();
}
}
},
'components' => [
'assetManager' => [
'linkAssets' => YII_ENV == "dev" ? 'true' : false,
],
'user' => [
'class' => 'yii\web\User',
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
'identityCookie' => [
'name' => 'distrib',
'domain' => (($serverName != 'localhost') ? '.' : '') . Yii::getAlias('@domainName'),
'path' => '/',
]
],
'session' => [
'class' => 'yii\web\Session',
'name' => 'PHPDISTRIBSESSID',
'cookieParams' => [
'domain' => (($serverName != 'localhost') ? '.' : '') . Yii::getAlias('@domainName'),
'httpOnly' => true,
],
],
'cache' => [
'class' => 'yii\caching\FileCache',
],
'image' => [
'class' => 'yii\image\ImageDriver',
'driver' => 'GD', //GD or Imagick
],
'urlManagerProducer' => [
'class' => 'producer\components\UrlManagerProducer',
'subDomain' => Yii::getAlias('@producerSubdomain'),
'domainName' => Yii::getAlias('@domainName'),
'baseUrl' => Yii::getAlias('@baseUrl') . Yii::getAlias('@baseUrlProducer'),
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => false,
'rules' => [
'<slug_producer:\w+>' => 'site/index',
'<slug_producer:\w+>/<controller>/<action>' => '<controller>/<action>',
],
],
'urlManagerFrontend' => [
'class' => 'common\components\UrlManagerCommon',
'subDomain' => Yii::getAlias('@frontendSubdomain'),
'domainName' => Yii::getAlias('@domainName'),
'baseUrl' => Yii::getAlias('@baseUrl') . Yii::getAlias('@baseUrlFrontend'),
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => false,
'rules' => [
],
],
'urlManagerBackend' => [
'class' => 'common\components\UrlManagerCommon',
'subDomain' => Yii::getAlias('@backendSubdomain'),
'domainName' => Yii::getAlias('@domainName'),
'baseUrl' => Yii::getAlias('@baseUrl') . Yii::getAlias('@baseUrlBackend'),
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => false,
'rules' => [
],
],
],
],
'language' => 'fr-FR',
'language' => 'fr-FR',
];

+ 90
- 37
common/config/params.php Целия файл

@@ -1,43 +1,96 @@
<?php

/**
Copyright distrib (2018)
/**
* 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.
*/

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é.
return [
'adminEmail' => 'contact@opendistrib.net',
'supportEmail' => 'contact@opendistrib.net',
'user.passwordResetTokenExpire' => 3600,
'producer' => false,
'orderStatus' => [
'new-order' => [
'name' => 'Nouvelle commande',
'color' => '#14c40e',
'nextStatusAllow' => ['waiting-paiement-on-delivery', 'waiting-paiement-by-credit', 'canceled'],
'slug' => 'new-order'
],
'waiting-paiement-on-delivery' => [
'name' => 'En attente de paiement à la livraison',
'color' => '#e19a4d',
'nextStatusAllow' => ['delivered', 'canceled'],
'slug' => 'waiting-paiement-on-delivery'
],
'waiting-paiement-by-credit' => [
'name' => 'En attente de paiement par crédit',
'color' => '#e19a4d',
'nextStatusAllow' => ['paid-by-credit', 'canceled'],
'slug' => 'waiting-paiement-by-credit'
],
'paid-by-credit' => [
'name' => 'Payé par crédit',
'color' => '#3180d5',
'nextStatusAllow' => ['waiting-delivery'],
'slug' => 'paid-by-credit'
],
'waiting-delevery'=>[
'name' => 'En attente de livraison',
'color' => '#d5bb31',
'nextStatusAllow' => ['delivered', 'refunded'],
'slug' => 'new-order'
],
'delivered' => [
'name' => 'Livré',
'color' => '#36d531',
'nextStatusAllow' => [],
'slug' => 'new-order'
],
'refunded' => [
'name' => 'Remboursé',
'color' => '#d01d14',
'nextStatusAllow' => ['canceled'],
'slug' => 'refunded'
],
'cancel' => [
'name' => 'Commande annulée',
'color' => '#d01d14',
'nextStatusAllow' => [],
'slug' => 'cancel'
]

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.
*/
]

return [
'adminEmail' => 'contact@opendistrib.net',
'supportEmail' => 'contact@opendistrib.net',
'user.passwordResetTokenExpire' => 3600,
];

+ 50
- 0
common/helpers/Debug.php Целия файл

@@ -0,0 +1,50 @@
<?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\helpers;

class Debug {
public static function dump($value)
{
echo '<pre>';
var_dump($value);
echo '</pre>';
}
}

+ 84
- 0
common/helpers/GlobalParam.php Целия файл

@@ -0,0 +1,84 @@
<?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\helpers;

use common\models\Producer;

class GlobalParam
{

public function get($key)
{
if($key == 'producer'){
return $this->getCurrentProducer();
}else{

return \Yii::$app->params[$key];
}
}

public static function getCurrentProducer()
{
if(\Yii::$app->params['producer'] == false){
\Yii::$app->params['producer'] = Producer::searchOne();
}
return \Yii::$app->params['producer'];
}

/**
* Retourne l'ID du producteur courant.
*
* @return integer|boolean
*/
public static function getCurrentProducerId()
{
if(\Yii::$app->controller->module->id == 'app-backend') {
if(!\Yii::$app->user->isGuest) {
return Yii::$app->user->identity->id_producer ;
}
}
else {
return \Yii::$app->controller->getProducer()->id;
}

return false ;
}


}

+ 50
- 39
common/helpers/Price.php Целия файл

@@ -1,48 +1,59 @@
<?php

/**
Copyright distrib (2018)
/**
* 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.
*/

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".
namespace common\helpers;

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.
class Price
{

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é.
public static function format($number)
{
return str_replace('.', ',',number_format($number, 2)) . ' €';
}

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.
*/
public static function getPrice($priceWithTax, $taxRate)
{
return round(floatval($priceWithTax) / ($taxRate + 1), 2);
}

namespace common\helpers;
public static function getPriceWithTax($priceWithoutTax, $taxRate)
{
return round(floatval($priceWithoutTax) * ($taxRate + 1), 2);
}

class Price {
public static function format($number)
{
return number_format($number, 2).' €' ;
}
}

+ 1
- 1
common/helpers/Tiller.php Целия файл

@@ -87,7 +87,7 @@ class Tiller
$ordersOpendistribSynchro[$orderOpendistrib->id] = false ;
foreach($ordersTiller->orders as $orderTiller) {
if($orderOpendistrib->id == $orderTiller->externalId
&& ($orderOpendistrib->getAmount(Order::AMOUNT_TOTAL) * 100) == $orderTiller->currentBill) {
&& ($orderOpendistrib->getAmountWithTax(Order::AMOUNT_TOTAL) * 100) == $orderTiller->currentBill) {

$ordersOpendistribSynchro[$orderOpendistrib->id] = true ;
}

+ 47
- 0
common/mail/sendDocument-html.php Целия файл

@@ -0,0 +1,47 @@
<?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.
*/

use yii\helpers\Html;

?>

<p>Bonjour <?= Html::encode($document->user->name); ?>,</p>

<p>Veuillez trouver en pièce jointe votre <?= strtolower($document->getType()) ?> <?php if($document->isStatusValid()): ?>N°<?= $document->reference ?><?php endif; ?>.</p>

<p>À bientôt.</p>

+ 45
- 0
common/mail/sendDocument-text.php Целия файл

@@ -0,0 +1,45 @@
<?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.
*/

?>

Bonjour <?= $document->user->name ?>,

Veuillez trouver en pièce jointe votre <?= strtolower($document->getType()) ?> <?php if($document->isStatusValid()): ?>N°<?= $document->reference ?><?php endif; ?>.

À bientôt.

+ 1
- 1
common/models/CreditHistory.php Целия файл

@@ -328,7 +328,7 @@ class CreditHistory extends ActiveRecordCommon
}
$str .= $this->getStrWording() ;
if(isset($this->order)) {
$str .= '<br />Montant de la commande : '.$this->order->getAmount(Order::AMOUNT_TOTAL, true) ;
$str .= '<br />Montant de la commande : '.$this->order->getAmountWithTax(Order::AMOUNT_TOTAL, true) ;
}
if(isset($this->user)) {
$str .= '<br />Client : '.Html::encode($this->user->name. ' '.$this->user->lastname) ;

+ 2
- 1
common/models/CreditHistorySearch.php Целия файл

@@ -38,6 +38,7 @@ termes.

namespace common\models ;

use common\helpers\GlobalParam;
use common\models\CreditHistory ;

class CreditHistorySearch extends CreditHistory
@@ -60,7 +61,7 @@ class CreditHistorySearch extends CreditHistory
$query = CreditHistory::find()
->with($optionsSearch['with'])
->innerJoinWith($optionsSearch['join_with'], true)
->where(['credit_history.id_producer' => Producer::getId()])
->where(['credit_history.id_producer' => GlobalParam::getCurrentProducerId()])
->orderBy('id DESC')
;

+ 93
- 0
common/models/DeliveryNote.php Целия файл

@@ -0,0 +1,93 @@
<?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\components\ActiveRecordCommon;
use Yii;

/**
* This is the model class for table "delivery_note".
*
* @property integer $id
* @property string $name
* @property string $reference
* @property string $date
* @property string $comment
* @property integer $id_point_sale_distribution
* @property integer $id_user
* @property string $address
* @property string $city
* @property string $postcode
*/
class DeliveryNote extends Document
{

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

/*
* Relations
*/

public function getOrders()
{
return $this->relationOrders('id_delivery_note') ;
}

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

}

+ 95
- 0
common/models/DeliveryNoteSearch.php Целия файл

@@ -0,0 +1,95 @@
<?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;

class DeliveryNoteSearch extends DeliveryNote
{
public $id_point_sale ;
public $date_distribution ;

public function rules()
{
return [
[[], 'safe'],
[['comment', 'address', 'status', 'date_distribution'], 'string'],
[['id_user', 'id_point_sale'], 'integer'],
[['name', 'reference'], 'string', 'max' => 255],
];
}

public function search($params)
{
$optionsSearch = self::defaultOptionsSearch();

$query = DeliveryNote::find()
->with($optionsSearch['with'])
->where(['delivery_note.id_producer' => GlobalParam::getCurrentProducerId()])
->orderBy('delivery_note.status ASC, delivery_note.reference DESC');

$dataProvider = new ActiveDataProvider([
'query' => $query,
'sort' => ['attributes' => ['name', 'reference', 'date']],
'pagination' => [
'pageSize' => 20,
],
]);

$this->load($params);
if (!$this->validate()) {
return $dataProvider;
}

$query->andFilterWhere(['like', 'delivery_note.name', $this->name]);
$query->andFilterWhere(['like', 'delivery_note.reference', $this->reference]);
$query->andFilterWhere(['like', 'delivery_note.status', $this->status]);

if($this->id_point_sale) {
$query->andWhere(['order.id_point_sale' => $this->id_point_sale]);
}

if($this->date_distribution && strlen($this->date_distribution)) {
$query->andFilterWhere(['like', 'distribution.date', date('Y-m-d',strtotime(str_replace('/','-',$this->date_distribution)))]);
}

return $dataProvider;
}
}

+ 2
- 1
common/models/Development.php Целия файл

@@ -38,6 +38,7 @@ termes.

namespace common\models;

use common\helpers\GlobalParam;
use Yii;
use common\components\ActiveRecordCommon ;
use common\models\DeveloppementPriorite;
@@ -101,7 +102,7 @@ class Development extends ActiveRecordCommon
return $this->hasOne(
DevelopmentPriority::className(),
['id_development' => 'id'])
->where(['id_producer' => Producer::getId()])
->where(['id_producer' => GlobalParam::getCurrentProducerId()])
->with('producer');
}


+ 332
- 333
common/models/Distribution.php Целия файл

@@ -1,45 +1,46 @@
<?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.
*/
/**
* 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 common\components\ActiveRecordCommon ;
use common\components\ActiveRecordCommon;
use common\models\Order;
use common\models\Distribution;

@@ -50,320 +51,318 @@ use common\models\Distribution;
* @property string $date
* @property integer $active
*/
class Distribution extends ActiveRecordCommon
class Distribution extends ActiveRecordCommon
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'distribution';
}

public function getProducer()
{
return $this->hasOne(Producer::className(), ['id' => 'id_producer']);
}

/**
* @inheritdoc
*/
public function rules()
{
return [
[['date'], 'required'],
[['date'], 'safe'],
[['active'], 'integer']
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'date' => 'Date',
'active' => 'Actif',
];
}

/*
* Relations
*/
public function getOrder()
{
return $this->hasMany(Order::className(), ['id_distribution' => 'id']);
}

public function getProductDistribution()
{
return $this->hasMany(ProductDistribution::className(), ['id_distribution' => 'id']);
}
/**
* Retourne les options de base nécessaires à la fonction de recherche.
*
* @return array
*/
public static function defaultOptionsSearch() {
return [
'with' => [],
'join_with' => [],
'orderby' => 'date ASC',
'attribute_id_producer' => 'distribution.id_producer'
] ;
}

/**
* Retourne si un produit est actif ou non.
*
* @param integer $idProduit
* @return boolean
*/
public function isActiveProduct($idProduit)
{
if ($idProduit &&
isset($this->productDistribution) &&
count($this->productDistribution) > 0)
/**
* @inheritdoc
*/
public static function tableName()
{
return 'distribution';
}

foreach ($this->productDistribution as $productDistribution) {
if ($productDistribution['id_product'] == $idProduct &&
$productDistribution['active'])
{
return true;
}
}
public function getProducer()
{
return $this->hasOne(Producer::className(), ['id' => 'id_producer']);
}

/**
* @inheritdoc
*/
public function rules()
{
return [
[['date'], 'required'],
[['date'], 'safe'],
[['active'], 'integer']
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'date' => 'Date',
'active' => 'Actif',
];
}

return false;
}
/**
* Initialise un jour de production.
*
* @param string $date
* @return Production
*/
public static function initDistribution($date, $idProducer = 0)
{
$distribution = null ;
if ($date != '') {
$paramsDistribution = [
'date' => $date
] ;
if($idProducer) {
$paramsDistribution['distribution.id_producer'] = (int) $idProducer ;
}
else {
$idProducer = Producer::getId() ;
}
$distribution = Distribution::searchOne($paramsDistribution) ;
if (!$distribution) {
$distribution = new Distribution;
$distribution->date = $date;
$distribution->delivery = 1;
$distribution->id_producer = $idProducer ;
$distribution->save();
}
/*
* Relations
*/

public function getOrder()
{
return $this->hasMany(Order::className(), ['id_distribution' => 'id']);
}

// point_sale_distribution à définir s'ils ne sont pas initialisés
if ($distribution) {
$countPointSaleDistribution = PointSaleDistribution::searchCount([
'id_distribution' => $distribution->id
]) ;
if (!$countPointSaleDistribution) {
PointSaleDistribution::setAll($distribution->id, true);
}
public function getProductDistribution()
{
return $this->hasMany(ProductDistribution::className(), ['id_distribution' => 'id']);
}
// init produits sélectionnés pour cette production
$products = Product::searchAll();
if ($distribution) {
$productsDistribution = ProductDistribution::searchAll([
'id_distribution' => $distribution->id
]) ;
if (!count($productsDistribution)) {
foreach ($products as $product) {
$distribution->linkProduct($product) ;

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

/**
* Retourne si un produit est actif ou non.
*
* @param integer $idProduit
* @return boolean
*/
public function isActiveProduct($idProduit)
{
if ($idProduit &&
isset($this->productDistribution) &&
count($this->productDistribution) > 0) {

foreach ($this->productDistribution as $productDistribution) {
if ($productDistribution['id_product'] == $idProduit &&
$productDistribution['active']) {
return true;
}
}
}
}
$distribution->linkProductGift() ;
return false;
}
return $distribution ;
}
/**
* Retourne les distributions futures.
*
* @return array
*/
public static function getIncomingDistributions()
{
$distributionsArray = Distribution::find()
->where('date > \'' . date('Y-m-d').'\'')
->andWhere([
'id_producer' => Producer::getId(),
'active' => 1
])
->orderBy('date ASC')
->all();
return $distributionsArray ;
}
/**
* Lie un produit aux jours de distribution futurs.
*
* @param Product $product
*/
public static function linkProductIncomingDistributions($product)
{
$distributionsArray = self::getIncomingDistributions() ;
foreach ($distributionsArray as $distribution) {
$distribution->linkProduct($product) ;

/**
* Initialise un jour de production.
*
* @param string $date
* @return Production
*/
public static function initDistribution($date, $idProducer = 0)
{
$distribution = null;
if ($date != '') {

$paramsDistribution = [
'date' => $date
];
if ($idProducer) {
$paramsDistribution['distribution.id_producer'] = (int)$idProducer;
} else {
$idProducer = GlobalParam::getCurrentProducerId();
}

$distribution = Distribution::searchOne($paramsDistribution);

if (!$distribution) {
$distribution = new Distribution;
$distribution->date = $date;
$distribution->delivery = 1;
$distribution->id_producer = $idProducer;
$distribution->save();
}
}

// point_sale_distribution à définir s'ils ne sont pas initialisés
if ($distribution) {

$countPointSaleDistribution = PointSaleDistribution::searchCount([
'id_distribution' => $distribution->id
]);

if (!$countPointSaleDistribution) {
PointSaleDistribution::setAll($distribution->id, true);
}
}

// init produits sélectionnés pour cette production
$products = Product::searchAll();

if ($distribution) {
$productsDistribution = ProductDistribution::searchAll([
'id_distribution' => $distribution->id
]);
if (!count($productsDistribution)) {
foreach ($products as $product) {
$distribution->linkProduct($product);
}
}
$distribution->linkProductGift();
}

return $distribution;
}
}
/**
* Lie un produit à la distribution.
*
* @param Product $product
*/
public function linkProduct($product)
{
$productDistribution = ProductDistribution::searchOne([
'id_distribution' => $this->id,
'id_product' => $product->id
]) ;

if(!$productDistribution) {
$productDistribution = new ProductDistribution();
$productDistribution->id_distribution = $this->id;
$productDistribution->id_product = $product->id;
/**
* Retourne les distributions futures.
*
* @return array
*/
public static function getIncomingDistributions()
{
$distributionsArray = Distribution::find()
->where('date > \'' . date('Y-m-d') . '\'')
->andWhere([
'id_producer' => GlobalParam::getCurrentProducerId(),
'active' => 1
])
->orderBy('date ASC')
->all();
return $distributionsArray;
}
$productDistribution->quantity_max = $product->quantity_max;
$dayDistribution = date('N', strtotime($this->date));
$daysArray = [
1 => 'monday',
2 => 'tuesday',
3 => 'wednesday',
4 => 'thursday',
5 => 'friday',
6 => 'saturday',
7 => 'sunday',
] ;
$productDistribution->active = 0;
$day = $daysArray[$dayDistribution] ;
if($product->active && $product->$day) {
$productDistribution->active = 1;

/**
* Lie un produit aux jours de distribution futurs.
*
* @param Product $product
*/
public static function linkProductIncomingDistributions($product)
{
$distributionsArray = self::getIncomingDistributions();
foreach ($distributionsArray as $distribution) {
$distribution->linkProduct($product);
}
}

$productDistribution->save();
return $productDistribution ;
}
/**
* Lie le produit "Don" à la distribution
*/
public function linkProductGift()
{
$productGift = Product::getProductGift() ;
if($productGift) {
$productDistribution = ProductDistribution::searchOne([
'id_distribution' => $this->id,
'id_product' => $productGift->id
]) ;

if(!$productDistribution) {
$productDistribution = new ProductDistribution();
$productDistribution->id_distribution = $this->id;
$productDistribution->id_product = $productGift->id;
$productDistribution->active = 1;
$productDistribution->save() ;
}
/**
* Lie un produit à la distribution.
*
* @param Product $product
*/
public function linkProduct($product)
{
$productDistribution = ProductDistribution::searchOne([
'id_distribution' => $this->id,
'id_product' => $product->id
]);

if (!$productDistribution) {
$productDistribution = new ProductDistribution();
$productDistribution->id_distribution = $this->id;
$productDistribution->id_product = $product->id;
}

$productDistribution->quantity_max = $product->quantity_max;

$dayDistribution = date('N', strtotime($this->date));
$daysArray = [
1 => 'monday',
2 => 'tuesday',
3 => 'wednesday',
4 => 'thursday',
5 => 'friday',
6 => 'saturday',
7 => 'sunday',
];

$productDistribution->active = 0;
$day = $daysArray[$dayDistribution];
if ($product->active && $product->$day) {
$productDistribution->active = 1;
}

$productDistribution->save();

return $productDistribution;
}
}
/**
* Lie un point de vente aux jours de distribution futurs.
*
* @param PointSale $pointSale
*/
public static function linkPointSaleIncomingDistributions($pointSale)
{
$distributionsArray = self::getIncomingDistributions() ;
foreach ($distributionsArray as $distribution) {
$distribution->linkPointSale($pointSale) ;

/**
* Lie le produit "Don" à la distribution
*/
public function linkProductGift()
{
$productGift = Product::getProductGift();

if ($productGift) {
$productDistribution = ProductDistribution::searchOne([
'id_distribution' => $this->id,
'id_product' => $productGift->id
]);

if (!$productDistribution) {
$productDistribution = new ProductDistribution();
$productDistribution->id_distribution = $this->id;
$productDistribution->id_product = $productGift->id;
$productDistribution->active = 1;
$productDistribution->save();
}
}
}
}
/**
*
* @param type $pointSale
*/
public function linkPointSale($pointSale)
{
$pointSaleDistribution = PointSaleDistribution::searchOne([
'id_distribution' => $this->id,
'id_point_sale' => $pointSale->id
]) ;
if(!$pointSaleDistribution) {
$pointSaleDistribution = new PointSaleDistribution();
$pointSaleDistribution->id_distribution = $this->id;
$pointSaleDistribution->id_point_sale = $pointSale->id;

/**
* Lie un point de vente aux jours de distribution futurs.
*
* @param PointSale $pointSale
*/
public static function linkPointSaleIncomingDistributions($pointSale)
{
$distributionsArray = self::getIncomingDistributions();
foreach ($distributionsArray as $distribution) {
$distribution->linkPointSale($pointSale);
}
}
$dayDistribution = date('N', strtotime($this->date));
$daysArray = [
1 => 'monday',
2 => 'tuesday',
3 => 'wednesday',
4 => 'thursday',
5 => 'friday',
6 => 'saturday',
7 => 'sunday',
] ;
$pointSaleDistribution->delivery = 0 ;
$deliveryDay = 'delivery_'.$daysArray[$dayDistribution] ;
if($pointSale->$deliveryDay) {
$pointSaleDistribution->delivery = 1;

/**
*
* @param type $pointSale
*/
public function linkPointSale($pointSale)
{
$pointSaleDistribution = PointSaleDistribution::searchOne([
'id_distribution' => $this->id,
'id_point_sale' => $pointSale->id
]);

if (!$pointSaleDistribution) {
$pointSaleDistribution = new PointSaleDistribution();
$pointSaleDistribution->id_distribution = $this->id;
$pointSaleDistribution->id_point_sale = $pointSale->id;
}

$dayDistribution = date('N', strtotime($this->date));
$daysArray = [
1 => 'monday',
2 => 'tuesday',
3 => 'wednesday',
4 => 'thursday',
5 => 'friday',
6 => 'saturday',
7 => 'sunday',
];

$pointSaleDistribution->delivery = 0;
$deliveryDay = 'delivery_' . $daysArray[$dayDistribution];
if ($pointSale->$deliveryDay) {
$pointSaleDistribution->delivery = 1;
}

$pointSaleDistribution->save();
}
$pointSaleDistribution->save() ;
}

/**
* Active ou désactive la distribution.
*/
public function active($active = true)
{
PointSaleDistribution::setAll($this->id, true);
$this->active = (int) $active ;
$this->save() ;

if ($active) {
// ajout des abonnements
Subscription::addAll($this->date);

/**
* Active ou désactive la distribution.
*/
public function active($active = true)
{
PointSaleDistribution::setAll($this->id, true);
$this->active = (int)$active;
$this->save();

if ($active) {
// ajout des abonnements
Subscription::addAll($this->date);
}
}
}

}

+ 357
- 0
common/models/Document.php Целия файл

@@ -0,0 +1,357 @@
<?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;

class Document extends ActiveRecordCommon
{
const STATUS_DRAFT = 'draft';
const STATUS_VALID = 'valid';

/**
* @inheritdoc
*/
public function rules()
{
return [
[['name', 'id_user'], 'required'],
[['date'], 'safe'],
[['comment', 'address'], 'string'],
[['id_user', 'id_producer'], 'integer'],
[['name', 'reference', 'status'], 'string', 'max' => 255],
[['deliveryNotes'], 'safe']
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'name' => 'Nom',
'reference' => 'Référence',
'date' => 'Date',
'comment' => 'Commentaire',
'id_user' => 'Utilisateur',
'address' => 'Adresse',
'id_producer' => 'Producteur',
'status' => 'Statut',
];
}

/*
* 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 relationOrders($fieldIdDocument)
{
$defaultOptionsSearch = Order::defaultOptionsSearch();

return $this->hasMany(Order::className(), [$fieldIdDocument => 'id'])
->with($defaultOptionsSearch['with'])
->joinWith($defaultOptionsSearch['join_with']);
}


/*
* Méthodes
*/

public function getAmount($type = Order::AMOUNT_TOTAL, $format = false)
{
return $this->_getAmountGeneric($type, false, $format);
}

public function getAmountWithTax($type = Order::AMOUNT_TOTAL, $format = false)
{
return $this->_getAmountGeneric($type, true, $format);
}

protected function _getAmountGeneric($type = Order::AMOUNT_TOTAL, $withTax = true, $format = false)
{
$amount = 0;
$ordersArray = $this->orders;

foreach ($ordersArray as $order) {
$order->init();
if ($withTax) {
$amount += $order->getAmountWithTax($type);
} else {
$amount += $order->getAmount($type);
}
}

if ($format) {
return Price::format($amount);
} else {
return $amount;
}
}

public function getPointSale()
{
if (isset($this->orders) && isset($this->orders[0])) {
return $this->orders[0]->pointSale;
} else {
return '';
}
}

public function getDistribution()
{
if (isset($this->orders) && isset($this->orders[0])) {
return $this->orders[0]->distribution;
} else {
return '';
}
}

public function getClass()
{
return str_replace('common\models\\', '', get_class($this));
}

public function getType()
{
$class = $this->getClass();

if ($class == 'Invoice') {
$documentType = 'Facture';
} elseif ($class == 'DeliveryNote') {
$documentType = 'Bon de livraison';
} elseif ($class == 'Quotation') {
$documentType = 'Devis';
}

if (isset($documentType)) {
return $documentType;
}

return '';
}

public function isValidClass($typeDocument)
{
return in_array($typeDocument, ['Invoice', 'DeliveryNote', 'Quotation']);
}

public function generateReference()
{
$class = $this->getClass();
$classLower = strtolower($class);
if ($classLower == 'deliverynote') {
$classLower = 'delivery_note';
}

$prefix = Producer::getConfig('document_' . $classLower . '_prefix');
$oneDocumentExist = $class::searchOne([], ['orderby' => 'reference DESC']);

if ($oneDocumentExist) {
$reference = $oneDocumentExist->reference;
$pattern = '#([A-Z]+)?([0-9]+)#';
preg_match($pattern, $reference, $matches, PREG_OFFSET_CAPTURE);
$sizeNumReference = strlen($matches[2][0]);
$numReference = ((int)$matches[2][0]) + 1;
$numReference = str_pad($numReference, $sizeNumReference, '0', STR_PAD_LEFT);

return $prefix . $numReference;
} else {
$firstReference = Producer::getConfig('document_' . $classLower . '_first_reference');

if (strlen($firstReference) > 0) {
return $firstReference;
} else {
return $prefix . '00001';
}
}
}

public function generatePdf($destination)
{
$producer = GlobalParam::getCurrentProducer();
$content = Yii::$app->controller->renderPartial('/document/download', [
'producer' => $producer,
'document' => $this
]);

$contentFooter = '<div id="footer">';
$contentFooter .= '<div class="infos-bottom">' . Html::encode($producer->document_infos_bottom) . '</div>';
if ($this->isStatusValid() || $this->isStatusDraft()) {
$contentFooter .= '<div class="reference-document">';
if ($this->isStatusValid()) {
$contentFooter .= $this->getType() . ' N°' . $this->reference;
}
if ($this->isStatusDraft()) {
$contentFooter .= $this->getType() . ' non validé';
if($this->getType() == 'Facture') {
$contentFooter .= 'e' ;
}
}
$contentFooter .= '</div>';
}
$contentFooter .= '</div>';

$pdf = new Pdf([
'mode' => Pdf::MODE_UTF8,
'format' => Pdf::FORMAT_A4,
'orientation' => Pdf::ORIENT_PORTRAIT,
'destination' => $destination,
'content' => $content,
'filename' => $this->getFilename(),
'cssFile' => Yii::getAlias('@webroot/css/document/download.css'),
'methods' => [
'SetHTMLFooter' => $contentFooter
]
]);

return $pdf->render();
}

public function send()
{
$producer = GlobalParam::getCurrentProducer();

$subjectEmail = $this->getType() ;
if($this->isStatusValid()) {
$subjectEmail .= ' N°'.$this->reference ;
}

$email = Yii::$app->mailer->compose(
[
'html' => 'sendDocument-html',
'text' => 'sendDocument-text'
], [
'document' => $this,
])
->setTo($this->user->email)
->setFrom([$producer->getEmailOpendistrib() => $producer->name])
->setSubject('['.$producer->name.'] '.$subjectEmail) ;

$this->generatePdf(Pdf::DEST_FILE) ;
$email->attach($this->getFilename());

return $email->send() ;
}

public function changeStatus($status)
{
if ($status == Document::STATUS_VALID) {
$this->status = $status;
$this->reference = $this->generateReference();
}
}

public function getStatusWording()
{
return ($this->status == self::STATUS_DRAFT) ? 'Brouillon' : 'Validé';
}

public function getStatusCssClass()
{
return ($this->status == self::STATUS_DRAFT) ? 'default' : 'success';
}

public function getHtmlLabel()
{
$label = $this->getStatusWording();
$classLabel = $this->getStatusCssClass();
return '<span class="label label-' . $classLabel . '">' . $label . '</span>';
}

public function isStatus($status)
{
return $this->status == $status;
}

public function isStatusDraft()
{
return $this->isStatus(self::STATUS_DRAFT);
}

public function isStatusValid()
{
return $this->isStatus(self::STATUS_VALID);
}

public function getProductsOrders()
{
$productsOrdersArray = [];
if ($this->orders && count($this->orders)) {
foreach ($this->orders as $order) {
foreach ($order->productOrder as $productOrder) {
if (!isset($productsOrdersArray[$productOrder->id_product])) {
$productsOrdersArray[$productOrder->id_product] = [$productOrder];
} else {
$productOrderMatch = false;
foreach ($productsOrdersArray[$productOrder->id_product] as &$theProductOrder) {
if ($theProductOrder->unit == $productOrder->unit && $theProductOrder->price == $productOrder->price) {
$theProductOrder->quantity += $productOrder->quantity;
$productOrderMatch = true;
}
}
if (!$productOrderMatch) {
$productsOrdersArray[$productOrder->id_product][] = $productOrder;
}
}
}
}
}

return $productsOrdersArray;
}

public function getFilename()
{
return Yii::getAlias('@app/web/pdf/'.$this->getType().'-' . $this->reference. '.pdf') ;
}

}

+ 44
- 87
common/models/Invoice.php Целия файл

@@ -38,100 +38,57 @@ termes.

namespace common\models;

use common\components\ActiveRecordCommon;
use Yii;
use common\components\ActiveRecordCommon ;

/**
* This is the model class for table "facture".
* This is the model class for table "invoice".
*
* @property integer $id
* @property integer $id_producer
* @property string $date
* @property string $name
* @property string $reference
* @property string $wording
* @property string $text
* @property double $amount_without_tax
* @property integer $paid
* @property string $date_payment
* @property string $mean_payment
* @property string $date
* @property string $comment
* @property integer $id_user
* @property string $address
* @property string $city
* @property string $postcode
*/
class Invoice extends ActiveRecordCommon
class Invoice extends Document
{

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

/**
* @inheritdoc
*/
public function rules()
{
return [
[['id_producer', 'paye'], 'integer'],
[['date', 'date_payment'], 'safe'],
[['texte'], 'string'],
[['amount_without_tax', 'ca'], 'number'],
[['reference', 'wording', 'mean_payment'], 'string', 'max' => 255],
];
}

/*
* Relations
*/
public function getProducer()
{
return $this->hasOne(Producer::className(), ['id' => 'id_producer']);
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'id_producer' => 'Producteur',
'date' => 'Date',
'reference' => 'Reference',
'wording' => 'Libellé',
'text' => 'Texte',
'amount_without_tax' => 'Montant Ht',
'paid' => 'Paye',
'date_payment' => 'Date de paiement',
'means_payment' => 'Méthode payment',
'turnover' => 'CA'
];
}

/**
* Retourne les options de base nécessaires à la fonction de recherche.
*
* @return array
*/
public static function defaultOptionsSearch()
{
return [
'with' => [],
'join_with' => [],
'orderby' => self::tableName().'.date ASc',
'attribute_id_producer' => self::tableName().'.id_producer'
] ;
}
/**
* Retourne la dernière facture émise.
*
* @return Facture
*/
public static function getLastInvoice()
{
return self::searchOne([],['orderby'=>'reference DESC']) ;
}
public $deliveryNotes ;

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

/*
* Relations
*/

public function getOrders()
{
return $this->relationOrders('id_invoice') ;
}

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

}

+ 85
- 0
common/models/InvoiceSearch.php Целия файл

@@ -0,0 +1,85 @@
<?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\Invoice;

class InvoiceSearch extends Invoice
{

public function rules()
{
return [
[[], 'safe'],
[['comment', 'address', 'status'], 'string'],
[['id_user'], 'integer'],
[['name', 'reference'], 'string', 'max' => 255],
];
}

public function search($params)
{
$optionsSearch = self::defaultOptionsSearch();

$query = Invoice::find()
->with($optionsSearch['with'])
->where(['invoice.id_producer' => GlobalParam::getCurrentProducerId()])
->orderBy('invoice.status ASC, invoice.reference DESC');

$dataProvider = new ActiveDataProvider([
'query' => $query,
'sort' => ['attributes' => ['name', 'reference', 'date']],
'pagination' => [
'pageSize' => 20,
],
]);

$this->load($params);
if (!$this->validate()) {
return $dataProvider;
}

$query->andFilterWhere(['like', 'invoice.name', $this->name]);
$query->andFilterWhere(['like', 'invoice.reference', $this->reference]);
$query->andFilterWhere(['like', 'invoice.status', $this->status]);

return $dataProvider;
}
}

+ 823
- 695
common/models/Order.php
Файловите разлики са ограничени, защото са твърде много
Целия файл


+ 81
- 0
common/models/OrderStatusHistory.php Целия файл

@@ -0,0 +1,81 @@
<?php

namespace common\models;

use common\components\ActiveRecordCommon;
use Yii;

/**
* This is the model class for table "order_order_status".
*
* @property integer $id
* @property integer $id_order
* @property integer $id_order_status
* @property string $date
*/
class OrderStatusHistory extends ActiveRecordCommon
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'order_status_history';
}

/**
* @inheritdoc
*/
public function rules()
{
return [
[['id_order', 'status', 'id_user', 'date', 'origin'], 'required'],
[['id_order', 'id_user',], 'integer'],
[['date'], 'safe'],
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'id_order' => 'Commande',
'id_user' => 'Utilisateur',
'status' => 'Statut',
'origin' => 'Origine',
'date' => 'Date',
];
}

/*
* Relations
*/

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

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' => ['order', 'orderStatus'],
'orderby' => 'date ASC',
'attribute_id_producer' => ''
];
}
}

+ 347
- 337
common/models/PointSale.php Целия файл

@@ -1,48 +1,49 @@
<?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.
*/
/**
* 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 ;
use common\models\PointSaleDistribution;
use common\components\ActiveRecordCommon;

/**
* This is the model class for table "point_vente".
@@ -55,317 +56,326 @@ use common\components\ActiveRecordCommon ;
*/
class PointSale extends ActiveRecordCommon
{
var $orders = [];
var $revenues = 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', 'integer'],
['id_producer', 'required'],
[['users', 'users_comment', 'code'], 'safe']
];
}

/**
* @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',
];
}

/*
* 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']
);
}

/**
* 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;

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;
}
var $orders = [];
var $revenues = 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']
];
}

/**
* @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'
];
}

/*
* 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;

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;
}
}
}
}
}
}
}

/**
* 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 = Producer::getId();
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();

/**
* 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 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();

/**
* 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();
}
}
}
}

/**
* 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;

/**
* 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();
}
}
}
}
}
return null ;
}

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

/**
* 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))) {

/**
* 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;
} 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) ;

/**
* 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 '';
}
}
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 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) ;

/**
* 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');
}
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() ;
}

/**
* 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();
}
}
}
}
}

+ 2
- 1
common/models/PointSaleDistribution.php Целия файл

@@ -38,6 +38,7 @@ termes.

namespace common\models;

use common\helpers\GlobalParam;
use Yii;
use common\components\ActiveRecordCommon ;
use common\models\PointVente;
@@ -129,7 +130,7 @@ class PointSaleDistribution extends ActiveRecordCommon
$q->where(['id_distribution' => $idDistribution]);
}])
->where([
'id_producer' => Producer::getId(),
'id_producer' => GlobalParam::getCurrentProducerId(),
])
->all();

+ 2
- 1
common/models/PointSaleSearch.php Целия файл

@@ -38,6 +38,7 @@ termes.

namespace common\models ;

use common\helpers\GlobalParam;
use common\models\PointSale ;

class PointSaleSearch extends PointSale
@@ -68,7 +69,7 @@ class PointSaleSearch extends PointSale
$query = PointSale::find()
->with($optionsSearch['with'])
->innerJoinWith($optionsSearch['join_with'], true)
->where(['point_sale.id_producer' => Producer::getId()])
->where(['point_sale.id_producer' => GlobalParam::getCurrentProducerId()])
;
$dataProvider = new ActiveDataProvider([

+ 487
- 459
common/models/Producer.php Целия файл

@@ -1,45 +1,45 @@
<?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.
*/
/**
* 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\components\ActiveRecordCommon;
use common\helpers\Departments;
use yii\helpers\Html;

@@ -63,195 +63,221 @@ use yii\helpers\Html;
* @property boolean use_credit_checked_default
* @property float credit_limit
* @property string background_color_logo
*
*
*/
class Producer extends ActiveRecordCommon
class Producer extends ActiveRecordCommon
{
const CREDIT_FUNCTIONING_MANDATORY = 'mandatory' ;
const CREDIT_FUNCTIONING_OPTIONAL = 'optional' ;
const CREDIT_FUNCTIONING_USER = 'user' ;
const HINT_CREDIT_FUNCTIONING = '<ul>'
const CREDIT_FUNCTIONING_MANDATORY = 'mandatory';
const CREDIT_FUNCTIONING_OPTIONAL = 'optional';
const CREDIT_FUNCTIONING_USER = 'user';
const HINT_CREDIT_FUNCTIONING = '<ul>'
. '<li>Optionnelle : l\'utilisateur choisit s\'il utilise son Crédit ou non. Les commandes peuvent être payées ou impayées.</li>'
. '<li>Obligatoire : toutes les commandes de l\'utilisateur son comptabilisées au niveau du Crédit. Toutes les commandes sont payées.</li>'
. '<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>'
. '</ul>' ;
public static $creditFunctioningArray = [
self::CREDIT_FUNCTIONING_MANDATORY => 'Obligatoire',
self::CREDIT_FUNCTIONING_OPTIONAL => 'Optionnelle',
self::CREDIT_FUNCTIONING_USER => 'Basée sur l\'utilisateur',
];
const BEHAVIOR_DELETE_ORDER_DELETE = 'delete' ;
const BEHAVIOR_DELETE_ORDER_STATUS = 'status' ;
var $secret_key_payplug ;
/**
* @inheritdoc
*/
public static function tableName()
{
return 'producer';
}

/**
* @inheritdoc
*/
public function rules()
{
return [
[['name','type'], 'required'],
[['tiller_provider_token','tiller_restaurant_token'], 'required', 'when' => function($model) {
return $model->tiller == true ;
}],
[['order_deadline', 'order_delay'], 'integer'],
['order_deadline', 'in', 'range' => [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]],
['order_delay', 'in', 'range' => [1, 2, 3, 4, 5, 6, 7]],
['code', function($attribute, $params) {
$code = $this->$attribute;
$producer = Producer::findOne(['code' => $code]);
if ($producer && $producer->id != $this->id) {
$this->addError($attribute, 'Ce code est déjà utilisé par un autre producteur.');
}
}],
[['description','mentions','gcs','order_infos','slug','secret_key_payplug','background_color_logo','option_behavior_cancel_order','tiller_provider_token','tiller_restaurant_token'], 'string'],
[['negative_balance', 'credit', 'active','online_payment','user_manage_subscription', 'option_allow_user_gift','use_credit_checked_default','tiller'], 'boolean'],
[['name', 'siret', 'logo', 'photo', 'postcode', 'city', 'code','type','credit_functioning','option_behavior_cancel_order'], 'string', 'max' => 255],
[['free_price', 'credit_limit_reminder','credit_limit'], 'double'],
['free_price', 'compare', 'compareValue' => 0, 'operator' => '>=', 'type' => 'number', 'message' => 'Prix libre doit être supérieur ou égal à 0'],
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'name' => 'Nom',
'siret' => 'Siret',
'logo' => 'Logo',
'photo' => 'Photo',
'description' => 'Description',
'postcode' => 'Code postal',
'city' => 'Ville',
'code' => 'Code',
'order_deadline' => 'Heure limite de commande',
'order_delay' => 'Délai de commande',
'negative_balance' => 'Solde négatif',
'credit' => 'Crédit pain',
'active' => 'Actif',
'date_creation' => 'Date de création',
'order_infos' => 'Informations',
'slug' => 'Slug',
'type' => 'Type de producteur',
'credit_limit_reminder' => 'Seuil de crédit limite avant relance',
'online_payment' => 'Activer le paiement en ligne',
'secret_key_payplug' => 'Clé secrète Payplug',
'user_manage_subscription' => 'Autoriser les utilisateurs à gérer leurs abonnements',
'mentions' => 'Mentions légales',
'gcs' => 'Conditions générales de vente',
'option_allow_user_gift' => 'Autoriser les utilisateurs à effectuer un don à la plateforme lors de leur commande',
'credit_functioning' => 'Utilisation du Crédit par l\'utilisateur',
'credit_limit' => 'Crédit limite',
'use_credit_checked_default' => 'Cocher par défaut l\'option "Utiliser mon crédit" lors de la commande de l\'utilisateur',
'background_color_logo' => 'Couleur de fond du logo',
'option_behavior_cancel_order' => 'Comportement lors de la suppression d\'une commande',
'tiller' => 'Tiller',
'tiller_provider_token' => 'Token provider',
'tiller_restaurant_token' => 'Token restaurant',
. '</ul>';

public static $creditFunctioningArray = [
self::CREDIT_FUNCTIONING_MANDATORY => 'Obligatoire',
self::CREDIT_FUNCTIONING_OPTIONAL => 'Optionnelle',
self::CREDIT_FUNCTIONING_USER => 'Basée sur l\'utilisateur',
];
}

/*
* Relations
*/
public function getUserProducer()
{
return $this->hasMany(
UserProducer::className(),
['id_producer' => 'id']
);
}

public function getUser()
{
return $this->hasMany(User::className(), ['id_producer' => 'id']);
}
public function getContact()
{
return $this->hasMany(User::className(),['id_producer' => 'id'])
->where(['status' => User::STATUS_PRODUCER]);
}
/**
* Retourne les options de base nécessaires à la fonction de recherche.
*
* @return array
*/
public static function defaultOptionsSearch() {
return [
'with' => [],
'join_with' => [],
'orderby' => 'name ASC',
'attribute_id_producer' => 'id'
] ;
}

/**
* Retourne la liste des établissements pour l'initialisation d'une liste
* sélective.
*
* @return array
*/
public static function getProducerPopulateDropdown()
{
$producers = Producer::find()
->where([
'active' => true,
])
->orderBy('postcode, city ASC')
->all() ;
$departments = Departments::get();
$dataProducers = [];
$optionsProducers = [];
foreach ($producers as $p) {
if (!key_exists('d' . substr($p->postcode, 0, 2), $dataProducers)) {
$dataProducers['d' . substr($p->postcode, 0, 2)] = '<strong>' . $departments[substr($p->postcode, 0, 2)] . '</strong>';
$optionsProducers['d' . substr($p->postcode, 0, 2)] = ['disabled' => true];
}

$dataProducers[$p->id] = '<span class="glyphicon glyphicon-lock"></span> ' . Html::encode($p->name) . ' - ' . Html::encode($p->postcode) . ' ' . Html::encode($p->city) . ' <span class="glyphicon glyphicon-lock"></span>';

if (strlen($p->code)) {
$optionsProducers[$p->id] = ['class' => 'lock'];
}

const BEHAVIOR_DELETE_ORDER_DELETE = 'delete';
const BEHAVIOR_DELETE_ORDER_STATUS = 'status';

var $secret_key_payplug;

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

return ['data' => $dataProducers, 'options' => $optionsProducers];
}

/**
* Retourne le CA de l'établissement pour un mois donné.
*
* @param string $period
* @param boolean $format
* @return string
*/
public function getTurnover($period = '', $format = false)
{
if (!$period) {
$period = date('Y-m');
/**
* @inheritdoc
*/
public function rules()
{
return [
[['name', 'type', 'id_tax_rate_default'], 'required'],
[['tiller_provider_token', 'tiller_restaurant_token'], 'required', 'when' => function ($model) {
return $model->tiller == true;
}],
[['order_deadline', 'order_delay', 'id_tax_rate_default', 'document_quotation_duration'], 'integer'],
['order_deadline', 'in', 'range' => [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]],
['order_delay', 'in', 'range' => [1, 2, 3, 4, 5, 6, 7]],
['code', function ($attribute, $params) {
$code = $this->$attribute;
$producer = Producer::findOne(['code' => $code]);
if ($producer && $producer->id != $this->id) {
$this->addError($attribute, 'Ce code est déjà utilisé par un autre producteur.');
}
}],
[['document_quotation_prefix', 'document_invoice_prefix', 'document_delivery_note_prefix'], function($attribute, $params) {
if(!ctype_upper($this->$attribute)) {
$this->addError($attribute, 'Ne doit contenir que des majuscules') ;
}
}],
[['description', 'mentions', 'gcs', 'order_infos', 'slug', 'secret_key_payplug', 'background_color_logo', 'option_behavior_cancel_order', 'tiller_provider_token', 'tiller_restaurant_token', 'status',
'document_infos_bottom', 'document_infos_quotation', 'document_infos_invoice', 'document_infos_delivery_note', 'address'], 'string'],
[['negative_balance', 'credit', 'active', 'online_payment', 'user_manage_subscription', 'option_allow_user_gift', 'use_credit_checked_default', 'tiller'], 'boolean'],
[['name', 'siret', 'logo', 'photo', 'postcode', 'city', 'code', 'type', 'credit_functioning', 'option_behavior_cancel_order', 'document_quotation_prefix', 'document_quotation_first_reference', 'document_invoice_prefix', 'document_invoice_first_reference', 'document_delivery_note_prefix', 'document_delivery_note_first_reference'], 'string', 'max' => 255],
[['free_price', 'credit_limit_reminder', 'credit_limit'], 'double'],
['free_price', 'compare', 'compareValue' => 0, 'operator' => '>=', 'type' => 'number', 'message' => 'Prix libre doit être supérieur ou égal à 0'],
];
}
$connection = Yii::$app->getDb();
$command = $connection->createCommand('

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'name' => 'Nom',
'siret' => 'Siret',
'logo' => 'Logo',
'photo' => 'Photo',
'description' => 'Description',
'postcode' => 'Code postal',
'city' => 'Ville',
'code' => 'Code',
'order_deadline' => 'Heure limite de commande',
'order_delay' => 'Délai de commande',
'negative_balance' => 'Solde négatif',
'credit' => 'Crédit pain',
'active' => 'Actif',
'date_creation' => 'Date de création',
'order_infos' => 'Informations',
'slug' => 'Slug',
'type' => 'Type de producteur',
'credit_limit_reminder' => 'Seuil de crédit limite avant relance',
'online_payment' => 'Activer le paiement en ligne',
'secret_key_payplug' => 'Clé secrète Payplug',
'user_manage_subscription' => 'Autoriser les utilisateurs à gérer leurs abonnements',
'mentions' => 'Mentions légales',
'gcs' => 'Conditions générales de vente',
'option_allow_user_gift' => 'Autoriser les utilisateurs à effectuer un don à la plateforme lors de leur commande',
'credit_functioning' => 'Utilisation du Crédit par l\'utilisateur',
'credit_limit' => 'Crédit limite',
'use_credit_checked_default' => 'Cocher par défaut l\'option "Utiliser mon crédit" lors de la commande de l\'utilisateur',
'background_color_logo' => 'Couleur de fond du logo',
'option_behavior_cancel_order' => 'Comportement lors de la suppression d\'une commande',
'tiller' => 'Tiller',
'tiller_provider_token' => 'Token provider',
'tiller_restaurant_token' => 'Token restaurant',
'status' => 'Statut',
'id_tax_rate_default' => 'Taxe',
'document_quotation_prefix' => 'Préfixe des devis',
'document_quotation_first_reference' => 'Première référence des devis',
'document_quotation_duration' => 'Durée du devis',
'document_invoice_prefix' => 'Préfixe des factures',
'document_invoice_first_reference' => 'Première référence des factures',
'document_delivery_note_prefix' => 'Préfixe des bons de livraison',
'document_delivery_note_first_reference' => 'Première référence des bons de livraison',
'document_infos_bottom' => 'Informations affichées en bas des documents',
'document_infos_quotation' => 'Informations affichées en bas des devis',
'document_infos_invoice' => 'Informations affichées en bas des factures',
'document_infos_delivery_note' => 'Informations affichées en bas des bons de livraison',
'address' => 'Adresse'
];
}

/*
* Relations
*/

public function getUserProducer()
{
return $this->hasMany(
UserProducer::className(),
['id_producer' => 'id']
);
}

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

public function getContact()
{
return $this->hasMany(User::className(), ['id_producer' => 'id'])
->where(['status' => User::STATUS_PRODUCER]);
}

public function getTaxRate()
{
return $this->hasOne(TaxRate::className(), ['id' => 'id_tax_rate_default']);
}

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

/**
* Retourne la liste des établissements pour l'initialisation d'une liste
* sélective.
*
* @return array
*/
public static function getProducerPopulateDropdown()
{
$producers = Producer::find()
->where([
'active' => true,
])
->orderBy('postcode, city ASC')
->all();

$departments = Departments::get();
$dataProducers = [];
$optionsProducers = [];
foreach ($producers as $p) {
if (!key_exists('d' . substr($p->postcode, 0, 2), $dataProducers)) {
$dataProducers['d' . substr($p->postcode, 0, 2)] = '<strong>' . $departments[substr($p->postcode, 0, 2)] . '</strong>';
$optionsProducers['d' . substr($p->postcode, 0, 2)] = ['disabled' => true];
}

$dataProducers[$p->id] = '<span class="glyphicon glyphicon-lock"></span> ' . Html::encode($p->name) . ' - ' . Html::encode($p->postcode) . ' ' . Html::encode($p->city) . ' <span class="glyphicon glyphicon-lock"></span>';

if (strlen($p->code)) {
$optionsProducers[$p->id] = ['class' => 'lock'];
}
}

return ['data' => $dataProducers, 'options' => $optionsProducers];
}

/**
* Retourne le CA de l'établissement pour un mois donné.
*
* @param string $period
* @param boolean $format
* @return string
*/
public function getTurnover($period = '', $format = false)
{
if (!$period) {
$period = date('Y-m');
}

$connection = Yii::$app->getDb();
$command = $connection->createCommand('
SELECT SUM(product_order.price * product_order.quantity) AS turnover
FROM `order`, product_order, distribution, product
WHERE `order`.id = product_order.id_order
@@ -260,265 +286,267 @@ class Producer extends ActiveRecordCommon
AND product_order.id_product = product.id
AND distribution.date > :date_begin
AND distribution.date < :date_end', [
':date_begin' => date('Y-m-31', strtotime("-1 month", strtotime($period))),
':date_end' => date('Y-m-01', strtotime("+1 month", strtotime($period))),
':id_producer' => $this->id
]);
':date_begin' => date('Y-m-31', strtotime("-1 month", strtotime($period))),
':date_end' => date('Y-m-01', strtotime("+1 month", strtotime($period))),
':id_producer' => $this->id
]);

$result = $command->queryOne();
$turnover = $result['turnover'];
$result = $command->queryOne();
$turnover = $result['turnover'];

if ($format) {
return number_format($turnover, 2) . ' €';
if ($format) {
return number_format($turnover, 2) . ' €';
} else {
return $turnover;
}
}
else {
return $turnover;

/**
* Retourne le montant à facturer pour une période donnée.
*
* @param string $periode
* @param float $ca
* @param boolean $format
* @return string
*/
public function getMAmountBilled($format = false)
{
if ($format) {
return number_format($this->free_price, 2) . ' €';
} else {
return $this->free_price;
}
}
}

/**
* Retourne le montant à facturer pour une période donnée.
*
* @param string $periode
* @param float $ca
* @param boolean $format
* @return string
*/
public function getMAmountBilled($format = false)
{
if ($format) {
return number_format($this->free_price, 2) . ' €' ;
} else {
return $this->free_price ;

/**
* Retourne la facture d'une période donnée.
*
* @param string $periode
* @return Facture
*/
public function getInvoice($period = '')
{
if (!$period) {
$period = date('Y-m', strtotime('-1 month'));
}

$invoice = Invoice::searchOne(
['id_producer' => $this->id, 'period' => ':period'],
['params' => [':period' => $period]]
);

return $invoice;
}
}

/**
* Retourne la facture d'une période donnée.
*
* @param string $periode
* @return Facture
*/
public function getInvoice($period = '')
{
if (!$period) {
$period = date('Y-m', strtotime('-1 month'));

/**
* Retourne la facture du mois dernier.
*
* @return Facture
*/
public function getInvoiceLastMonth()
{
return $this->getInvoice(date('Y-m', strtotime('-1 month')));
}
$invoice = Invoice::searchOne(
['id_producer' => $this->id, 'period' => ':period'],
['params' => [':period' => $period]]
) ;

return $facture;
}

/**
* Retourne la facture du mois dernier.
*
* @return Facture
*/
public function getInvoiceLastMonth()
{
return $this->getInvoice(date('Y-m', strtotime('-1 month')));
}

/**
* Retourne une configuration d'un établissement donné.
*
* @param string $config
* @param integer $id_etablissement
* @return mixed
*/
public static function getConfig($config = '', $idProducer = 0)
{
if (strlen($config)) {
if (!$idProducer) {
$idProducer = Producer::getId() ;
}
$producer = self::findOne($idProducer);
if ($producer) {
return $producer->$config;
}

/**
* Retourne une configuration d'un établissement donné.
*
* @param string $config
* @param integer $id_etablissement
* @return mixed
*/
public static function getConfig($config = '', $idProducer = 0)
{
if (strlen($config)) {
if (!$idProducer) {
$idProducer = GlobalParam::getCurrentProducerId();
}

$producer = self::findOne($idProducer);
if ($producer) {
return $producer->$config;
}
}

return false;
}

return false;
}

/**
* Retourne le montant de l'abonnement à prix libre définit par
* le producteur.
*
* @param boolean $format
* @return mixed
*/
public function getFreePrice($format = true)
{
if (!is_null($this->free_price)) {
if($format) {
return number_format($this->free_price, 2, ',', false) . ' € HT';
}
else {
return $this->free_price;
}
/**
* Retourne le montant de l'abonnement à prix libre définit par
* le producteur.
*
* @param boolean $format
* @return mixed
*/
public function getFreePrice($format = true)
{
if (!is_null($this->free_price)) {
if ($format) {
return number_format($this->free_price, 2, ',', false) . ' € HT';
} else {
return $this->free_price;
}
}
}
}
/**
* Lie un utilisateur à un producteur.
*
* @param integer $id_user
* @param integer $id_producer
* @return UserProducer
*/
public static function addUser($idUser, $idProducer, $bookmark = 1)
{
$userProducer = UserProducer::searchOne([
'user_producer.id_user' => $idUser,
'user_producer.id_producer' => $idProducer
]) ;

if (!$userProducer) {
$newUserProducer = new UserProducer;
$newUserProducer->id_producer = $idProducer;
$newUserProducer->id_user = $idUser;
$newUserProducer->credit = 0;
$newUserProducer->active = 1;
$newUserProducer->bookmark = (int) $bookmark ;
$newUserProducer->save();
} else {
if (!$userProducer->active) {
$userProducer->active = 1;
$userProducer->save();
}

/**
* Lie un utilisateur à un producteur.
*
* @param integer $id_user
* @param integer $id_producer
* @return UserProducer
*/
public static function addUser($idUser, $idProducer, $bookmark = 1)
{
$userProducer = UserProducer::searchOne([
'user_producer.id_user' => $idUser,
'user_producer.id_producer' => $idProducer
]);

if (!$userProducer) {
$newUserProducer = new UserProducer;
$newUserProducer->id_producer = $idProducer;
$newUserProducer->id_user = $idUser;
$newUserProducer->credit = 0;
$newUserProducer->active = 1;
$newUserProducer->bookmark = (int)$bookmark;
$newUserProducer->save();
} else {
if (!$userProducer->active) {
$userProducer->active = 1;
$userProducer->save();
}
}

return $userProducer;
}
return $userProducer ;
}
/**
* Retourne l'ID du producteur courant.
*
* @return integer|boolean
*/
public static function getId()
{
if(Yii::$app->controller->module->id == 'app-backend') {
if(!Yii::$app->user->isGuest) {
return Yii::$app->user->identity->id_producer ;
}

/**
* Retourne la date la plus proche où il est possible de commander.
* Attention, cette méthode ne garantit pas qu'une distribution a été initialisée
* à cette date.
*
* @return string
*/
public function getEarliestDateOrder()
{
$deadline = 20;
$earliestDateOrder = date('Y-m-d');

if ($this->order_deadline) {
$deadline = $this->order_deadline;
}
if (date('H') >= $deadline) {
$earliestDateOrder = date('Y-m-d', strtotime(date('Y-m-d')) + ($this->order_delay) * (24 * 60 * 60));
} else {
$earliestDateOrder = date('Y-m-d', strtotime(date('Y-m-d')) + ($this->order_delay - 1) * (24 * 60 * 60));
}

return $earliestDateOrder;
}
else {
return Yii::$app->controller->getProducer()->id ; ;

/**
* Retourne le chemin vers le fichier contenant la clé secrète d'API de Payplug
*
* @return string
*/
public function getFilenameSecretKeyPayplug()
{
return '../../common/config/payplug/' . $this->id . '.key';
}
return false ;
}
/**
* Retourne le producteur courant.
*
* @return Producer|boolean
*/
public static function getCurrent()
{
if(self::getId()) {
return self::searchOne() ;

/**
* Enregistre la clé secrète d'API de Payplug dans un fichier
*/
public function saveSecretKeyPayplug()
{
if ($this->online_payment) {
$handle = fopen($this->getFilenameSecretKeyPayplug(), "w");
fwrite($handle, $this->secret_key_payplug);
fclose($handle);
}
}
return false ;
}
/**
* Retourne la date la plus proche où il est possible de commander.
* Attention, cette méthode ne garantit pas qu'une distribution a été initialisée
* à cette date.
*
* @return string
*/
public function getEarliestDateOrder()
{
$deadline = 20;
$earliestDateOrder = date('Y-m-d');
if($this->order_deadline) {
$deadline = $this->order_deadline;

/**
* Retourne la clé secrète d'API de Payplug.
*
* @return string
*/
public function getSecretKeyPayplug()
{
if (file_exists($this->getFilenameSecretKeyPayplug())) {
$handle = fopen($this->getFilenameSecretKeyPayplug(), "r");
$filesize = filesize($this->getFilenameSecretKeyPayplug());
if ($handle && $filesize) {
$secretKey = fread($handle, $filesize);
fclose($handle);
return $secretKey;
}
}

return '';
}
if (date('H') >= $deadline) {
$earliestDateOrder = date('Y-m-d', strtotime(date('Y-m-d')) + ($this->order_delay) * (24 * 60 * 60));
} else {
$earliestDateOrder = date('Y-m-d', strtotime(date('Y-m-d')) + ($this->order_delay - 1) * (24 * 60 * 60));

/**
* Retourne le compte producteur de démonstration.
*
* @return Producer
*/
public static function getDemoAccount()
{
$producer = Producer::find()->where('name LIKE \'Démo\'')->one();
return $producer;
}
return $earliestDateOrder ;
}
/**
* Retourne le chemin vers le fichier contenant la clé secrète d'API de Payplug
*
* @return string
*/
public function getFilenameSecretKeyPayplug()
{
return '../../common/config/payplug/'.$this->id.'.key' ;
}
/**
* Enregistre la clé secrète d'API de Payplug dans un fichier
*/
public function saveSecretKeyPayplug()
{
if($this->online_payment) {
$handle = fopen($this->getFilenameSecretKeyPayplug(),"w");
fwrite($handle,$this->secret_key_payplug);
fclose($handle);

/**
* Retourne true si le compte est un compte de démo.
*
* @return boolean
*/
public function isDemo()
{
if (strpos($this->name, 'Démo') !== false) {
return true;
}

return false;
}
}
/**
* Retourne la clé secrète d'API de Payplug.
*
* @return string
*/
public function getSecretKeyPayplug()
{
if(file_exists($this->getFilenameSecretKeyPayplug())) {
$handle = fopen($this->getFilenameSecretKeyPayplug(), "r") ;
$filesize = filesize($this->getFilenameSecretKeyPayplug()) ;
if($handle && $filesize) {
$secretKey = fread($handle, $filesize);
fclose($handle);
return $secretKey ;
}

public function getFullAddress($nl2br = false)
{
$address = '' ;
$address .= $this->name."\n" ;

if(strlen($this->address)) {
$address .= $this->address."\n" ;
}

if(strlen($this->postcode) || strlen($this->city)) {
$address .= $this->postcode.' '.$this->city ;
}

if($nl2br) {
$address = nl2br($address) ;
}

return $address ;
}
return '' ;
}
/**
* Retourne le compte producteur de démonstration.
*
* @return Producer
*/
public static function getDemoAccount()
{
$producer = Producer::find()->where('name LIKE \'Démo\'')->one() ;
return $producer ;
}
/**
* Retourne true si le compte est un compte de démo.
*
* @return boolean
*/
public function isDemo()
{
if(strpos($this->name, 'Démo') !== false) {
return true ;

public function getHtmlLogo()
{
$html = '' ;

if(strlen($this->logo)) {
$html = '<img src="'.Yii::$app->urlManagerProducer->getHostInfo().'/'.Yii::$app->urlManagerProducer->baseUrl.'/uploads/'.$this->logo.'" class="producer-logo" />' ;
}

return $html ;
}
return false ;
}

public function getEmailOpendistrib()
{
return $this->slug.'@opendistrib.net' ;
}

}

+ 320
- 268
common/models/Product.php Целия файл

@@ -1,45 +1,48 @@
<?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.
*/
/**
* 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\Debug;
use common\helpers\GlobalParam;
use common\helpers\Price;
use Yii;
use common\components\ActiveRecordCommon ;
use common\components\ActiveRecordCommon;

/**
* This is the model class for table "product".
@@ -57,240 +60,289 @@ use common\components\ActiveRecordCommon ;
*/
class Product extends ActiveRecordCommon
{
var $total = 0;
var $apply_distributions = true ;
public static $unitsArray = [
'piece' => [
'unit' => 'piece',
'wording_unit' => 'la pièce',
'wording' => 'pièce(s)',
'wording_short' => 'p.',
'coefficient' => 1
],
'g' => [
'unit' => 'g',
'wording_unit' => 'le g',
'wording' => 'g',
'wording_short' => 'g',
'coefficient' => 1000
],
'kg' => [
'unit' => 'kg',
'wording_unit' => 'le kg',
'wording' => 'kg',
'wording_short' => 'kg',
'coefficient' => 1
],
'mL' => [
'unit' => 'mL',
'wording_unit' => 'le mL',
'wording' => 'mL',
'wording_short' => 'mL',
'coefficient' => 1000
],
'L' => [
'unit' => 'L',
'wording_unit' => 'le litre',
'wording' => 'L',
'wording_short' => 'L',
'coefficient' => 1
],
];
/**
* @inheritdoc
*/
public static function tableName()
{
return 'product';
}

/**
* @inheritdoc
*/
public function rules()
{
return [
[['name', 'id_producer'], 'required'],
[['active', 'order', 'quantity_max', 'id_producer'], 'integer'],
[['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'unavailable','apply_distributions'], 'boolean'],
[['price', 'weight', 'step'], 'number'],
[[ 'photo'], 'file'],
[['name', 'description', 'photo', 'unit'], 'string', 'max' => 255],
[['recipe'], 'string', 'max' => 1000],
['step', 'required', 'message' => 'Champs obligatoire', 'when' => function($model) {
if($model->unit != 'piece') {
return true ;
}
return false ;
}],
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'name' => 'Nom',
'description' => 'Description',
'active' => 'Actif',
'photo' => 'Photo',
'price' => 'Prix (€)',
'weight' => 'Poids',
'recipe' => 'Recette',
'monday' => 'Lundi',
'tuesday' => 'Mardi',
'wednesday' => 'Mercredi',
'thursday' => 'Jeudi',
'friday' => 'Vendredi',
'saturday' => 'Samedi',
'sunday' => 'Dimanche',
'order' => 'Ordre',
'quantity_max' => 'Quantité max par défaut',
'unavailable' => 'Épuisé',
'apply_distributions' => 'Appliquer ces modifications dans les distributions futures',
'unit' => 'Unité',
'step' => 'Pas'
public $total = 0;
public $apply_distributions = true;

public $price_with_tax = 0 ;
public $wording_unit = '' ;

public static $unitsArray = [
'piece' => [
'unit' => 'piece',
'wording_unit' => 'la pièce',
'wording' => 'pièce(s)',
'wording_short' => 'p.',
'coefficient' => 1
],
'g' => [
'unit' => 'g',
'wording_unit' => 'le g',
'wording' => 'g',
'wording_short' => 'g',
'coefficient' => 1000
],
'kg' => [
'unit' => 'kg',
'wording_unit' => 'le kg',
'wording' => 'kg',
'wording_short' => 'kg',
'coefficient' => 1
],
'mL' => [
'unit' => 'mL',
'wording_unit' => 'le mL',
'wording' => 'mL',
'wording_short' => 'mL',
'coefficient' => 1000
],
'L' => [
'unit' => 'L',
'wording_unit' => 'le litre',
'wording' => 'L',
'wording_short' => 'L',
'coefficient' => 1
],
];
}
public function getProductDistribution()
{
return $this->hasMany(ProductDistribution::className(), ['id_product' => 'id']);
}
public function getProductSubscription()
{
return $this->hasMany(ProductSubscription::className(), ['id_product' => 'id']);
}
/**
* Retourne les options de base nécessaires à la fonction de recherche.
*
* @return array
*/
public static function defaultOptionsSearch() {
return [
'with' => [],
'join_with' => [],
'orderby' => 'order ASC',
'attribute_id_producer' => 'product.id_producer'
] ;
}

/**
* Retourne la description du produit.
*
* @return string
*/
public function getDescription()
{
$description = $this->description;
if (isset($this->weight) && is_numeric($this->weight) && $this->weight > 0) {
if ($this->weight >= 1000) {
$description .= ' (' . ($this->weight / 1000) . 'kg)';
} else {
$description .= ' (' . $this->weight . 'g)';
}

/**
* @inheritdoc
*/
public static function tableName()
{
return 'product';
}
return $description;
}

/**
* Retourne le libellé (admin) du produit.
* @return type
*/
public function getStrWordingAdmin()
{
return $this->name;
}

/**
* Enregistre le produit.
*
* @param boolean $runValidation
* @param array $attributeNames
* @return boolean
*/
public function save($runValidation = true, $attributeNames = NULL)
{
$this->id_producer = Producer::getId();
return parent::save($runValidation, $attributeNames);
}

/**
* Retourne les produits d'une production donnée.
*
* @param integer $idDistribution
* @return array
*/
public static function searchByDistribution($idDistribution)
{
return Product::find()
->leftJoin('product_distribution', 'product.id = product_distribution.id_product')
->where([
'id_producer' => Producer::getId(),
'product_distribution.id_distribution' => $idDistribution
])
->orderBy('product_distribution.active DESC, product.order ASC')
->all();
}

/**
* Retourne le nombre de produits du producteur courant.
*
* @return integer
*/
public static function count()
{
return self::searchCount() ;
}
/**
* Retourne le produit "Don".
*
* @return Product
*/
public static function getProductGift()
{
$productGift = Product::find()
->where([
'product.id_producer' => 0
])
->andFilterWhere(['like','product.name','Don'])
->one() ;
return $productGift ;
}
/**
* Retourne le libellé d'une unité.
*
* @param $format wording_unit, wording, short
* @param $unitInDb Unité stockée en base de données (ex: si g > kg, si mL > L)
* @return $string Libellé de l'unité
*/
public static function strUnit($unit, $format = 'wording_short', $unitInDb = false)
{
$strUnit = '' ;
if($unitInDb) {
if($unit == 'g') {
$unit = 'kg' ;
}
if($unit == 'mL') {
$unit = 'L' ;
}

/**
* @inheritdoc
*/
public function rules()
{
return [
[['name', 'id_producer'], 'required'],
[['active', 'order', 'quantity_max', 'id_producer', 'id_tax_rate'], 'integer'],
[['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'unavailable', 'apply_distributions'], 'boolean'],
[['price', 'weight', 'step'], 'number'],
[['photo'], 'file'],
[['name', 'description', 'photo', 'unit'], 'string', 'max' => 255],
[['recipe'], 'string', 'max' => 1000],
['step', 'required', 'message' => 'Champs obligatoire', 'when' => function ($model) {
if ($model->unit != 'piece') {
return true;
}
return false;
}],
[['price_with_tax', 'wording_unit'], 'safe']
];
}
if(isset(self::$unitsArray[$unit]) && isset(self::$unitsArray[$unit][$format])) {
$strUnit = self::$unitsArray[$unit][$format] ;

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'name' => 'Nom',
'description' => 'Description',
'active' => 'Actif',
'photo' => 'Photo',
'price' => 'Prix (€) TTC',
'weight' => 'Poids',
'recipe' => 'Recette',
'monday' => 'Lundi',
'tuesday' => 'Mardi',
'wednesday' => 'Mercredi',
'thursday' => 'Jeudi',
'friday' => 'Vendredi',
'saturday' => 'Samedi',
'sunday' => 'Dimanche',
'order' => 'Ordre',
'quantity_max' => 'Quantité max par défaut',
'unavailable' => 'Épuisé',
'apply_distributions' => 'Appliquer ces modifications dans les distributions futures',
'unit' => 'Unité',
'step' => 'Pas',
'id_tax_rate' => 'TVA'
];
}
return $strUnit ;
}

public function afterFind() {
if ($this->taxRate == null) {
$this->populateRelation('taxRate', GlobalParam::getCurrentProducer()->taxRate);
}

$this->wording_unit = Product::strUnit($this->unit) ;
$this->price_with_tax = $this->getpriceWithTax() ;

parent::afterFind();
}

public function getProductDistribution()
{
return $this->hasMany(ProductDistribution::className(), ['id_product' => 'id']);
}

public function getProductSubscription()
{
return $this->hasMany(ProductSubscription::className(), ['id_product' => 'id']);
}

public function getTaxRate()
{

return $this->hasOne(TaxRate::className(), ['id' => 'id_tax_rate']);
}

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

/**
* Retourne la description du produit.
*
* @return string
*/
public function getDescription()
{
$description = $this->description;
if (isset($this->weight) && is_numeric($this->weight) && $this->weight > 0) {
if ($this->weight >= 1000) {
$description .= ' (' . ($this->weight / 1000) . 'kg)';
} else {
$description .= ' (' . $this->weight . 'g)';
}
}
return $description;
}

/**
* Retourne le libellé (admin) du produit.
* @return type
*/
public function getStrWordingAdmin()
{
return $this->name;
}

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

/**
* Retourne les produits d'une production donnée.
*
* @param integer $idDistribution
* @return array
*/
public static function searchByDistribution($idDistribution)
{
return Product::find()
->leftJoin('product_distribution', 'product.id = product_distribution.id_product')
->where([
'id_producer' => GlobalParam::getCurrentProducerId(),
'product_distribution.id_distribution' => $idDistribution
])
->orderBy('product_distribution.active DESC, product.order ASC')
->all();
}

/**
* Retourne le nombre de produits du producteur courant.
*
* @return integer
*/
public static function count()
{
return self::searchCount();
}

/**
* Retourne le produit "Don".
*
* @return Product
*/
public static function getProductGift()
{
$productGift = Product::find()
->where([
'product.id_producer' => 0
])
->andFilterWhere(['like', 'product.name', 'Don'])
->one();

return $productGift;
}

/**
* Retourne le libellé d'une unité.
*
* @param $format wording_unit, wording, short
* @param $unitInDb Unité stockée en base de données (ex: si g > kg, si mL > L)
* @return $string Libellé de l'unité
*/
public static function strUnit($unit, $format = 'wording_short', $unitInDb = false)
{
$strUnit = '';

if ($unitInDb) {
if ($unit == 'g') {
$unit = 'kg';
}
if ($unit == 'mL') {
$unit = 'L';
}
}

if (isset(self::$unitsArray[$unit]) && isset(self::$unitsArray[$unit][$format])) {
$strUnit = self::$unitsArray[$unit][$format];
}

return $strUnit;
}

public function getPrice()
{
return $this->price ;
}

/**
* Retourne le prix du produit avec taxe
*/
public function getPriceWithTax()
{

return Price::getPriceWithTax($this->price, $this->taxRate->value);
}

public function getTheTaxRate()
{
if($this->id_tax_rate) {
return $this->id_tax_rate ;
}
else {
return GlobalParam::getCurrentProducer()->taxRate->id;
}
}


}

+ 125
- 93
common/models/ProductOrder.php Целия файл

@@ -1,45 +1,47 @@
<?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.
*/
/**
* 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\helpers\Price;
use Yii;
use common\components\ActiveRecordCommon ;
use common\components\ActiveRecordCommon;

/**
* This is the model class for table "product_order".
@@ -53,62 +55,92 @@ use common\components\ActiveRecordCommon ;
class ProductOrder extends ActiveRecordCommon
{

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

/*
* Relations
*/

public function getProduct()
{
return $this->hasOne(Product::className(), ['id' => 'id_product']);
}

/**
* @inheritdoc
*/
public function rules()
{
return [
[['id_order', 'id_product', 'quantity'], 'required'],
[['id_order', 'id_product'], 'integer'],
[['unit'], 'string', 'max' => 255],
[['quantity'], 'number', 'min' => 0]
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'id_order' => 'Commande',
'id_product' => 'Product',
'quantity' => 'Quantité',
'unit' => 'Unité'
];
}
/**
* 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' => ''
] ;
}
/**
* @inheritdoc
*/
public static function tableName()
{
return 'product_order';
}

/*
* Relations
*/

public function getProduct()
{
return $this->hasOne(Product::className(), ['id' => 'id_product']);
}

public function getTaxRate()
{
return $this->hasOne(TaxRate::className(), ['id' => 'id_tax_rate']);
}

/**
* @inheritdoc
*/
public function rules()
{
return [
[['id_order', 'id_product', 'quantity'], 'required'],
[['id_order', 'id_product', 'id_tax_rate'], 'integer'],
[['unit'], 'string', 'max' => 255],
[['quantity'], 'number', 'min' => 0],
[['description'], 'safe']
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'id_order' => 'Commande',
'id_product' => 'Product',
'quantity' => 'Quantité',
'unit' => 'Unité',
'id_tax_rate' => 'Taxe',
'description' => 'Description'
];
}

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

public function afterFind() {
if ($this->taxRate == null) {
$this->populateRelation('taxRate', GlobalParam::getCurrentProducer()->taxRate);
}
parent::afterFind();
}

public function getPrice()
{
return $this->price ;
}

/**
* Retourne le prix du produit avec taxe
*/
public function getPriceWithTax()
{

return Price::getPriceWithTax($this->price, $this->taxRate->value);
}

}

+ 2
- 1
common/models/ProductSearch.php Целия файл

@@ -38,6 +38,7 @@ termes.

namespace common\models ;

use common\helpers\GlobalParam;
use common\models\Product ;

class ProductSearch extends Product
@@ -61,7 +62,7 @@ class ProductSearch extends Product
$query = Product::find()
->with($optionsSearch['with'])
->innerJoinWith($optionsSearch['join_with'], true)
->where(['product.id_producer' => Producer::getId()])
->where(['product.id_producer' => GlobalParam::getCurrentProducerId()])
->orderBy('product.order ASC')
;

+ 91
- 0
common/models/Quotation.php Целия файл

@@ -0,0 +1,91 @@
<?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;

/**
* This is the model class for table "quotation".
*
* @property integer $id
* @property string $name
* @property string $reference
* @property string $date
* @property string $comment
* @property integer $id_user
* @property string $address
* @property string $city
* @property string $postcode
*/
class Quotation extends Document
{

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

/*
* Relations
*/

public function getOrders()
{
return $this->relationOrders('id_quotation') ;
}

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

}

+ 85
- 0
common/models/QuotationSearch.php Целия файл

@@ -0,0 +1,85 @@
<?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\models\Quotation;
use common\helpers\GlobalParam;

class QuotationSearch extends Quotation
{

public function rules()
{
return [
[[], 'safe'],
[['comment', 'address', 'status'], 'string'],
[['id_user'], 'integer'],
[['name', 'reference'], 'string', 'max' => 255],
];
}

public function search($params)
{
$optionsSearch = self::defaultOptionsSearch();

$query = Quotation::find()
->with($optionsSearch['with'])
->where(['quotation.id_producer' => GlobalParam::getCurrentProducerId()])
->orderBy('quotation.status ASC, quotation.reference DESC');

$dataProvider = new ActiveDataProvider([
'query' => $query,
'sort' => ['attributes' => ['name', 'reference', 'date']],
'pagination' => [
'pageSize' => 20,
],
]);

$this->load($params);
if (!$this->validate()) {
return $dataProvider;
}

$query->andFilterWhere(['like', 'quotation.name', $this->name]);
$query->andFilterWhere(['like', 'quotation.reference', $this->reference]);
$query->andFilterWhere(['like', 'quotation.status', $this->status]);

return $dataProvider;
}
}

+ 421
- 441
common/models/Subscription.php Целия файл

@@ -1,51 +1,52 @@
<?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.
*/
/**
* 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 common\components\ActiveRecordCommon ;
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 ;
use common\models\User;

/**
* This is the model class for table "commande_auto".
@@ -70,426 +71,405 @@ use common\models\User ;
*/
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','comment'], '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)
{
// 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;
if(strlen($this->comment)) {
$order->comment = $this->comment ;
}
$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();
}
/**
* @inheritdoc
*/
public static function tableName()
{
return 'subscription';
}
}
/**
* 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);
}
}

/**
* @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', 'comment'], 'safe'],
];
}
}
/**
* 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 ;
}
}

/**
* @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'
];
}
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;
}

/*
* Relations
*/

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

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 ;
}
public function getProducer()
{
return $this->hasOne(
Producer::className(),
['id' => 'id_producer']
);
}
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)) ;

public function getPointSale()
{
return $this->hasOne(
PointSale::className(),
['id' => 'id_point_sale']
);
}
$incomingDistributions->orderBy('date ASC') ;
$incomingDistributions->params($params) ;
$incomingDistributionsArray = $incomingDistributions->all() ;
$matchedIncomingDistributionsArray = [] ;
foreach($incomingDistributionsArray as $incomingDistribution) {
if($this->matchWith($incomingDistribution->date)) {
$matchedIncomingDistributionsArray[] = $incomingDistribution ;
}

public function getProductSubscription()
{
return $this->hasMany(
ProductSubscription::className(),
['id_subscription' => 'id']
)->with('product');
}
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' ;

/**
* 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'
];
}
else {
$conditionDistributionDate = 'distribution.date >= :date_today' ;

/**
* 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->status = 'tmp-order' ;
if (strlen($this->comment)) {
$order->comment = $this->comment;
}

$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->product->unit;
$productOrder->step = $productSubscription->product->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' => 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);
}
}

}
}

/**
* 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;
}
$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 ;

/**
* 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;
}

$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()
);
/**
* 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;
}
}
ProductOrder::deleteAll(['id_order' => $order->id]) ;
$order->delete() ;
}

return false;
}
}
public function updateIncomingDistributions($update = false)
{
$matchedDistributionsArray = $this->searchMatchedIncomingDistributions() ;
if($update) {
$this->deleteOrdersIncomingDistributions() ;

/**
* Recherche les distributions futures où l'abonnement peut s'appliquer.
*
* @return array
*/
public function searchMatchedIncomingDistributions()
{
$producer = GlobalParam::getCurrentProducer();
$params = [
':date_earliest_order' => $producer->getEarliestDateOrder(),
':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();

$matchedIncomingDistributionsArray = [];
foreach ($incomingDistributionsArray as $incomingDistribution) {
if ($this->matchWith($incomingDistribution->date)) {
$matchedIncomingDistributionsArray[] = $incomingDistribution;
}
}

return $matchedIncomingDistributionsArray;
}
if(count($matchedDistributionsArray)) {
foreach($matchedDistributionsArray as $distribution) {
$this->add($distribution->date) ;
}

public function deleteOrdersIncomingDistributions()
{
$params = [
':id_producer' => GlobalParam::getCurrentProducerId(),
':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();
}
}
}
}
/**
* 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 ;

public function updateIncomingDistributions($update = false)
{
$matchedDistributionsArray = $this->searchMatchedIncomingDistributions();

if ($update) {
$this->deleteOrdersIncomingDistributions();
}

if (count($matchedDistributionsArray)) {
foreach ($matchedDistributionsArray as $distribution) {
$this->add($distribution->date);
}
}
}
}
return false ;
}


}

Някои файлове не бяха показани, защото твърде много файлове са промени

Loading…
Отказ
Запис