Guillaume Bourgeois 2 лет назад
Родитель
Сommit
5c02e17fe2
26 измененных файлов: 796 добавлений и 595 удалений
  1. +6
    -1
      .gitignore
  2. +15
    -0
      README.md
  3. +7
    -4
      backend/controllers/CronController.php
  4. +1
    -1
      backend/views/document/_download_product_line.php
  5. +5
    -2
      backend/views/document/download.php
  6. +11
    -7
      backend/views/producer/update.php
  7. +1
    -5
      backend/views/user/_form.php
  8. +111
    -100
      backend/views/user/index.php
  9. +13
    -12
      backend/web/css/document/download.css
  10. +6
    -6
      backend/web/js/vuejs/document-form.js
  11. +3
    -3
      backend/web/sass/document/download.scss
  12. +6
    -2
      common/models/Producer.php
  13. +427
    -424
      common/models/Product.php
  14. +10
    -3
      common/models/User.php
  15. +1
    -0
      common/models/UserSearch.php
  16. +47
    -0
      console/migrations/m220817_074240_add_foreign_keys_documents.php
  17. +20
    -0
      console/migrations/m220823_083001_add_option_document_display_product_description.php
  18. +45
    -0
      console/migrations/m220823_084928_add_option_notify_producer_order_summary.php
  19. +1
    -0
      frontend/controllers/SiteController.php
  20. +13
    -1
      frontend/models/SignupForm.php
  21. +2
    -2
      producer/controllers/OrderController.php
  22. +15
    -5
      producer/views/order/order.php
  23. +10
    -10
      producer/web/css/screen.css
  24. +1
    -0
      producer/web/js/vuejs/order-order.js
  25. +1
    -1
      producer/web/sass/order/_order.scss
  26. +18
    -6
      setPermissionsOpenDistrib.sh

+ 6
- 1
.gitignore Просмотреть файл

@@ -33,5 +33,10 @@ common/config/bootstrap.php


