Browse Source

Merge branch 'dev'

prodstable
Guillaume Bourgeois 2 years ago
parent
commit
5c02e17fe2
26 changed files with 796 additions and 595 deletions
  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 View File





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

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

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

+ 15
- 0
README.md View File

# 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 View File

/* /*
* Envoi des commandes par email au producteur * 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([ $arrayOrders = Order::searchAll([
'distribution.date' => $date, 'distribution.date' => $date,
'distribution.id_producer' => $producer->id 'distribution.id_producer' => $producer->id
} }


if ($producer->active) { 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() /*Yii::$app->mailer->compose()
->setFrom('contact@opendistrib.net') ->setFrom('contact@opendistrib.net')
->setTo('contact@opendistrib.net') ->setTo('contact@opendistrib.net')

+ 1
- 1
backend/views/document/_download_product_line.php View File

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

+ 5
- 2
backend/views/document/download.php View File

<?php <?php


$displayPrices = Yii::$app->controller->getClass() != 'DeliveryNote' || (Yii::$app->controller->getClass() == 'DeliveryNote' && Producer::getConfig('document_display_prices_delivery_note')) ; $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');


?> ?>


'document' => $document, 'document' => $document,
'productOrder' => $productOrder, 'productOrder' => $productOrder,
'displayOrders' => true, 'displayOrders' => true,
'displayPrices' => $displayPrices
'displayPrices' => $displayPrices,
'displayProductDescription' => $displayProductDescription
]) ?> ]) ?>
<?php endforeach; ?> <?php endforeach; ?>
<?php endforeach; ?> <?php endforeach; ?>
<?= $this->render('_download_product_line', [ <?= $this->render('_download_product_line', [
'document' => $document, 'document' => $document,
'productOrder' => $productOrder, 'productOrder' => $productOrder,
'displayPrices' => $displayPrices
'displayPrices' => $displayPrices,
'displayProductDescription' => $displayProductDescription
]) ?> ]) ?>
<?php endforeach; ?> <?php endforeach; ?>
<?php endforeach; ?> <?php endforeach; ?>

+ 11
- 7
backend/views/producer/update.php View File

<?= $form->field($model, 'order_infos') <?= $form->field($model, 'order_infos')
->textarea(['rows' => 6]) ->textarea(['rows' => 6])
->hint('Affichées au client lors de sa commande')?> ->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') <?= $form->field($model, 'option_behavior_cancel_order')
->dropDownList([ ->dropDownList([
1 => 'Oui' 1 => 'Oui'
], []); ?> ], []); ?>


<?= $form->field($model, 'option_allow_order_guest')
<?php echo $form->field($model, 'option_allow_order_guest')
->dropDownList([ ->dropDownList([
0 => 'Non', 0 => 'Non',
1 => 'Oui' 1 => 'Oui'
0 => 'Non', 0 => 'Non',
1 => 'Oui' 1 => 'Oui'
]) ; ?> ]) ; ?>
<?= $form->field($model, 'document_display_product_description')->dropDownList([
0 => 'Non',
1 => 'Oui'
]) ; ?>
<?= $form->field($model, 'document_infos_bottom') <?= $form->field($model, 'document_infos_bottom')
->textarea(['rows' => 15]) ?> ->textarea(['rows' => 15]) ?>
<?= $form->field($model, 'document_infos_quotation') <?= $form->field($model, 'document_infos_quotation')

+ 1
- 5
backend/views/user/_form.php View File

]); ?> ]); ?>


<?= $form->field($model, 'type') <?= $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' 'v-model' => 'type'
]) ; ?> ]) ; ?>
<?= $form->field($model, 'name_legal_person', ['options' => ['v-show' => "type == 'legal-person'"]])->textInput() ?> <?= $form->field($model, 'name_legal_person', ['options' => ['v-show' => "type == 'legal-person'"]])->textInput() ?>

+ 111
- 100
backend/views/user/index.php View File

<?= <?=


$this->render('_menu', [ $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([ <?= 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=""> <input type="text" class="form-control input-credit" readonly="readonly" value="' . number_format($credit, 2) . ' €" placeholder="">
<span class="input-group-btn"> <span class="input-group-btn">
' . Html::a( ' . 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> </span>
</div>'; </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 View File

/* line 14, ../../sass/document/download.scss */ /* line 14, ../../sass/document/download.scss */
.document-download #block-addresses .producer { .document-download #block-addresses .producer {
text-align: left; 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 { .document-download #block-addresses .producer .logo {
margin-bottom: 20px; margin-bottom: 20px;
} }
/* line 27, ../../sass/document/download.scss */
/* line 26, ../../sass/document/download.scss */
.document-download #block-addresses .user { .document-download #block-addresses .user {
text-align: right; text-align: right;
} }
/* line 32, ../../sass/document/download.scss */
/* line 31, ../../sass/document/download.scss */
.document-download #block-infos-document { .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 { .document-download #block-infos-document .date {
padding-bottom: 10px; padding-bottom: 10px;
} }
/* line 38, ../../sass/document/download.scss */
/* line 37, ../../sass/document/download.scss */
.document-download #block-infos-document .reference { .document-download #block-infos-document .reference {
padding-bottom: 10px; padding-bottom: 10px;
font-size: 15px; font-size: 15px;
font-weight: bold; font-weight: bold;
} }
/* line 43, ../../sass/document/download.scss */
/* line 42, ../../sass/document/download.scss */
.document-download #block-infos-document .reference .block-is-draft { .document-download #block-infos-document .reference .block-is-draft {
border: solid 2px black; border: solid 2px black;
padding: 10px; padding: 10px;
text-transform: uppercase; text-transform: uppercase;
} }
/* line 54, ../../sass/document/download.scss */
/* line 53, ../../sass/document/download.scss */
.document-download #block-no-product { .document-download #block-no-product {
font-weight: bold; font-weight: bold;
border: solid 2px black; border: solid 2px black;
text-transform: uppercase; text-transform: uppercase;
padding: 10px; padding: 10px;
} }
/* line 61, ../../sass/document/download.scss */
/* line 60, ../../sass/document/download.scss */
.document-download #block-products { .document-download #block-products {
padding-top: 20px; padding-top: 20px;
} }
/* line 64, ../../sass/document/download.scss */
/* line 63, ../../sass/document/download.scss */
.document-download #block-products table { .document-download #block-products table {
width: 100%; width: 100%;
padding: 0px; padding: 0px;
border-right: solid 1px #c0c0c0; border-right: solid 1px #c0c0c0;
border-collapse: collapse; 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 { .document-download #block-products table td, .document-download #block-products table th {
padding: 5px; padding: 5px;
border-top: solid 1px #c0c0c0; border-top: solid 1px #c0c0c0;
border-left: solid 1px #c0c0c0; border-left: solid 1px #c0c0c0;
font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif; font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 13px;
} }
/* line 78, ../../sass/document/download.scss */ /* line 78, ../../sass/document/download.scss */
.document-download #block-products table td.align-left, .document-download #block-products table th.align-left { .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 View File