backend/web/assets/*
backend/runtime/logs/*

producer/web/assets/*
frontend/web/assets/*
producer/runtime/logs/*

frontend/web/assets/*
frontend/runtime/logs/*

+ 15
- 0
README.md Просмотреть файл

@@ -0,0 +1,15 @@
# Open Distrib - Readme
### Procédure d'instalation
* Faire un clone du projet depuis https://forge.laclic.fr/Laclic/Opendistrib.git
* Télécharger et installer une base de donné sur votre serveur local
* Télécharger le dossier opendistrib-config.zip depuis le nuage (nuage.laclic.fr) dossier : laclic/projets/opendistrib/Ressources
* Modifier configuration dans common/config/main-local.php
* Ajouter nom/utilisateur/mdp pour la base de donnée
* Appliquer la configuration au mailer transport ou passer useFileTransport à true (à tester)
* Modifier configuration dans common/config/bootstrap.php
* Modifier baseUrl en fonction de l'emplacement du projet et de votre configuration apache.
* Vérifier que les modules RewriteEngine et RewriteEngine sont activés pour votre apache
* Vérifier le dossier de votre projet à l'option AllowOverride à all sur votre configuration apache
* Éxécuter le script setPermissionsOpenDistrib.sh
* Faire un composer install
* Prendre un thé ou un café et enjoy !

+ 7
- 4
backend/controllers/CronController.php Просмотреть файл

@@ -212,7 +212,8 @@ class CronController extends BackendController
/*
* Envoi des commandes par email au producteur
*/
if (!strlen($forceDate)) {

if (!strlen($forceDate) && Producer::getConfig('option_notify_producer_order_summary', $producer->id)) {
$arrayOrders = Order::searchAll([
'distribution.date' => $date,
'distribution.id_producer' => $producer->id
@@ -263,9 +264,11 @@ class CronController extends BackendController
}

if ($producer->active) {
$messageLog = $producer->name . ' : Distribution du ' . $date . ', ' . count(
$arrayOrders
) . ' commande(s) enregistrée(s), ' . $countOrders . ' commande(s) payée(s), ' . ($mailOrdersSend ? 'Récapitulatif de commandes envoyé' : 'Aucun email envoyé');
$strCountOrders = 0;
if ($arrayOrders && is_array($arrayOrders)) {
$strCountOrders = count($arrayOrders);
}
$messageLog = $producer->name . ' : Distribution du ' . $date . ', ' . $strCountOrders . ' commande(s) enregistrée(s), ' . $countOrders . ' commande(s) payée(s), ' . ($mailOrdersSend ? 'Récapitulatif de commandes envoyé' : 'Aucun email envoyé');
/*Yii::$app->mailer->compose()
->setFrom('contact@opendistrib.net')
->setTo('contact@opendistrib.net')

+ 1
- 1
backend/views/document/_download_product_line.php Просмотреть файл

@@ -4,7 +4,7 @@
<?php if($productOrder->unit == 'piece' && isset($productOrder->product->weight) && $productOrder->product->weight): ?>
<span class="weight"> / <?= $productOrder->product->weight ?> g</span>
<?php endif; ?>
<?php if(strlen($productOrder->product->description)): ?>
<?php if(strlen($productOrder->product->description) && $displayProductDescription): ?>
<br /><small><?= Html::encode($productOrder->product->description) ?></small>
<?php endif; ?>
</td>

+ 5
- 2
backend/views/document/download.php Просмотреть файл

@@ -1,6 +1,7 @@
<?php

$displayPrices = Yii::$app->controller->getClass() != 'DeliveryNote' || (Yii::$app->controller->getClass() == 'DeliveryNote' && Producer::getConfig('document_display_prices_delivery_note')) ;
$displayProductDescription = Producer::getConfig('document_display_product_description');

?>

@@ -99,7 +100,8 @@ $displayPrices = Yii::$app->controller->getClass() != 'DeliveryNote' || (Yii::$a
'document' => $document,
'productOrder' => $productOrder,
'displayOrders' => true,
'displayPrices' => $displayPrices
'displayPrices' => $displayPrices,
'displayProductDescription' => $displayProductDescription
]) ?>
<?php endforeach; ?>
<?php endforeach; ?>
@@ -109,7 +111,8 @@ $displayPrices = Yii::$app->controller->getClass() != 'DeliveryNote' || (Yii::$a
<?= $this->render('_download_product_line', [
'document' => $document,
'productOrder' => $productOrder,
'displayPrices' => $displayPrices
'displayPrices' => $displayPrices,
'displayProductDescription' => $displayProductDescription
]) ?>
<?php endforeach; ?>
<?php endforeach; ?>

+ 11
- 7
backend/views/producer/update.php Просмотреть файл

@@ -227,12 +227,12 @@ $this->addBreadcrumb($this->getTitle()) ;
<?= $form->field($model, 'order_infos')
->textarea(['rows' => 6])
->hint('Affichées au client lors de sa commande')?>
<?= $form->field($model, 'option_allow_user_gift')
->dropDownList([
0 => 'Non',
1 => 'Oui',
], []) ; ?>
<?= $form->field($model, 'option_notify_producer_order_summary')
->dropDownList([
0 => 'Non',
1 => 'Oui',
], []) ; ?>
<?= $form->field($model, 'option_behavior_cancel_order')
->dropDownList([
@@ -290,7 +290,7 @@ $this->addBreadcrumb($this->getTitle()) ;
1 => 'Oui'
], []); ?>

<?= $form->field($model, 'option_allow_order_guest')
<?php echo $form->field($model, 'option_allow_order_guest')
->dropDownList([
0 => 'Non',
1 => 'Oui'
@@ -445,6 +445,10 @@ $this->addBreadcrumb($this->getTitle()) ;
0 => 'Non',
1 => 'Oui'
]) ; ?>
<?= $form->field($model, 'document_display_product_description')->dropDownList([
0 => 'Non',
1 => 'Oui'
]) ; ?>
<?= $form->field($model, 'document_infos_bottom')
->textarea(['rows' => 15]) ?>
<?= $form->field($model, 'document_infos_quotation')

+ 1
- 5
backend/views/user/_form.php Просмотреть файл

@@ -52,11 +52,7 @@ use common\models\ProductPrice ;
]); ?>

<?= $form->field($model, 'type')
->dropDownList([
User::TYPE_INDIVIDUAL => 'Particulier',
User::TYPE_LEGAL_PERSON => 'Personne morale',
User::TYPE_GUEST => 'Visiteur'
], [
->dropDownList(User::getTypeChoicesArray(), [
'v-model' => 'type'
]) ; ?>
<?= $form->field($model, 'name_legal_person', ['options' => ['v-show' => "type == 'legal-person'"]])->textInput() ?>

+ 111
- 100
backend/views/user/index.php Просмотреть файл

@@ -50,119 +50,130 @@ $this->addButton(['label' => 'Nouvel utilisateur <span class="glyphicon glyphico
<?=

$this->render('_menu', [
'idPointSaleActive' => $idPointSaleActive,
'sectionInactiveUsers' => $sectionInactiveUsers,
'sectionSubscribers' => $sectionSubscribers,
'pointsSaleArray' => $pointsSaleArray,
'section' => 'index'
'idPointSaleActive' => $idPointSaleActive,
'sectionInactiveUsers' => $sectionInactiveUsers,
'sectionSubscribers' => $sectionSubscribers,
'pointsSaleArray' => $pointsSaleArray,
'section' => 'index'
]);

?>

<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
[
'attribute' => 'username',
'label' => 'Nom',
'value' => function ($model) {
if (isset($model['name_legal_person']) && strlen($model['name_legal_person'])) {
return $model['name_legal_person'];
} else {
return $model['lastname'] . ' ' . $model['name'];
}
}
],
[
'attribute' => 'contacts',
'header' => 'Contacts',
'format' => 'raw',
'value' => function ($model) {
$html = '';
if (strlen($model['phone'])) {
$html .= $model['phone'];
}
if (strlen($model['phone']) && strlen($model['email'])) {
$html .= '<br />';
}
if (strlen($model['email'])) {
$html .= $model['email'];
}
return $html;
}
],
[
'class' => 'yii\grid\ActionColumn',
'header' => 'Commandes',
'template' => '{orders}',
'headerOptions' => ['class' => 'actions'],
'buttons' => [
'orders' => function ($url, $model) {
$url = Yii::$app->urlManager->createUrl(['user/orders', 'id' => $model['id']]);
$countOrders = Order::searchCount([
'id_user' => $model['id']
], ['conditions' => 'date_delete IS NULL']);
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
[
'attribute' => 'username',
'label' => 'Nom',
'value' => function ($model) {
if (isset($model['name_legal_person']) && strlen($model['name_legal_person'])) {
return $model['name_legal_person'];
} else {
return $model['lastname'] . ' ' . $model['name'];
}
}
],
[
'attribute' => 'type',
'label' => 'Type',
'value' => function ($model) {
$typeArray = User::getTypeChoicesArray();
if(isset($typeArray[$model['type']])) {
return $typeArray[$model['type']];
}
return '';
}
],
[
'attribute' => 'contacts',
'header' => 'Contacts',
'format' => 'raw',
'value' => function ($model) {
$html = '';
if (strlen($model['phone'])) {
$html .= $model['phone'];
}
if (strlen($model['phone']) && strlen($model['email'])) {
$html .= '<br />';
}
if (strlen($model['email'])) {
$html .= $model['email'];
}
return $html;
}
],
[
'class' => 'yii\grid\ActionColumn',
'header' => 'Commandes',
'template' => '{orders}',
'headerOptions' => ['class' => 'actions'],
'buttons' => [
'orders' => function ($url, $model) {
$url = Yii::$app->urlManager->createUrl(['user/orders', 'id' => $model['id']]);
$countOrders = Order::searchCount([
'id_user' => $model['id']
], ['conditions' => 'date_delete IS NULL']);

$html = '';
if ($countOrders) {
$html .= Html::a('<span class="glyphicon glyphicon-eye-open"></span> ' . $countOrders, $url, [
'title' => Yii::t('app', 'Commandes'), 'class' => 'btn btn-default '
]);;
} else {
$html .= 'Aucune commande';
}
$html = '';
if ($countOrders) {
$html .= Html::a('<span class="glyphicon glyphicon-eye-open"></span> ' . $countOrders, $url, [
'title' => Yii::t('app', 'Commandes'), 'class' => 'btn btn-default '
]);;
} else {
$html .= 'Aucune commande';
}

return $html;
},
],
],
[
'attribute' => 'credit',
'format' => 'raw',
'value' => function ($model) use ($producer) {
return $html;
},
],
],
[
'attribute' => 'credit',
'format' => 'raw',
'value' => function ($model) use ($producer) {

$userProducer = UserProducer::searchOne([
'id_user' => $model->id
]);
$credit = $userProducer ? $userProducer->credit : 0;
$classBtnCredit = $userProducer->credit_active ? 'btn-success' : 'btn-default';
$userProducer = UserProducer::searchOne([
'id_user' => $model->id
]);
$credit = $userProducer ? $userProducer->credit : 0;
$classBtnCredit = $userProducer->credit_active ? 'btn-success' : 'btn-default';

$html = '<div class="input-group">
$html = '<div class="input-group">
<input type="text" class="form-control input-credit" readonly="readonly" value="' . number_format($credit, 2) . ' €" placeholder="">
<span class="input-group-btn">
' . Html::a(
'<span class="glyphicon glyphicon-euro"></span>',
Yii::$app->urlManager->createUrl(['user/credit', 'id' => $model->id]),
[
'title' => 'Crédit',
'class' => 'btn ' . $classBtnCredit
]
) . '
'<span class="glyphicon glyphicon-euro"></span>',
Yii::$app->urlManager->createUrl(['user/credit', 'id' => $model->id]),
[
'title' => 'Crédit',
'class' => 'btn ' . $classBtnCredit
]
) . '
</span>
</div>';
return $html;
}
],
[
'class' => 'yii\grid\ActionColumn',
'template' => '{update} {delete}',
'headerOptions' => ['class' => 'column-actions'],
'contentOptions' => ['class' => 'column-actions'],
'buttons' => [
'update' => function ($url, $model) {
$url = Yii::$app->urlManager->createUrl(['user/update', 'id' => $model->id]);
$user = User::find()->with('userProducer')->where(['id' => $model->id])->one();
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>', Yii::$app->urlManager->createUrl(array_merge(['user/delete', 'id' => $model->id], Yii::$app->getRequest()->getQueryParams())), [
'title' => Yii::t('app', 'Supprimer'), 'class' => 'btn btn-default btn-confirm-delete'
]);
}
],
],
return $html;
}
],
[
'class' => 'yii\grid\ActionColumn',
'template' => '{update} {delete}',
'headerOptions' => ['class' => 'column-actions'],
'contentOptions' => ['class' => 'column-actions'],
'buttons' => [
'update' => function ($url, $model) {
$url = Yii::$app->urlManager->createUrl(['user/update', 'id' => $model->id]);
$user = User::find()->with('userProducer')->where(['id' => $model->id])->one();
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>', Yii::$app->urlManager->createUrl(array_merge(['user/delete', 'id' => $model->id], Yii::$app->getRequest()->getQueryParams())), [
'title' => Yii::t('app', 'Supprimer'), 'class' => 'btn btn-default btn-confirm-delete'
]);
}
],
],
],
]); ?>

+ 13
- 12
backend/web/css/document/download.css Просмотреть файл

@@ -10,48 +10,48 @@ body {
/* line 14, ../../sass/document/download.scss */
.document-download #block-addresses .producer {
text-align: left;
margin-bottom: 20px;
margin-bottom: 5px;
}
/* line 19, ../../sass/document/download.scss */
/* line 18, ../../sass/document/download.scss */
.document-download #block-addresses .producer .logo {
margin-bottom: 20px;
}
/* line 27, ../../sass/document/download.scss */
/* line 26, ../../sass/document/download.scss */
.document-download #block-addresses .user {
text-align: right;
}
/* line 32, ../../sass/document/download.scss */
/* line 31, ../../sass/document/download.scss */
.document-download #block-infos-document {
padding-top: 30px;
padding-top: 15px;
}
/* line 35, ../../sass/document/download.scss */
/* line 34, ../../sass/document/download.scss */
.document-download #block-infos-document .date {
padding-bottom: 10px;
}
/* line 38, ../../sass/document/download.scss */
/* line 37, ../../sass/document/download.scss */
.document-download #block-infos-document .reference {
padding-bottom: 10px;
font-size: 15px;
font-weight: bold;
}
/* line 43, ../../sass/document/download.scss */
/* line 42, ../../sass/document/download.scss */
.document-download #block-infos-document .reference .block-is-draft {
border: solid 2px black;
padding: 10px;
text-transform: uppercase;
}
/* line 54, ../../sass/document/download.scss */
/* line 53, ../../sass/document/download.scss */
.document-download #block-no-product {
font-weight: bold;
border: solid 2px black;
text-transform: uppercase;
padding: 10px;
}
/* line 61, ../../sass/document/download.scss */
/* line 60, ../../sass/document/download.scss */
.document-download #block-products {
padding-top: 20px;
}
/* line 64, ../../sass/document/download.scss */
/* line 63, ../../sass/document/download.scss */
.document-download #block-products table {
width: 100%;
padding: 0px;
@@ -60,12 +60,13 @@ body {
border-right: solid 1px #c0c0c0;
border-collapse: collapse;
}
/* line 72, ../../sass/document/download.scss */
/* line 71, ../../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;
font-size: 13px;
}
/* line 78, ../../sass/document/download.scss */
.document-download #block-products table td.align-left, .document-download #block-products table th.align-left {

+ 6
- 6
backend/web/js/vuejs/document-form.js Просмотреть файл

@@ -165,7 +165,7 @@ var app = new Vue({
getBestProductPrice: function (idProduct, theQuantity) {
var product = this.getProductById(idProduct);

var thePriceWithTax = 9999;
var thePrice = 9999;
var pricesArray = product.prices;
var unitCoefficient = product.unit_coefficient;

@@ -175,20 +175,20 @@ var app = new Vue({

for (var i = 0; i < pricesArray.length; i++) {
if(pricesArray[i]) {
var priceWithTax = pricesArray[i].price_with_tax;
var price = pricesArray[i].price;
var fromQuantity = pricesArray[i].from_quantity;

if (priceWithTax < thePriceWithTax && fromQuantity <= theQuantity) {
thePriceWithTax = priceWithTax;
if (price < thePrice && fromQuantity <= theQuantity) {
thePrice = price;
}
}
}

if (thePriceWithTax == 9999) {
if (thePrice == 9999) {
return 0;
}
else {
return thePriceWithTax;
return thePrice;
}
},
changeQuantityProductAdd: function (quantity) {

+ 3
- 3
backend/web/sass/document/download.scss Просмотреть файл

@@ -12,9 +12,8 @@ body {
#block-addresses {

.producer {

text-align: left ;
margin-bottom: 20px ;
margin-bottom: 5px ;

.logo {
margin-bottom: 20px ;
@@ -30,7 +29,7 @@ body {
}

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

.date {
padding-bottom: 10px ;
@@ -74,6 +73,7 @@ body {
border-top: solid 1px $border-color ;
border-left: solid 1px $border-color ;
font-family: $font-family ;
font-size: 13px;

&.align-left {
text-align: left ;

+ 6
- 2
common/models/Producer.php Просмотреть файл

@@ -222,6 +222,7 @@ class Producer extends ActiveRecordCommon
'document_display_orders_invoice',
'document_display_orders_delivery_note',
'document_display_prices_delivery_note',
'document_display_product_description',
'option_email_confirm',
'option_email_confirm_producer',
'option_csv_export_all_products',
@@ -230,7 +231,8 @@ class Producer extends ActiveRecordCommon
'option_allow_order_guest',
'option_delivery',
'option_display_export_grid',
'option_stripe_mode_test'
'option_stripe_mode_test',
'option_notify_producer_order_summary'
],
'boolean'
],
@@ -359,7 +361,9 @@ class Producer extends ActiveRecordCommon
'option_allow_order_guest' => 'Autoriser les visiteurs à passer commande (création de compte à la fin du tunnel)',
'option_order_entry_point' => 'Point d\'entrée par point de vente ou par date',
'option_delivery' => 'Proposer la livraison à domicile',
'option_display_export_grid' => 'Afficher l\'export grille dans les distributions'
'option_display_export_grid' => 'Afficher l\'export grille dans les distributions',
'document_display_product_description' => 'Documents : afficher la description des produits',
'option_notify_producer_order_summary' => 'Recevoir les récapitulatifs de commande par email'
];
}


+ 427
- 424
common/models/Product.php Просмотреть файл

@@ -60,478 +60,481 @@ use common\components\ActiveRecordCommon;
*/
class Product extends ActiveRecordCommon
{
public $total = 0;
public $apply_distributions = true;

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

public $pointsSale;

public static $unitsArray = [
'piece' => [
'unit' => 'piece',
'wording_unit' => 'la pièce',
'wording' => 'pièce(s)',
'wording_short' => 'p.',
'coefficient' => 1
],
'g' => [
'ref_unit' => 'kg',
'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' => [
'ref_unit' => 'L',
'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 $total = 0;
public $apply_distributions = true;

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

public $pointsSale;

public static $unitsArray = [
'piece' => [
'unit' => 'piece',
'wording_unit' => 'la pièce',
'wording' => 'pièce(s)',
'wording_short' => 'p.',
'coefficient' => 1
],
'g' => [
'ref_unit' => 'kg',
'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' => [
'ref_unit' => 'L',
'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', 'id_producer', 'id_tax_rate', 'id_product_category'], 'integer'],
[['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'unavailable', 'apply_distributions', 'available_on_points_sale'], 'boolean'],
[['price', 'weight', 'step', 'quantity_max', 'quantity_max_monday', 'quantity_max_tuesday', 'quantity_max_wednesday', 'quantity_max_thursday', 'quantity_max_friday', 'quantity_max_saturday', 'quantity_max_sunday'], 'number'],
[['photo'], 'file'],
[['name', 'reference', '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', 'pointsSale'], 'safe']
];

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

/**
* @inheritdoc
*/
public function rules()
{
return [
[['name', 'id_producer'], 'required'],
[['active', 'order', 'id_producer', 'id_tax_rate', 'id_product_category'], 'integer'],
[['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'unavailable', 'apply_distributions', 'available_on_points_sale'], 'boolean'],
[['price', 'weight', 'step', 'quantity_max', 'quantity_max_monday', 'quantity_max_tuesday', 'quantity_max_wednesday', 'quantity_max_thursday', 'quantity_max_friday', 'quantity_max_saturday', 'quantity_max_sunday'], 'number'],
[['photo'], 'file'],
[['name', 'reference', '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', 'pointsSale'], 'safe']
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'name' => 'Nom',
'reference' => 'Référence',
'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',
'quantity_max_monday' => 'Quantité max : lundi',
'quantity_max_tuesday' => 'Quantité max : mardi',
'quantity_max_wednesday' => 'Quantité max : mercredi',
'quantity_max_thursday' => 'Quantité max : jeudi',
'quantity_max_friday' => 'Quantité max : vendredi',
'quantity_max_saturday' => 'Quantité max : samedi',
'quantity_max_sunday' => 'Quantité max : dimanche',
'unavailable' => 'Épuisé',
'apply_distributions' => 'Appliquer ces modifications dans les distributions futures',
'unit' => 'Unité',
'step' => 'Pas',
'id_tax_rate' => 'TVA',
'id_product_category' => 'Catégorie',
'available_on_points_sale' => 'Par défaut'
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'name' => 'Nom',
'reference' => 'Référence',
'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',
'quantity_max_monday' => 'Quantité max : lundi',
'quantity_max_tuesday' => 'Quantité max : mardi',
'quantity_max_wednesday' => 'Quantité max : mercredi',
'quantity_max_thursday' => 'Quantité max : jeudi',
'quantity_max_friday' => 'Quantité max : vendredi',
'quantity_max_saturday' => 'Quantité max : samedi',
'quantity_max_sunday' => 'Quantité max : dimanche',
'unavailable' => 'Épuisé',
'apply_distributions' => 'Appliquer ces modifications dans les distributions futures',
'unit' => 'Unité',
'step' => 'Pas',
'id_tax_rate' => 'TVA',
'id_product_category' => 'Catégorie',
'available_on_points_sale' => 'Par défaut'
];
}

public function afterFind()
{
if ($this->taxRate == null) {
$producer = Producer::searchOne(['id' => GlobalParam::getCurrentProducerId()]);
if ($producer) {
$this->populateRelation('taxRate', $producer->taxRate);
}
}

public function afterFind() {
if ($this->taxRate == null) {
$producer = Producer::searchOne(['id' => GlobalParam::getCurrentProducerId()]) ;
if($producer) {
$this->populateRelation('taxRate', $producer->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']);
}

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

public function getProductCategory()
{
return $this->hasOne(ProductCategory::className(), ['id' => 'id_product_category']);
}

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

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

public function isAvailableOnPointSale($pointSale)
{
// disponible par défaut
if ($this->available_on_points_sale) {
foreach ($this->productPointSale as $productPointSale) {
if ($pointSale->id == $productPointSale->id_point_sale
//&& $productPointSale->id_product == $this->id
&& !$productPointSale->available) {
return false;
}
}

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

public function getProductPrice()
{
return $this->hasMany(ProductPrice::className(), ['id_product' => 'id']);
}
return true;
} // indisponible par défaut
else {
foreach ($this->productPointSale as $productPointSale) {
if ($pointSale->id == $productPointSale->id_point_sale
//&& $productPointSale->id_product == $this->id
&& $productPointSale->available) {
return true;
}
}

public function getProductCategory()
{
return $this->hasOne(ProductCategory::className(), ['id' => 'id_product_category']) ;
return false;
}

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

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

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

public function getRefUnit($unit)
{
if (isset(self::$unitsArray[$unit]) && isset(self::$unitsArray[$unit]['ref_unit'])) {
return self::$unitsArray[$unit]['ref_unit'];
}

public function isAvailableOnPointSale($pointSale)
{
// disponible par défaut
if($this->available_on_points_sale) {
foreach($this->productPointSale as $productPointSale) {
if($pointSale->id == $productPointSale->id_point_sale
//&& $productPointSale->id_product == $this->id
&& !$productPointSale->available) {
return false;
}
}

return true;
return $unit;
}

/**
* 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';
}
// indisponible par défaut
else {
foreach($this->productPointSale as $productPointSale) {
if($pointSale->id == $productPointSale->id_point_sale
//&& $productPointSale->id_product == $this->id
&& $productPointSale->available) {
return true;
}
}

return false;
if ($unit == 'mL') {
$unit = 'L';
}
}

/**
* 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;
if (isset(self::$unitsArray[$unit]) && isset(self::$unitsArray[$unit][$format])) {
$strUnit = self::$unitsArray[$unit][$format];
}

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

/**
* 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);
}
public function getPriceArray($user, $pointSale)
{
$priceArray = [];

/**
* 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();
$userProducer = null;
if ($user) {
$userProducer = UserProducer::searchOne([
'id_user' => $user->id,
]);
}

/**
* Retourne le nombre de produits du producteur courant.
*
* @return integer
*/
public static function count()
{
return self::searchCount();
// specific prices
$specificPriceArray = $this->getSpecificPricesFilterByPriorityMatch(
$this->productPrice,
$user,
$pointSale
);

foreach ($specificPriceArray as $specificPrice) {
$priceArray[] = [
'from_quantity' => $specificPrice->from_quantity ? $specificPrice->from_quantity : 0,
'price' => $this->getPrice([
'user' => $user,
'user_producer' => $userProducer,
'point_sale' => $pointSale,
'quantity' => $specificPrice->from_quantity
]),
'price_with_tax' => $this->getPriceWithTax([
'user' => $user,
'user_producer' => $userProducer,
'point_sale' => $pointSale,
'quantity' => $specificPrice->from_quantity
]),
];
}

/**
* 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;
if (!$this->hasPriceWithQuantityZero($priceArray)) {
// base price
$priceArray[] = [
'from_quantity' => 0,
'price_with_tax' => $this->getPriceWithTax(),
];
}

public function getRefUnit($unit)
{
if(isset(self::$unitsArray[$unit]) && isset(self::$unitsArray[$unit]['ref_unit'])) {
return self::$unitsArray[$unit]['ref_unit'];
usort($priceArray, function ($a, $b) {
if ($a['price_with_tax'] < $b['price_with_tax']) {
return 1;
} elseif ($a['price_with_tax'] > $b['price_with_tax']) {
return -1;
} else {
return 0;
}
});

return $unit;
}

/**
* 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';
}
}
return $priceArray;
}

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

return $strUnit;
public function hasPriceWithQuantityZero($priceArray)
{
foreach ($priceArray as $price) {
if ($price['from_quantity'] == 0) {
return true;
}
}

public function getPriceArray($user, $pointSale)
{
$priceArray = [];
return false;
}

$userProducer = null;
if($user) {
$userProducer = UserProducer::searchOne([
'id_user' => $user->id,
]);
}
public function getSpecificPricesFilterByPriorityMatch($specificPrices, $user, $pointSale)
{
$priorityMatchSpecificPrice = ProductPrice::getPriorityMatchOfSpecificPriceArray($specificPrices, $user, $pointSale);
$specificPricesFilter = [];

// specific prices
$specificPriceArray = $this->getSpecificPricesFilterByPriorityMatch(
$this->productPrice,
$user,
$pointSale
);

foreach ($specificPriceArray as $specificPrice) {
$priceArray[] = [
'from_quantity' => $specificPrice->from_quantity ? $specificPrice->from_quantity : 0,
'price_with_tax' => $this->getPriceWithTax([
'user' => $user,
'user_producer' => $userProducer,
'point_sale' => $pointSale,
'quantity' => $specificPrice->from_quantity
]),
];
}
foreach ($specificPrices as $keySpecificPrice => $specificPrice) {
if (($priorityMatchSpecificPrice && $specificPrice->$priorityMatchSpecificPrice($user, $pointSale))
|| $specificPrice->matchFromQuantityOnly()) {

if(!$this->hasPriceWithQuantityZero($priceArray)) {
// base price
$priceArray[] = [
'from_quantity' => 0,
'price_with_tax' => $this->getPriceWithTax(),
];
$specificPricesFilter[] = $specificPrice;
}

usort($priceArray, function($a, $b) {
if($a['price_with_tax'] < $b['price_with_tax']) {
return 1;
}
elseif($a['price_with_tax'] > $b['price_with_tax']) {
return -1;
}
else {
return 0;
}
});

return $priceArray;
}

public function hasPriceWithQuantityZero($priceArray)
{
foreach($priceArray as $price) {
if($price['from_quantity'] == 0) {
return true;
return $specificPricesFilter;
}

public function getPrice($params = [])
{
$specificPrices = $this->productPrice;

$user = isset($params['user']) ? $params['user'] : false;
$userProducer = isset($params['user_producer']) ? $params['user_producer'] : false;
$pointSale = isset($params['point_sale']) ? $params['point_sale'] : false;
$quantity = (isset($params['quantity']) && $params['quantity']) ? $params['quantity'] : 1;

if ($specificPrices && ($user || $pointSale)) {
$specificPrices = $this->getSpecificPricesFilterByPriorityMatch($specificPrices, $user, $pointSale);
$bestPrice = 9999;
foreach ($specificPrices as $specificPrice) {
$fromQuantity = $specificPrice->from_quantity;
if ((($fromQuantity && $fromQuantity <= $quantity) || !$fromQuantity)
&& $specificPrice->price < $bestPrice) {
$bestPrice = $specificPrice->price;
}
}

return false;
}

public function getSpecificPricesFilterByPriorityMatch($specificPrices, $user, $pointSale)
{
$priorityMatchSpecificPrice = ProductPrice::getPriorityMatchOfSpecificPriceArray($specificPrices, $user, $pointSale);
$specificPricesFilter = [];

foreach($specificPrices as $keySpecificPrice => $specificPrice) {
if(($priorityMatchSpecificPrice && $specificPrice->$priorityMatchSpecificPrice($user, $pointSale))
|| $specificPrice->matchFromQuantityOnly()) {

$specificPricesFilter[] = $specificPrice;
}
if ($bestPrice != 9999) {
return $bestPrice;
}

return $specificPricesFilter;
}

public function getPrice($params = [])
{
$specificPrices = $this->productPrice ;

$user = isset($params['user']) ? $params['user'] : false ;
$userProducer = isset($params['user_producer']) ? $params['user_producer'] : false ;
$pointSale = isset($params['point_sale']) ? $params['point_sale'] : false ;
$quantity = (isset($params['quantity']) && $params['quantity']) ? $params['quantity'] : 1 ;

if($specificPrices && ($user || $pointSale)) {
$specificPrices = $this->getSpecificPricesFilterByPriorityMatch($specificPrices, $user, $pointSale);
$bestPrice = 9999;
foreach($specificPrices as $specificPrice) {
$fromQuantity = $specificPrice->from_quantity;
if((($fromQuantity && $fromQuantity <= $quantity) || !$fromQuantity)
&& $specificPrice->price < $bestPrice) {
$bestPrice = $specificPrice->price;
}
}

if($bestPrice != 9999) {
return $bestPrice;
}
}

if($userProducer && $userProducer->product_price_percent) {
return $this->price * (1 + $userProducer->product_price_percent / 100) ;
}

if($pointSale && $pointSale->product_price_percent) {
return $this->price * (1 + $pointSale->product_price_percent / 100) ;
}

return $this->price ;
if ($userProducer && $userProducer->product_price_percent) {
return $this->price * (1 + $userProducer->product_price_percent / 100);
}

/**
* Retourne le prix du produit avec taxe
*/
public function getPriceWithTax($params = [])
{
$taxRateValue = $this->taxRate ? $this->taxRate->value : 0 ;
return Price::getPriceWithTax($this->getPrice($params), $taxRateValue);
if ($pointSale && $pointSale->product_price_percent) {
return $this->price * (1 + $pointSale->product_price_percent / 100);
}

public function getTheTaxRate()
{
if($this->id_tax_rate) {
return $this->id_tax_rate ;
}
else {
return GlobalParam::getCurrentProducer()->taxRate->id;
}
return $this->price;
}

/**
* Retourne le prix du produit avec taxe
*/
public function getPriceWithTax($params = [])
{
$taxRateValue = $this->taxRate ? $this->taxRate->value : 0;
return Price::getPriceWithTax($this->getPrice($params), $taxRateValue);
}

public function getTheTaxRate()
{
if ($this->id_tax_rate) {
return $this->id_tax_rate;
} else {
return GlobalParam::getCurrentProducer()->taxRate->id;
}
}

public function getNameExport()
{
$producer = GlobalParam::getCurrentProducer() ;
if($producer->option_export_display_product_reference && $this->reference && strlen($this->reference) > 0) {
return $this->reference ;
}

return $this->name ;
public function getNameExport()
{
$producer = GlobalParam::getCurrentProducer();
if ($producer->option_export_display_product_reference && $this->reference && strlen($this->reference) > 0) {
return $this->reference;
}

return $this->name;
}


}

+ 10
- 3
common/models/User.php Просмотреть файл

@@ -226,10 +226,10 @@ class User extends ActiveRecordCommon implements IdentityInterface
public function verifyEmail($attribute, $params)
{
if($this->id) {
$user = User::find()->where("email LIKE :email AND id != :id")->params(array(':email' => '%' . $this->email . '%', ':id' => $this->id))->one();
$user = User::find()->where("email LIKE :email AND type != :guest AND id != :id")->params(array(':email' => '%' . $this->email . '%', ':id' => $this->id, ':guest' => 'guest'))->one();
}
else {
$user = User::find()->where("email LIKE :email")->params(array(':email' => '%' . $this->email . '%'))->one();
$user = User::find()->where("email LIKE :email AND type != :guest")->params(array(':email' => '%' . $this->email . '%', ':guest' => 'guest'))->one();
}

if ($user) {
@@ -802,5 +802,12 @@ class User extends ActiveRecordCommon implements IdentityInterface
return false ;
}


public static function getTypeChoicesArray()
{
return [
User::TYPE_INDIVIDUAL => 'Particulier',
User::TYPE_LEGAL_PERSON => 'Personne morale',
User::TYPE_GUEST => 'Visiteur'
];
}
}

+ 1
- 0
common/models/UserSearch.php Просмотреть файл

@@ -85,6 +85,7 @@ class UserSearch extends User
. '`user`.id_producer, '
. '`user`.date_last_connection, '
. '`user`.name_legal_person, '
. '`user`.type, '
. '(SELECT COUNT(*) FROM `order` WHERE `user`.id = `order`.id_user) AS count_orders');

$dataProvider = new ActiveDataProvider([

+ 47
- 0
console/migrations/m220817_074240_add_foreign_keys_documents.php Просмотреть файл

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

use yii\db\Migration;

/**
* Class m220817_074240_add_foreign_keys_documents
*/
class m220817_074240_add_foreign_keys_documents extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->createIndex('user_fk', 'delivery_note', ['id_user']);
$this->createIndex('producer_fk', 'delivery_note', ['id_producer']);

$this->createIndex('user_fk', 'quotation', ['id_user']);
$this->createIndex('producer_fk', 'quotation', ['id_producer']);

$this->createIndex('user_fk', 'invoice', ['id_user']);
$this->createIndex('producer_fk', 'invoice', ['id_producer']);

$this->createIndex('delivery_note_fk', 'order', ['id_delivery_note']);
$this->createIndex('quotation_fk', 'order', ['id_quotation']);
$this->createIndex('invoice_fk', 'order', ['id_invoice']);
}

/**
* {@inheritdoc}
*/
public function safeDown()
{
$this->dropIndex('user_fk', 'delivery_note');
$this->dropIndex('producer_fk', 'delivery_note');

$this->dropIndex('user_fk', 'quotation');
$this->dropIndex('producer_fk', 'quotation');

$this->dropIndex('user_fk', 'invoice');
$this->dropIndex('producer_fk', 'invoice');

$this->dropIndex('delivery_note_fk', 'order');
$this->dropIndex('quotation_fk', 'order');
$this->dropIndex('invoice_fk', 'order');
}
}

+ 20
- 0
console/migrations/m220823_083001_add_option_document_display_product_description.php Просмотреть файл

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

use yii\db\Migration;
use yii\db\Schema ;

/**
* Class m220823_083001_add_option_document_display_product_description
*/
class m220823_083001_add_option_document_display_product_description extends Migration
{
public function safeUp()
{
$this->addColumn('producer', 'document_display_product_description', Schema::TYPE_BOOLEAN.' DEFAULT 1');
}

public function safeDown()
{
$this->dropColumn('producer', 'document_display_product_description');
}
}

+ 45
- 0
console/migrations/m220823_084928_add_option_notify_producer_order_summary.php Просмотреть файл

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

use yii\db\Migration;
use yii\db\Schema;

/**
* Class m220823_084928_add_option_notify_producer_order_summary
*/
class m220823_084928_add_option_notify_producer_order_summary extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn('producer', 'option_notify_producer_order_summary', Schema::TYPE_BOOLEAN.' DEFAULT 1');
}

/**
* {@inheritdoc}
*/
public function safeDown()
{
$this->dropColumn('producer', 'option_notify_producer_order_summary');

echo "m220823_084928_add_option_notify_producer_order_summary cannot be reverted.\n";

return false;
}

/*
// Use up()/down() to run migration code without a transaction.
public function up()
{

}

public function down()
{
echo "m220823_084928_add_option_notify_producer_order_summary cannot be reverted.\n";

return false;
}
*/
}

+ 1
- 0
frontend/controllers/SiteController.php Просмотреть файл

@@ -252,6 +252,7 @@ class SiteController extends FrontendController
$model = new SignupForm();
if ($model->load(Yii::$app->request->post())) {
$user = $model->signup();

if ($user) {
if (Yii::$app->getUser()->login($user)) {
if ($model->option_user_producer == 'producer') {

+ 13
- 1
frontend/models/SignupForm.php Просмотреть файл

@@ -80,7 +80,19 @@ class SignupForm extends Model
['email', 'filter', 'filter' => 'trim'],
['email', 'required', 'message' => 'Champs obligatoire'],
['email', 'email'],
['email', 'unique', 'targetClass' => '\common\models\User', 'message' => 'Cet email est déjà utilisé'],
['email', function($attribute, $params) {
$email = $this->$attribute;

$userExist = User::searchOne([
'type' => 'individual',
'email' => $email
]);

if($userExist) {
$this->addError($attribute, 'Cet email est déjà utilisé.');
}
}],
//['email', 'unique', 'targetClass' => '\common\models\User', 'message' => 'Cet email est déjà utilisé'],
[['name', 'lastname', 'phone'], 'required', 'message' => 'Champs obligatoire'],
[['name', 'lastname', 'phone', 'option_user_producer'], 'string', 'min' => 2, 'max' => 255],
['password', 'required', 'message' => 'Champs obligatoire'],

+ 2
- 2
producer/controllers/OrderController.php Просмотреть файл

@@ -678,7 +678,7 @@ class OrderController extends ProducerBaseController
'option_order_entry_point' => $producer->option_order_entry_point,
'option_delivery' => $producer->option_delivery,
'online_payment' => $producer->online_payment,
'option_online_payment_type' => $producer->online_payment,
'option_online_payment_type' => $producer->online_payment
];

// Distributions
@@ -765,7 +765,7 @@ class OrderController extends ProducerBaseController
}

$json['user'] = false;
if ($userProducer) {
if ($user && $userProducer) {
$json['user'] = [
'address' => $user->address,
'credit' => $userProducer->credit,

+ 15
- 5
producer/views/order/order.php Просмотреть файл

@@ -44,12 +44,13 @@ use common\models\Distribution ;

$this->setTitle('Commander') ;

$producer = GlobalParam::getCurrentProducer() ;
$producer = $this->context->getProducer();

?>

<script>
var appInitValues = {
urlLogin: '<?= Yii::$app->urlManagerFrontend->createAbsoluteUrl(['site/producer', 'id' => $this->context->getProducer()->id, 'return_url' => Yii::$app->urlManagerProducer->createAbsoluteUrl(['order/order', 'slug_producer' => $this->context->getProducer()->slug])]) ?>'
};
</script>

@@ -242,10 +243,19 @@ $producer = GlobalParam::getCurrentProducer() ;
<input v-model="pointsSaleCodes[pointSale.id]" type="password" placeholder="Code" class="form-control input-code" />
</div>
</div>
<button class="btn btn-primary" @click="pointSaleClick" :data-code="pointSale.code.length > 0" :data-id-point-sale="pointSale.id">
<span class="glyphicon glyphicon-map-marker"></span>
Choisir
</button>

<div v-if="!user && producer.credit == 1 && pointSale.credit == 1">
<a :href="urlLogin" class="btn btn-default">
<span class="glyphicon glyphicon-log-in"></span>
Connexion obligatoire
</a>
</div>
<div v-else>
<button class="btn btn-primary" @click="pointSaleClick" :data-code="pointSale.code.length > 0" :data-id-point-sale="pointSale.id">
<span class="glyphicon glyphicon-map-marker"></span>
Choisir
</button>
</div>
</template>
</td>
</tr>

+ 10
- 10
producer/web/css/screen.css Просмотреть файл

@@ -34,7 +34,7 @@ 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.
*/
/* line 5, ../../../../../../../var/lib/gems/2.7.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
/* line 5, ../../../../../../lib/gems/3.0.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
@@ -56,45 +56,45 @@ time, mark, audio, video {
vertical-align: baseline;
}

/* line 22, ../../../../../../../var/lib/gems/2.7.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
/* line 22, ../../../../../../lib/gems/3.0.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
html {
line-height: 1;
}

/* line 24, ../../../../../../../var/lib/gems/2.7.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
/* line 24, ../../../../../../lib/gems/3.0.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
ol, ul {
list-style: none;
}

/* line 26, ../../../../../../../var/lib/gems/2.7.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
/* line 26, ../../../../../../lib/gems/3.0.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
table {
border-collapse: collapse;
border-spacing: 0;
}

/* line 28, ../../../../../../../var/lib/gems/2.7.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
/* line 28, ../../../../../../lib/gems/3.0.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
caption, th, td {
text-align: left;
font-weight: normal;
vertical-align: middle;
}

/* line 30, ../../../../../../../var/lib/gems/2.7.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
/* line 30, ../../../../../../lib/gems/3.0.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
q, blockquote {
quotes: none;
}
/* line 103, ../../../../../../../var/lib/gems/2.7.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
/* line 103, ../../../../../../lib/gems/3.0.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
q:before, q:after, blockquote:before, blockquote:after {
content: "";
content: none;
}

/* line 32, ../../../../../../../var/lib/gems/2.7.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
/* line 32, ../../../../../../lib/gems/3.0.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
a img {
border: none;
}

/* line 116, ../../../../../../../var/lib/gems/2.7.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
/* line 116, ../../../../../../lib/gems/3.0.0/gems/compass-core-1.0.3/stylesheets/compass/reset/_utilities.scss */
article, aside, details, figcaption, figure, footer, header, hgroup, main, menu, nav, section, summary {
display: block;
}
@@ -1566,7 +1566,7 @@ termes.
}
/* line 304, ../sass/order/_order.scss */
.order-order #main #app-order-order table#products .price-unit, .order-order #main #app-order-order table#products .price-total {
width: 120px;
width: 135px;
text-align: center;
}
/* line 308, ../sass/order/_order.scss */

+ 1
- 0
producer/web/js/vuejs/order-order.js Просмотреть файл

@@ -27,6 +27,7 @@ var app = new Vue({
disableConfirmButton: false,
delivery: false,
deliveryAddress: null,
urlLogin: '#',
calendar: {
mode: 'single',
attrs: [],

+ 1
- 1
producer/web/sass/order/_order.scss Просмотреть файл

@@ -302,7 +302,7 @@
}

.price-unit, .price-total {
width: 120px ;
width: 135px ;
text-align: center ;
.unit {

+ 18
- 6
setPermissionsOpenDistrib.sh Просмотреть файл

@@ -1,15 +1,27 @@
#!/usr/bin/env bash

sudo chown guillaume:www-data . -R
if [ -z "$1" ]; then
echo "Vous devez ajouter en paramètre le nom de l'utilisateur à appliquer aux dossiers"
else
sudo chown $1:www-data . -R

sudo chown guillaume:www-data frontend/runtime/ -R
chmod 775 frontend/runtime/
sudo chown $1:www-data frontend/runtime/ -R
sudo chmod 775 frontend/runtime/ -R

sudo chown guillaume:www-data frontend/web/assets/ -R
sudo chown $1:www-data frontend/web/assets/ -R
sudo chmod 775 frontend/web/assets/ -R

sudo chown guillaume:www-data backend/runtime/ -R
sudo chown $1:www-data backend/runtime/ -R
sudo chmod 775 backend/runtime/ -R

sudo chown guillaume:www-data backend/web/assets/ -R
sudo chown $1:www-data backend/web/assets/ -R
sudo chmod 775 backend/web/assets/ -R

sudo chown $1:www-data producer/runtime/ -R
sudo chmod 775 producer/runtime/ -R

sudo chown $1:www-data producer/web/assets/ -R
sudo chmod 775 producer/web/assets/ -R

fi


Загрузка…
Отмена
Сохранить