getBestProductPrice: function (idProduct, theQuantity) { getBestProductPrice: function (idProduct, theQuantity) {
var product = this.getProductById(idProduct); var product = this.getProductById(idProduct);


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




for (var i = 0; i < pricesArray.length; i++) { for (var i = 0; i < pricesArray.length; i++) {
if(pricesArray[i]) { if(pricesArray[i]) {
var priceWithTax = pricesArray[i].price_with_tax;
var price = pricesArray[i].price;
var fromQuantity = pricesArray[i].from_quantity; 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; return 0;
} }
else { else {
return thePriceWithTax;
return thePrice;
} }
}, },
changeQuantityProductAdd: function (quantity) { changeQuantityProductAdd: function (quantity) {

+ 3
- 3
backend/web/sass/document/download.scss View File

#block-addresses { #block-addresses {


.producer { .producer {

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


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


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


.date { .date {
padding-bottom: 10px ; padding-bottom: 10px ;
border-top: solid 1px $border-color ; border-top: solid 1px $border-color ;
border-left: solid 1px $border-color ; border-left: solid 1px $border-color ;
font-family: $font-family ; font-family: $font-family ;
font-size: 13px;


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

+ 6
- 2
common/models/Producer.php View File

'document_display_orders_invoice', 'document_display_orders_invoice',
'document_display_orders_delivery_note', 'document_display_orders_delivery_note',
'document_display_prices_delivery_note', 'document_display_prices_delivery_note',
'document_display_product_description',
'option_email_confirm', 'option_email_confirm',
'option_email_confirm_producer', 'option_email_confirm_producer',
'option_csv_export_all_products', 'option_csv_export_all_products',
'option_allow_order_guest', 'option_allow_order_guest',
'option_delivery', 'option_delivery',
'option_display_export_grid', 'option_display_export_grid',
'option_stripe_mode_test'
'option_stripe_mode_test',
'option_notify_producer_order_summary'
], ],
'boolean' 'boolean'
], ],
'option_allow_order_guest' => 'Autoriser les visiteurs à passer commande (création de compte à la fin du tunnel)', '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_order_entry_point' => 'Point d\'entrée par point de vente ou par date',
'option_delivery' => 'Proposer la livraison à domicile', '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 View File

*/ */
class Product extends 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 View File

public function verifyEmail($attribute, $params) public function verifyEmail($attribute, $params)
{ {
if($this->id) { 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 { 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) { if ($user) {
return false ; 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 View File

. '`user`.id_producer, ' . '`user`.id_producer, '
. '`user`.date_last_connection, ' . '`user`.date_last_connection, '
. '`user`.name_legal_person, ' . '`user`.name_legal_person, '
. '`user`.type, '
. '(SELECT COUNT(*) FROM `order` WHERE `user`.id = `order`.id_user) AS count_orders'); . '(SELECT COUNT(*) FROM `order` WHERE `user`.id = `order`.id_user) AS count_orders');


$dataProvider = new ActiveDataProvider([ $dataProvider = new ActiveDataProvider([

+ 47
- 0
console/migrations/m220817_074240_add_foreign_keys_documents.php View File

<?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 View File

<?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 View File

<?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 View File

$model = new SignupForm(); $model = new SignupForm();
if ($model->load(Yii::$app->request->post())) { if ($model->load(Yii::$app->request->post())) {
$user = $model->signup(); $user = $model->signup();

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

+ 13
- 1
frontend/models/SignupForm.php View File

['email', 'filter', 'filter' => 'trim'], ['email', 'filter', 'filter' => 'trim'],
['email', 'required', 'message' => 'Champs obligatoire'], ['email', 'required', 'message' => 'Champs obligatoire'],
['email', 'email'], ['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'], 'required', 'message' => 'Champs obligatoire'],
[['name', 'lastname', 'phone', 'option_user_producer'], 'string', 'min' => 2, 'max' => 255], [['name', 'lastname', 'phone', 'option_user_producer'], 'string', 'min' => 2, 'max' => 255],
['password', 'required', 'message' => 'Champs obligatoire'], ['password', 'required', 'message' => 'Champs obligatoire'],

+ 2
- 2
producer/controllers/OrderController.php View File

'option_order_entry_point' => $producer->option_order_entry_point, 'option_order_entry_point' => $producer->option_order_entry_point,
'option_delivery' => $producer->option_delivery, 'option_delivery' => $producer->option_delivery,
'online_payment' => $producer->online_payment, 'online_payment' => $producer->online_payment,
'option_online_payment_type' => $producer->online_payment,
'option_online_payment_type' => $producer->online_payment
]; ];


// Distributions // Distributions
} }


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

+ 15
- 5
producer/views/order/order.php View File



$this->setTitle('Commander') ; $this->setTitle('Commander') ;


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


?> ?>


<script> <script>
var appInitValues = { 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> </script>


<input v-model="pointsSaleCodes[pointSale.id]" type="password" placeholder="Code" class="form-control input-code" /> <input v-model="pointsSaleCodes[pointSale.id]" type="password" placeholder="Code" class="form-control input-code" />
</div> </div>
</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> </template>
</td> </td>
</tr> </tr>

+ 10
- 10
producer/web/css/screen.css View File

pris connaissance de la licence CeCILL, et que vous en avez accepté les pris connaissance de la licence CeCILL, et que vous en avez accepté les
termes. 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, html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre, h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code, a, abbr, acronym, address, big, cite, code,
vertical-align: baseline; 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 { html {
line-height: 1; 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 { ol, ul {
list-style: none; 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 { table {
border-collapse: collapse; border-collapse: collapse;
border-spacing: 0; 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 { caption, th, td {
text-align: left; text-align: left;
font-weight: normal; font-weight: normal;
vertical-align: middle; 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 { q, blockquote {
quotes: none; 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 { q:before, q:after, blockquote:before, blockquote:after {
content: ""; content: "";
content: none; 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 { a img {
border: none; 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 { article, aside, details, figcaption, figure, footer, header, hgroup, main, menu, nav, section, summary {
display: block; display: block;
} }
} }
/* line 304, ../sass/order/_order.scss */ /* 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 { .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; text-align: center;
} }
/* line 308, ../sass/order/_order.scss */ /* line 308, ../sass/order/_order.scss */

+ 1
- 0
producer/web/js/vuejs/order-order.js View File

disableConfirmButton: false, disableConfirmButton: false,
delivery: false, delivery: false,
deliveryAddress: null, deliveryAddress: null,
urlLogin: '#',
calendar: { calendar: {
mode: 'single', mode: 'single',
attrs: [], attrs: [],

+ 1
- 1
producer/web/sass/order/_order.scss View File

} }


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

+ 18
- 6
setPermissionsOpenDistrib.sh View File

#!/usr/bin/env bash #!/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 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 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 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


Loading…
Cancel
Save