瀏覽代碼

Merge branch 'develop'

master
Guillaume Bourgeois 1 年之前
父節點
當前提交
537c35d3fe
共有 71 個文件被更改,包括 1973 次插入457 次删除
  1. +5
    -0
      backend/controllers/BackendController.php
  2. +140
    -0
      backend/controllers/FeatureAdminController.php
  3. +9
    -0
      backend/controllers/ProductController.php
  4. +1
    -1
      backend/controllers/SupportAdminController.php
  5. +6
    -2
      backend/controllers/UserController.php
  6. +5
    -2
      backend/controllers/UserImportController.php
  7. +4
    -1
      backend/forms/UserImportUploadForm.php
  8. +1
    -0
      backend/models/CreditForm.php
  9. +10
    -1
      backend/views/dashboard/index.php
  10. +12
    -10
      backend/views/distribution/index.php
  11. +21
    -7
      backend/views/document/_download_product_line.php
  12. +41
    -35
      backend/views/document/download.php
  13. +167
    -0
      backend/views/feature-admin/index.php
  14. +60
    -0
      backend/views/feature-admin/update.php
  15. +4
    -2
      backend/views/layouts/left.php
  16. +105
    -102
      backend/views/point-sale/_form.php
  17. +44
    -31
      backend/views/producer/update.php
  18. +1
    -0
      backend/views/user-import/index.php
  19. +3
    -0
      backend/views/user/_form.php
  20. +18
    -0
      backend/views/user/index.php
  21. +65
    -44
      backend/web/css/document/download.css
  22. +6
    -0
      backend/web/css/screen.css
  23. +62
    -56
      backend/web/js/backend.js
  24. +123
    -102
      backend/web/sass/document/download.scss
  25. +9
    -0
      backend/web/sass/feature-admin/_index.scss
  26. +1
    -0
      backend/web/sass/screen.scss
  27. +2
    -0
      common/components/BusinessLogic.php
  28. +12
    -0
      common/components/BusinessLogicTrait.php
  29. +5
    -0
      common/logic/AbstractRepository.php
  30. +14
    -0
      common/logic/Distribution/Distribution/Service/ExportManager.php
  31. +0
    -13
      common/logic/Document/Document/Service/DocumentManager.php
  32. +93
    -0
      common/logic/Feature/Feature/Model/Feature.php
  33. +49
    -0
      common/logic/Feature/Feature/Module/FeatureModule.php
  34. +40
    -0
      common/logic/Feature/Feature/Repository/FeatureRepository.php
  35. +22
    -0
      common/logic/Feature/Feature/Repository/FeatureRepositoryQuery.php
  36. +60
    -0
      common/logic/Feature/Feature/Service/FeatureBuilder.php
  37. +31
    -0
      common/logic/Feature/Feature/Service/FeatureDefinition.php
  38. +32
    -0
      common/logic/Feature/Feature/Service/FeatureImporter.php
  39. +80
    -0
      common/logic/Feature/Feature/Service/FeatureManager.php
  40. +96
    -0
      common/logic/Feature/FeatureProducer/Model/FeatureProducer.php
  41. +35
    -0
      common/logic/Feature/FeatureProducer/Module/FeatureProducerModule.php
  42. +34
    -0
      common/logic/Feature/FeatureProducer/Repository/FeatureProducerRepository.php
  43. +23
    -0
      common/logic/Feature/FeatureProducer/Repository/FeatureProducerRepositoryQuery.php
  44. +58
    -0
      common/logic/Feature/FeatureProducer/Service/FeatureProducerBuilder.php
  45. +25
    -0
      common/logic/Feature/FeatureProducer/Service/FeatureProducerDefinition.php
  46. +1
    -1
      common/logic/Order/Order/Service/OrderSolver.php
  47. +17
    -0
      common/logic/Order/ProductOrder/Service/ProductOrderSolver.php
  48. +3
    -1
      common/logic/PointSale/PointSale/Model/PointSale.php
  49. +21
    -4
      common/logic/Producer/Producer/Model/Producer.php
  50. +3
    -8
      common/logic/Producer/Producer/Service/ProducerSolver.php
  51. +4
    -1
      common/logic/User/User/Model/User.php
  52. +10
    -1
      common/logic/User/User/Model/UserSearch.php
  53. +14
    -2
      common/logic/User/User/Service/UserBuilder.php
  54. +4
    -3
      common/logic/User/User/Service/UserBulkImporter.php
  55. +6
    -3
      common/logic/User/UserGroup/Repository/UserGroupRepository.php
  56. +1
    -1
      common/logic/User/UserGroup/Service/UserGroupBuilder.php
  57. +22
    -0
      common/logic/User/UserUserGroup/Model/UserUserGroup.php
  58. +8
    -4
      common/logic/User/UserUserGroup/Service/UserUserGroupBuilder.php
  59. +17
    -0
      console/commands/ImportFeaturesController.php
  60. +26
    -0
      console/migrations/m231108_092151_rename_column_producer_option_document_height_logo.php
  61. +26
    -0
      console/migrations/m231108_131232_add_column_producer_option_document_display_price_unit_reference.php
  62. +26
    -0
      console/migrations/m231109_072158_add_column_point_sale_home_delivery.php
  63. +28
    -0
      console/migrations/m231109_090026_add_column_producer_id_user_group_default.php
  64. +26
    -0
      console/migrations/m231110_073749_add_column_producer_option_check_by_default_prevent_user_credit.php
  65. +46
    -0
      console/migrations/m231110_084013_create_tables_feature_flag.php
  66. +9
    -1
      frontend/forms/SignupForm.php
  67. +7
    -0
      producer/controllers/OrderController.php
  68. +6
    -5
      producer/controllers/SiteController.php
  69. +4
    -2
      producer/views/layouts/main.php
  70. +1
    -5
      producer/views/order/order.php
  71. +3
    -6
      producer/web/js/vuejs/order-order.js

+ 5
- 0
backend/controllers/BackendController.php 查看文件

@@ -76,6 +76,11 @@ class BackendController extends CommonController
{
return Producer::searchOne();
}

public function redirectDashboard()
{
return $this->redirect(['dashboard/index']);
}
}

?>

+ 140
- 0
backend/controllers/FeatureAdminController.php 查看文件

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

/**
* Copyright distrib (2018)
*
* contact@opendistrib.net
*
* Ce logiciel est un programme informatique servant à aider les producteurs
* à distribuer leur production en circuits courts.
*
* Ce logiciel est régi par la licence CeCILL soumise au droit français et
* respectant les principes de diffusion des logiciels libres. Vous pouvez
* utiliser, modifier et/ou redistribuer ce programme sous les conditions
* de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
* sur le site "http://www.cecill.info".
*
* En contrepartie de l'accessibilité au code source et des droits de copie,
* de modification et de redistribution accordés par cette licence, il n'est
* offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
* seule une responsabilité restreinte pèse sur l'auteur du programme, le
* titulaire des droits patrimoniaux et les concédants successifs.
*
* A cet égard l'attention de l'utilisateur est attirée sur les risques
* associés au chargement, à l'utilisation, à la modification et/ou au
* développement et à la reproduction du logiciel par l'utilisateur étant
* donné sa spécificité de logiciel libre, qui peut le rendre complexe à
* manipuler et qui le réserve donc à des développeurs et des professionnels
* avertis possédant des connaissances informatiques approfondies. Les
* utilisateurs sont donc invités à charger et tester l'adéquation du
* logiciel à leurs besoins dans des conditions permettant d'assurer la
* sécurité de leurs systèmes et ou de leurs données et, plus généralement,
* à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
*
* Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
* pris connaissance de la licence CeCILL, et que vous en avez accepté les
* termes.
*/

namespace backend\controllers;

use common\helpers\Ajax;
use yii\filters\AccessControl;
use yii\helpers\Html;
use yii\web\NotFoundHttpException;

/**
* UserController implements the CRUD actions for User model.
*/
class FeatureAdminController extends BackendController
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::class,
'rules' => [
[
'allow' => true,
'roles' => ['@'],
'matchCallback' => function ($rule, $action) {
return $this->getUserModule()
->getAuthorizationChecker()
->isGrantedAsAdministrator($this->getUserCurrent());
}
]
],
],
];
}

public function actionIndex()
{
$featureModule = $this->getFeatureModule();
$dataProviderFeatures = $featureModule->getRepository()->queryAll()->getDataProvider(100);

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

public function actionAjaxToggleStatus($id, $status)
{
$featureManager = $this->getFeatureModule()->getManager();
$feature = $this->findModel($id);

if($status) {
$featureManager->enable($feature);
$messageResponse = 'La fonctionnalité "'.Html::encode($feature->name).'" a bien été activée';
}
else {
$featureManager->disable($feature);
$messageResponse = 'La fonctionnalité "'.Html::encode($feature->name).'" a bien été désactivée';
}

return Ajax::responseSuccess($messageResponse);
}

public function actionToggleStatusFeatureProducer(int $id, bool $status = null)
{
$featureManager = $this->getFeatureModule()->getManager();
$feature = $this->findModel($id);

if(is_null($status)) {
$featureManager->defaultForProducer($feature);
}
elseif($status == 0) {
$featureManager->disableForProducer($feature);
}
elseif($status == 1) {
$featureManager->enableForProducer($feature);
}

return $this->redirectReferer();
}

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

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

protected function findModel($id)
{
$featureModule = $this->getFeatureModule();
if (($feature = $featureModule->getRepository()->findOneFeatureById($id)) !== null) {
return $feature;
} else {
throw new NotFoundHttpException('La fonctionnalité demandée est introuvable.');
}
}
}

+ 9
- 0
backend/controllers/ProductController.php 查看文件

@@ -42,6 +42,7 @@ use backend\forms\ProductPriceUploadForm;
use common\helpers\CSV;
use common\helpers\GlobalParam;
use common\logic\Distribution\ProductDistribution\Model\ProductDistribution;
use common\logic\Feature\Feature\Model\Feature;
use common\logic\PointSale\PointSale\Model\PointSale;
use common\logic\Product\Product\Model\Product;
use common\logic\Product\Product\Model\ProductSearch;
@@ -373,6 +374,10 @@ class ProductController extends BackendController
*/
public function actionPriceImport()
{
if($this->getFeatureModule()->getManager()->isDisabled(Feature::ALIAS_PRODUCT_PRICE_IMPORT)) {
return $this->redirectDashboard();
}

$productModule = $this->getProductModule();
$productPriceModule = $this->getProductPriceModule();
$userGroupModule = $this->getUserGroupModule();
@@ -479,6 +484,10 @@ class ProductController extends BackendController
*/
public function actionPriceExport()
{
if($this->getFeatureModule()->getManager()->isDisabled(Feature::ALIAS_PRODUCT_PRICE_IMPORT)) {
return $this->redirectDashboard();
}

$productModule = $this->getProductModule();
$productPriceModule = $this->getProductPriceModule();
$userModule = $this->getUserModule();

+ 1
- 1
backend/controllers/SupportAdminController.php 查看文件

@@ -60,7 +60,7 @@ class SupportAdminController extends SupportController
'matchCallback' => function ($rule, $action) {
return $this->getUserModule()
->getAuthorizationChecker()
->isGrantedAsProducer($this->getUserCurrent());
->isGrantedAsAdministrator($this->getUserCurrent());
}
]
],

+ 6
- 2
backend/controllers/UserController.php 查看文件

@@ -148,7 +148,8 @@ class UserController extends BackendController
$model->phone,
$model->address,
$model->newsletter,
Password::generate()
Password::generate(),
$model->send_mail_welcome
);

$this->processLinkPointSale($model);
@@ -181,7 +182,7 @@ class UserController extends BackendController
if ($model->load(\Yii::$app->request->post()) && $model->save()) {

// on envoie le mail de bienvenue si le mail vient d'être défini
if (!strlen($previousMail) && strlen($model->email)) {
if (!strlen($previousMail) && strlen($model->email) && $model->send_mail_welcome) {
$password = Password::generate();
$userModule->setPassword($model, $password);
$model->username = $model->email;
@@ -383,6 +384,7 @@ class UserController extends BackendController
*/
public function actionCredit(int $id)
{
$producerModule = $this->getProducerModule();
$userModule = $this->getUserModule();
$paymentModule = $this->getPaymentModule();
$userProducerModule = $this->getUserProducerModule();
@@ -392,6 +394,8 @@ class UserController extends BackendController

if ($userProducer) {
$creditForm = new CreditForm();
$creditForm->send_mail = $producerModule->getSolver()->getConfig('option_check_by_default_prevent_user_credit');

if ($creditForm->load(\Yii::$app->request->post()) && $creditForm->validate()) {

$paymentModule->getManager()

+ 5
- 2
backend/controllers/UserImportController.php 查看文件

@@ -68,11 +68,14 @@ class UserImportController extends BackendController
public function actionIndex()
{
$model = new UserImportUploadForm();
if (\Yii::$app->request->isPost) {
if ($model->load(\Yii::$app->request->post())) {
$model->file = UploadedFile::getInstance($model, 'file');
if($model->file && $model->validate()) {
try {
$this->getUserModule()->getBulkImporter()->import($model->file->tempName);
$this->getUserModule()->getBulkImporter()->import(
$model->file->tempName,
(bool) $model->send_mail_welcome
);
$this->setFlash('success', "Fichier importé.");
}
catch(ErrorException $exception) {

+ 4
- 1
backend/forms/UserImportUploadForm.php 查看文件

@@ -11,6 +11,7 @@ class UserImportUploadForm extends Model
* @var UploadedFile file attribute
*/
public $file;
public $send_mail_welcome;

/**
* @return array the validation rules.
@@ -19,13 +20,15 @@ class UserImportUploadForm extends Model
{
return [
[['file'], 'file', 'skipOnEmpty' => false, 'mimeTypes' => 'text/csv, text/plain'],
[['send_mail_welcome'], 'boolean']
];
}

public function attributeLabels()
{
return [
'file' => "Fichier d'import (CSV)"
'file' => "Fichier d'import (CSV)",
'send_mail_welcome' => "Envoyer un email de bienvenue aux utilisateurs importés"
];
}
}

+ 1
- 0
backend/models/CreditForm.php 查看文件

@@ -40,6 +40,7 @@ namespace backend\models;

use common\helpers\GlobalParam;
use common\logic\Payment\Module\PaymentModule;
use common\logic\Producer\Producer\Module\ProducerModule;
use common\logic\User\User\Module\UserModule;
use common\logic\User\UserProducer\Module\UserProducerModule;
use yii\base\Model;

+ 10
- 1
backend/views/dashboard/index.php 查看文件

@@ -37,6 +37,7 @@ termes.
*/

use common\helpers\GlobalParam;
use common\logic\Distribution\Distribution\Module\DistributionModule;
use common\logic\Order\Order\Model\Order;
use common\logic\Order\Order\Module\OrderModule;
use common\logic\Producer\Producer\Module\ProducerModule;
@@ -44,6 +45,7 @@ use common\logic\Subscription\Subscription\Module\SubscriptionModule;
use common\logic\User\User\Module\UserModule;
use yii\helpers\Html ;

$distributionModule = DistributionModule::getInstance();
$userModule = UserModule::getInstance();
$orderModule = OrderModule::getInstance();
$subscriptionModule = SubscriptionModule::getInstance();
@@ -119,7 +121,14 @@ $this->setTitle('Tableau de bord');
<span class="info-box-number"></span>
<div class="buttons">
<?= Html::a('<span class="fa fa-eye"></span>', ['distribution/index', 'date' => $distribution->date], ['class' => 'btn btn-default']); ?>
<?php if(count($distribution->order)): ?><?= Html::a('<span class="fa fa-download"></span>', ['distribution/report', 'date' => $distribution->date], ['class' => 'btn btn-default']); ?><?php endif; ?>
<?php if(count($distribution->order)): ?>
<?php
$exportsEnabledArray = $distributionModule->getExportManager()->getAllEnabled();
foreach($exportsEnabledArray as $name => $export) {
echo Html::a('<span class="fa fa-download"></span>', ['distribution/export', 'name' => $name, 'date' => $distribution->date], ['class' => 'btn btn-default', 'title' => $export[0]]).' ';
}
?>
<?php endif; ?>
</div>
</div>
</div>

+ 12
- 10
backend/views/distribution/index.php 查看文件

@@ -396,17 +396,19 @@ $this->setPageTitle('Distributions') ;
</div>
</td>
<td class="column-state-payment">
<a href="javascript:void(0);" @click="orderPaymentModalClick" :data-id-order="order.id">
<order-state-payment :order="order" :producer="producer"></order-state-payment>
</a>
<span class="glyphicon glyphicon-time" title="Débit automatique du crédit la veille de la distribution" v-if="order.amount != 0 && order.isCreditAutoPayment && (order.amount_paid == 0 || order.amount_paid < order.amount)"></span>
<template v-if="!order.date_delete">
<a href="javascript:void(0);" @click="orderPaymentModalClick" :data-id-order="order.id">
<order-state-payment :order="order" :producer="producer"></order-state-payment>
</a>
<span class="glyphicon glyphicon-time" title="Débit automatique du crédit la veille de la distribution" v-if="order.amount != 0 && order.isCreditAutoPayment && (order.amount_paid == 0 || order.amount_paid < order.amount)"></span>

<div v-if="order.amount_paid > 0 && order.amount_paid < order.amount">
<span class="glyphicon glyphicon-alert"></span> Reste à payer
</div>
<div v-if="order.amount_paid > order.amount">
<span class="glyphicon glyphicon-alert"></span> Surplus à rembourser
</div>
<div v-if="order.amount_paid > 0 && order.amount_paid < order.amount">
<span class="glyphicon glyphicon-alert"></span> Reste à payer
</div>
<div v-if="order.amount_paid > order.amount">
<span class="glyphicon glyphicon-alert"></span> Surplus à rembourser
</div>
</template>
</td>
<td class="column-credit" v-if="!idActivePointSale || (pointSaleActive && pointSaleActive.credit == 1)">
<template v-if="order.isCreditContext">

+ 21
- 7
backend/views/document/_download_product_line.php 查看文件

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

use common\helpers\Price;
use common\logic\Order\ProductOrder\Module\ProductOrderModule;
use common\logic\Producer\Producer\Module\ProducerModule;
use common\logic\Product\Product\Model\Product;
use yii\helpers\Html;

$documentModule = $this->getDocumentModule();
$productModule = $this->getProductModule();
$productOrderModule = ProductOrderModule::getInstance();
$producerModule = ProducerModule::getInstance();

?>

<tr class="<?php if(isset($displayOrders) && $displayOrders): ?>order<?php endif; ?>">
<td class="align-left">
<td class="align-left column-product">
<?php if($productOrder->product): ?>
<?= Html::encode($productOrder->product->name) ?>
<?php endif; ?>
@@ -30,19 +34,29 @@ $productModule = $this->getProductModule();
?>

<?php if($displayPrices): ?>
<td class="align-center">
<?= Price::format($price, $documentPriceDecimals) ?>
<td class="align-center column-unit-price">
<?php $displayPriceUnitReference = $producerModule->getSolver()->getConfig('option_document_display_price_unit_reference'); ?>
<?php $priceUnitReference = $productOrderModule->getSolver()->getPriceUnitReference($productOrder); ?>
<?php $priceUnitReferenceString = Price::format($priceUnitReference, $documentPriceDecimals).' / kg' ?>
<?php if($productOrder->unit == 'piece'): ?>
<?= Price::format($price, $documentPriceDecimals) ?>
<?php if($priceUnitReference): ?>
(<?= $priceUnitReferenceString ?>)
<?php endif; ?>
<?php else: ?>
<?= $priceUnitReferenceString ?>
<?php endif; ?>
</td>
<?php endif; ?>
<td class="align-center">
<td class="align-center column-quantity">
<?= $productOrder->quantity * Product::$unitsArray[$productOrder->unit]['coefficient'] ?>
<?= $productModule->getSolver()->strUnit($productOrder->product, 'wording') ?>
</td>
<td class="align-center"><?= $productModule->getSolver()->strUnit($productOrder->product, 'wording') ?></td>
<?php if($displayPrices): ?>
<?php if($producer->taxRate->value != 0): ?>
<td class="align-center"><?= $productOrder->taxRate->value * 100 ?> %</td>
<td class="align-center column-tax-rate"><?= $productOrder->taxRate->value * 100 ?> %</td>
<?php endif; ?>
<td class="align-center">
<td class="align-center column-price">
<?php if($documentModule->getClass($document) == ''): ?>
<?= Price::format($price * $productOrder->quantity) ?>
<?php else: ?>

+ 41
- 35
backend/views/document/download.php 查看文件

@@ -20,13 +20,13 @@ $documentPriceDecimals = (int) $producerModule->getConfig('option_document_price
<div id="block-addresses">
<div class="producer">
<?php if (strlen($producer->logo)) : ?>
<div class="logo">
<?php $optionDocumentHeightLogo = $producerModule->getSolver()->getConfig('option_document_height_logo'); ?>
<img style="height: <?= $optionDocumentHeightLogo ?: 100; ?>px;" src="<?= $producerModule->getUrlLogo($producer) ?>"/>
<?php $optionDocumentWidthLogo = $producerModule->getSolver()->getConfig('option_document_width_logo'); ?>
<div class="logo" style="width: <?= $optionDocumentWidthLogo ?: 100; ?>px;">
<img src="<?= $producerModule->getUrlLogo($producer) ?>"/>
</div>
<?php endif; ?>
<div class="address">
<?= $producerModule->getFullAddress($producer, true); ?>
<?= $producerModule->getFullAddressAsHtml($producer); ?>
</div>
<?php if (strlen($producer->document_infos_top)): ?>
<div class="infos-top">
@@ -43,30 +43,39 @@ $documentPriceDecimals = (int) $producerModule->getConfig('option_document_price
</div>
</div>

<?php if($documentModule->getSolver()->isStatusDraft($document)): ?>
<div class="block-is-draft">
<?= $documentModule->getType($document); ?> non
validé<?= ($documentModule->getType($document) == 'Facture') ? 'e' : '' ?></div>
<?php endif; ?>

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

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

<div id="block-products">
<?php if (count($document->orders) > 0) : ?>
<table class="table table-bordered">
@@ -81,7 +90,6 @@ $documentPriceDecimals = (int) $producerModule->getConfig('option_document_price
<?php endif; ?>
<?php endif; ?>
<th>Quantité</th>
<th>Unité</th>
<?php if ($displayPrices): ?>
<?php if ($producer->taxRate->value == 0): ?>
<th>Prix</th>
@@ -108,7 +116,6 @@ $documentPriceDecimals = (int) $producerModule->getConfig('option_document_price
<td class="align-center"></td>
<?php endif; ?>
<td></td>
<td></td>
<?php if ($displayPrices): ?>
<?php if ($producer->taxRate->value != 0): ?>
<td class="align-center"></td>
@@ -148,7 +155,7 @@ $documentPriceDecimals = (int) $producerModule->getConfig('option_document_price
<?php if ($producer->taxRate->value != 0): ?>

<tr>
<td class="align-right" colspan="5"><strong>Total HT</strong></td>
<td class="align-right" colspan="4"><strong>Total HT</strong></td>
<td class="align-center">
<?= Price::format($documentModule->getAmount($document, $typeAmount)); ?>
</td>
@@ -158,31 +165,30 @@ $documentPriceDecimals = (int) $producerModule->getConfig('option_document_price
$taxRateArray = $this-> getTaxRateModule()->findTaxRatesAsArray();
foreach ($documentModule->getTotalVatArray($document, $typeAmount) as $idTaxRate => $totalVat): ?>
<tr>
<td class="align-right" colspan="5">
<td class="align-right" colspan="4">
<strong>TVA <?= $taxRateArray[$idTaxRate]->value * 100 ?> %</strong></td>
<td class="align-center">
<?= Price::format($totalVat); ?>
</td>
</tr>
<?php endforeach; ?>

<!--<tr>
<td class="align-right" colspan="5"><strong>TVA</strong></td>
<td class="align-center">
<?= Price::format($documentModule->getAmountWithTax($document, $typeAmount) - $documentModule->getAmount($document, $typeAmount)) ?>
</td>
</tr>-->
<tr>
<td class="align-right" colspan="5"><strong>Total TTC</strong></td>
<td class="align-center"><?= Price::format($documentModule->getAmountWithTax($document, $typeAmount)) ?></td>
<td class="align-right" colspan="4">
<strong>Total TTC</strong>
</td>
<td class="align-center">
<?= Price::format($documentModule->getAmountWithTax($document, $typeAmount)) ?>
</td>
</tr>
<?php else: ?>
<tr>
<td class="align-right" colspan="4">
<td class="align-right" colspan="3">
<strong>Total</strong><br/>
TVA non applicable
</td>
<td class="align-center"><?= Price::format($documentModule->getAmount($document, $typeAmount)) ?></td>
<td class="align-center">
<?= Price::format($documentModule->getAmount($document, $typeAmount)) ?>
</td>
</tr>
<?php endif; ?>
<?php endif; ?>
@@ -199,7 +205,7 @@ $documentPriceDecimals = (int) $producerModule->getConfig('option_document_price
$fieldProducerDocumentInfo = 'document_infos_' . str_replace('deliverynote', 'delivery_note', strtolower($documentModule->getClass($document))); ?>
<?php if (strlen($producer->$fieldProducerDocumentInfo)): ?>
<div class="block-infos">
<strong>Informations</strong><br/>
<strong>Informations générales</strong><br/>
<?= nl2br(Html::encode($producer->$fieldProducerDocumentInfo)) ?>
</div>
<?php endif; ?>

+ 167
- 0
backend/views/feature-admin/index.php 查看文件

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

/**
* Copyright distrib (2018)
*
* contact@opendistrib.net
*
* Ce logiciel est un programme informatique servant à aider les producteurs
* à distribuer leur production en circuits courts.
*
* Ce logiciel est régi par la licence CeCILL soumise au droit français et
* respectant les principes de diffusion des logiciels libres. Vous pouvez
* utiliser, modifier et/ou redistribuer ce programme sous les conditions
* de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
* sur le site "http://www.cecill.info".
*
* En contrepartie de l'accessibilité au code source et des droits de copie,
* de modification et de redistribution accordés par cette licence, il n'est
* offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
* seule une responsabilité restreinte pèse sur l'auteur du programme, le
* titulaire des droits patrimoniaux et les concédants successifs.
*
* A cet égard l'attention de l'utilisateur est attirée sur les risques
* associés au chargement, à l'utilisation, à la modification et/ou au
* développement et à la reproduction du logiciel par l'utilisateur étant
* donné sa spécificité de logiciel libre, qui peut le rendre complexe à
* manipuler et qui le réserve donc à des développeurs et des professionnels
* avertis possédant des connaissances informatiques approfondies. Les
* utilisateurs sont donc invités à charger et tester l'adéquation du
* logiciel à leurs besoins dans des conditions permettant d'assurer la
* sécurité de leurs systèmes et ou de leurs données et, plus généralement,
* à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
*
* Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
* pris connaissance de la licence CeCILL, et que vous en avez accepté les
* termes.
*/

use common\helpers\Price;
use lo\widgets\Toggle;
use yii\helpers\Html;
use yii\grid\GridView;

$this->setTitle('Fonctionnalités');
$this->addBreadcrumb($this->getTitle());

?>

<div class="feature-admin-index">
<?= GridView::widget([
'dataProvider' => $dataProviderFeatures,
'columns' => [
'name',
[
'attribute' => 'status',
'headerOptions' => ['class' => 'status column-hide-on-mobile'],
'filterOptions' => ['class' => 'column-hide-on-mobile'],
'contentOptions' => ['class' => 'center column-hide-on-mobile'],
'format' => 'raw',
'filter' => [0 => 'Désactivée', 1 => 'Activée'],
'value' => function ($model) {
return Toggle::widget(
[
'name' => 'active',
'checked' => $model->status,
'options' => [
'data-id' => $model->id,
'data-on' => 'Activée',
'data-off' => 'Désactivée',
],
]
);
}
],
[
'attribute' => 'producers',
'label' => 'Producteurs',
'headerOptions' => ['class' => 'column-hide-on-mobile'],
'filterOptions' => ['class' => 'column-hide-on-mobile'],
'contentOptions' => ['class' => 'column-hide-on-mobile'],
'format' => 'raw',
'value' => function ($model) {
$html = '';
foreach($model->featureProducers as $featureProducer) {
if(!is_null($featureProducer->status)) {
$html .= feature_status_producer($featureProducer->producer->name, $featureProducer->status);
}
}

return $html;
}
],
[
'attribute' => 'only_for_selected_producers',
'label' => "Producteurs sélectionnés",
'headerOptions' => ['class' => 'only-for-selected-producers column-hide-on-mobile'],
'filterOptions' => ['class' => 'column-hide-on-mobile'],
'contentOptions' => ['class' => 'only-for-selected-producers column-hide-on-mobile'],
'format' => 'raw',
'value' => function ($model) {
return '<span class="label label-'.($model->only_for_selected_producers ? 'success' : 'default').'">'
.($model->only_for_selected_producers ? 'Oui' : 'Non') .'</span>';
}
],
[
'attribute' => 'is_paid_feature',
'headerOptions' => ['class' => 'column-hide-on-mobile'],
'filterOptions' => ['class' => 'column-hide-on-mobile'],
'contentOptions' => ['class' => 'column-hide-on-mobile'],
'format' => 'raw',
'value' => function ($model) {
return '<span class="label label-'.($model->is_paid_feature ? 'success' : 'default').'">'
.($model->is_paid_feature ? 'Oui' : 'Non') .'</span>';
}
],
[
'attribute' => 'price',
'headerOptions' => ['class' => 'column-hide-on-mobile'],
'filterOptions' => ['class' => 'column-hide-on-mobile'],
'contentOptions' => ['class' => 'column-hide-on-mobile'],
'format' => 'raw',
'value' => function ($model) {
if($model->is_paid_feature && $model->price) {
return Price::format($model->price);
}

return '';
}
],
[
'class' => 'yii\grid\ActionColumn',
'template' => '{toggle_status_feature_producer} {update}',
'headerOptions' => ['class' => 'column-actions'],
'contentOptions' => ['class' => 'column-actions'],
'buttons' => [
'toggle_status_feature_producer' => function ($url, $model) use ($producerCurrent) {
return '<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
'.Html::encode($producerCurrent->name).'
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li><a href="'.Yii::$app->urlManager->createUrl(['feature-admin/toggle-status-feature-producer', 'id' => $model->id]).'">Par défaut</a></li>
<li><a href="'.Yii::$app->urlManager->createUrl(['feature-admin/toggle-status-feature-producer', 'id' => $model->id, 'status' => 1]).'">Activer</a></li>
<li><a href="'.Yii::$app->urlManager->createUrl(['feature-admin/toggle-status-feature-producer', 'id' => $model->id, 'status' => 0]).'">Désactiver</a></li>
</ul>
</div>';
},
'update' => function ($url, $model) {
return Html::a('<span class="glyphicon glyphicon-pencil"></span>', $url, [
'title' => 'Modifier', 'class' => 'btn btn-default'
]);
},
],
],
]
]);
?>
</div>

<?php

function feature_status_producer($producerName, $status): string {
return '<span class="label label-'.($status ? 'success' : 'danger').'">'.Html::encode($producerName).'</span> ';
}

?>

+ 60
- 0
backend/views/feature-admin/update.php 查看文件

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

/**
Copyright distrib (2018)

contact@opendistrib.net

Ce logiciel est un programme informatique servant à aider les producteurs
à distribuer leur production en circuits courts.

Ce logiciel est régi par la licence CeCILL soumise au droit français et
respectant les principes de diffusion des logiciels libres. Vous pouvez
utiliser, modifier et/ou redistribuer ce programme sous les conditions
de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
sur le site "http://www.cecill.info".

En contrepartie de l'accessibilité au code source et des droits de copie,
de modification et de redistribution accordés par cette licence, il n'est
offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
seule une responsabilité restreinte pèse sur l'auteur du programme, le
titulaire des droits patrimoniaux et les concédants successifs.

A cet égard l'attention de l'utilisateur est attirée sur les risques
associés au chargement, à l'utilisation, à la modification et/ou au
développement et à la reproduction du logiciel par l'utilisateur étant
donné sa spécificité de logiciel libre, qui peut le rendre complexe à
manipuler et qui le réserve donc à des développeurs et des professionnels
avertis possédant des connaissances informatiques approfondies. Les
utilisateurs sont donc invités à charger et tester l'adéquation du
logiciel à leurs besoins dans des conditions permettant d'assurer la
sécurité de leurs systèmes et ou de leurs données et, plus généralement,
à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.

Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
pris connaissance de la licence CeCILL, et que vous en avez accepté les
termes.
*/

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

$this->setTitle('Modifier une fonctionnalité') ;
$this->addBreadcrumb(['label' => 'Fonctionnalité', 'url' => ['index']]) ;
$this->addBreadcrumb('Modifier') ;

?>

<div class="feature-admin-update">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'status')->radioList([1 => 'Oui', 0 => 'Non']) ?>
<?= $form->field($model, 'name') ?>
<?= $form->field($model, 'description')->textarea(['rows' => '4']) ; ?>
<?= $form->field($model, 'only_for_selected_producers')->radioList([1 => 'Oui', 0 => 'Non']) ?>
<?= $form->field($model, 'is_paid_feature')->radioList([1 => 'Oui', 0 => 'Non']) ?>
<?= $form->field($model, 'price') ?>
<div class="form-group">
<?= Html::submitButton('Modifier', ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>

+ 4
- 2
backend/views/layouts/left.php 查看文件

@@ -37,12 +37,14 @@
*/

use common\helpers\GlobalParam;
use common\logic\Feature\Feature\Model\Feature;
use common\logic\User\User\Module\UserModule;

$producerModule = $this->getProducerModule();
$userModule = UserModule::getInstance();
$userProducerModule = $this->getUserProducerModule();
$ticketModule = $this->getTicketModule();
$featureManager = $this->getFeatureModule()->getManager();

$producer = GlobalParam::getCurrentProducer();
$userCurrent = GlobalParam::getCurrentUser();
@@ -104,7 +106,7 @@ $isUserCurrentGrantedAsProducer = $userModule->getAuthorizationChecker()->isGran
'items' => [
['label' => 'Liste', 'icon' => 'th-list', 'url' => ['/product/index'], 'visible' => $isUserCurrentGrantedAsProducer],
['label' => 'Catégories', 'icon' => 'book', 'url' => ['/product-category/index'], 'visible' => $isUserCurrentGrantedAsProducer],
['label' => 'Import prix', 'icon' => 'upload', 'url' => ['/product/price-import'], 'visible' => $isUserCurrentGrantedAsProducer],
['label' => 'Import prix', 'icon' => 'upload', 'url' => ['/product/price-import'], 'visible' => $isUserCurrentGrantedAsProducer && $featureManager->isEnabled(Feature::ALIAS_PRODUCT_PRICE_IMPORT)],
]
],
['label' => 'Points de vente', 'icon' => 'map-marker', 'url' => ['/point-sale/index'], 'visible' => $isUserCurrentGrantedAsProducer, 'active' => Yii::$app->controller->id == 'point-sale'],
@@ -180,7 +182,7 @@ $isUserCurrentGrantedAsProducer = $userModule->getAuthorizationChecker()->isGran
['label' => 'Commandes clients', 'icon' => 'calendar', 'url' => ['/stats-admin/customer-orders'], 'visible' => $isUserCurrentGrantedAsAdministrator],
],
],
['label' => 'Fonctionnalités', 'icon' => 'flag', 'url' => ['/feature-admin/index'], 'visible' => $isUserCurrentGrantedAsAdministrator],
['label' => 'Tranches de prix', 'icon' => 'eur', 'url' => ['/producer-price-range-admin/index'], 'visible' => $isUserCurrentGrantedAsAdministrator],
['label' => 'Taxes', 'icon' => 'eur', 'url' => ['/tax-rate-admin/index'], 'visible' => $isUserCurrentGrantedAsAdministrator],
['label' => 'Communiquer', 'icon' => 'bullhorn', 'url' => ['/communicate-admin/index'], 'visible' => $isUserCurrentGrantedAsAdministrator],

+ 105
- 102
backend/views/point-sale/_form.php 查看文件

@@ -53,109 +53,112 @@ $distributionModule = DistributionModule::getInstance();

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

<?php $form = ActiveForm::begin(); ?>
<div class="col-md-8">
<?= $form->field($model, 'name')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'locality')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'address')->textarea(['rows' => 6]) ?>
<?= $form->field($model, 'id_user', [
'template' => '{label} <a href="' . Yii::$app->urlManager->createUrl(['user/create']) . '" class="btn btn-xs btn-default">Nouvel utilisateur <span class="glyphicon glyphicon-plus"></span></a><div>{input}</div>{hint}',
])
->dropDownList($userModule->populateUserDropdownList(), ['class' => 'select2'])
->hint('Utilisé lors de la facturation'); ?>
<?php
$addHintCredit = '';
if (!$producerModule->getConfig('credit')):
$addHintCredit = '<br /><strong>Attention, le système de Crédit est désactivé au niveau des ' . Html::a('paramètres globaux', ['producer/update']) . '.</strong>';
endif;
echo $form->field($model, 'credit')
->checkbox()
->hint('Cochez cette case si le client peut régler ses commandes via son compte <strong>Crédit</strong> pour ce point de vente.'
. $addHintCredit);
?>
<?= $form->field($model, 'credit_functioning')
->dropDownList([
'' => 'Paramètres globaux (' . Producer::$creditFunctioningArray[$producerModule->getConfig('credit_functioning')] . ')',
Producer::CREDIT_FUNCTIONING_OPTIONAL => Producer::$creditFunctioningArray[Producer::CREDIT_FUNCTIONING_OPTIONAL],
Producer::CREDIT_FUNCTIONING_MANDATORY => Producer::$creditFunctioningArray[Producer::CREDIT_FUNCTIONING_MANDATORY],
Producer::CREDIT_FUNCTIONING_USER => Producer::$creditFunctioningArray[Producer::CREDIT_FUNCTIONING_USER],
], [])->hint(Producer::HINT_CREDIT_FUNCTIONING); ?>
<?php /*$form->field($model, 'product_price_percent')
<?php $form = ActiveForm::begin(); ?>
<div class="col-md-8">
<?= $form->field($model, 'name')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'locality')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'address')->textarea(['rows' => 6]) ?>
<?= $form->field($model, 'id_user', [
'template' => '{label} <a href="' . Yii::$app->urlManager->createUrl(['user/create']) . '" class="btn btn-xs btn-default">Nouvel utilisateur <span class="glyphicon glyphicon-plus"></span></a><div>{input}</div>{hint}',
])
->dropDownList($userModule->populateUserDropdownList(), ['class' => 'select2'])
->hint('Utilisé lors de la facturation'); ?>
<?php
$addHintCredit = '';
if (!$producerModule->getConfig('credit')):
$addHintCredit = '<br /><strong>Attention, le système de Crédit est désactivé au niveau des ' . Html::a('paramètres globaux', ['producer/update']) . '.</strong>';
endif;
echo $form->field($model, 'credit')
->checkbox()
->hint('Cochez cette case si le client peut régler ses commandes via son compte <strong>Crédit</strong> pour ce point de vente.'
. $addHintCredit);
?>
<?= $form->field($model, 'credit_functioning')
->dropDownList([
'' => 'Paramètres globaux (' . Producer::$creditFunctioningArray[$producerModule->getConfig('credit_functioning')] . ')',
Producer::CREDIT_FUNCTIONING_OPTIONAL => Producer::$creditFunctioningArray[Producer::CREDIT_FUNCTIONING_OPTIONAL],
Producer::CREDIT_FUNCTIONING_MANDATORY => Producer::$creditFunctioningArray[Producer::CREDIT_FUNCTIONING_MANDATORY],
Producer::CREDIT_FUNCTIONING_USER => Producer::$creditFunctioningArray[Producer::CREDIT_FUNCTIONING_USER],
], [])->hint(Producer::HINT_CREDIT_FUNCTIONING); ?>
<?php /*$form->field($model, 'product_price_percent')
->dropDownList( ProductPrice::percentValues(), [])->hint('Pourcentage appliqué aux prix de chaque produit dans ce point de vente.');*/ ?>

<?= $form->field($model, 'maximum_number_orders')->textInput() ?>

<h2>Boîte à pain</h2>
<?= $form->field($model, 'is_bread_box')->checkbox() ?>
<?= $form->field($model, 'bread_box_code')->textInput() ?>

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

<h2>Informations</h2>
<?= $form->field($model, 'infos_monday')->textarea(['rows' => 3]) ?>
<?= $form->field($model, 'infos_tuesday')->textarea(['rows' => 3]) ?>
<?= $form->field($model, 'infos_wednesday')->textarea(['rows' => 3]) ?>
<?= $form->field($model, 'infos_thursday')->textarea(['rows' => 3]) ?>
<?= $form->field($model, 'infos_friday')->textarea(['rows' => 3]) ?>
<?= $form->field($model, 'infos_saturday')->textarea(['rows' => 3]) ?>
<?= $form->field($model, 'infos_sunday')->textarea(['rows' => 3]) ?>
<?= $form->field($model, 'maximum_number_orders')->textInput() ?>

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

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

<h2>Livraison à domicile</h2>
<?= $form->field($model, 'is_home_delivery')->checkbox() ?>

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

<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Génération des bons de livraison</h3>
</div>
<div class="panel-body">
<?= $form->field($model, 'button_generate_delivery_note_point_sale')->checkbox() ?>
<?= $form->field($model, 'button_generate_delivery_note_each_user')->checkbox() ?>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Génération des bons de livraison</h3>
</div>
<div class="panel-body">
<?= $form->field($model, 'button_generate_delivery_note_point_sale')->checkbox() ?>
<?= $form->field($model, 'button_generate_delivery_note_each_user')->checkbox() ?>
</div>
</div>

<?php if($distributionModule->getExportManager()->isEnabled(ExportManager::SHOPPING_CART_LABELS_PDF)): ?>
<?php if ($distributionModule->getExportManager()->isEnabled(ExportManager::SHOPPING_CART_LABELS_PDF)): ?>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Exports</h3>
@@ -164,14 +167,14 @@ $distributionModule = DistributionModule::getInstance();
<?= $form->field($model, 'exclude_export_shopping_cart_labels')->checkbox(); ?>
</div>
</div>
<?php endif; ?>
</div>
<div class="clr"></div>
<?php endif; ?>
</div>
<div class="clr"></div>

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

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

</div>

+ 44
- 31
backend/views/producer/update.php 查看文件

@@ -40,6 +40,7 @@ use common\helpers\Dropdown;
use common\helpers\GlobalParam;
use common\logic\Distribution\Distribution\Module\DistributionModule;
use common\logic\User\User\Module\UserModule;
use common\logic\User\UserGroup\Module\UserGroupModule;
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use common\logic\Producer\Producer\Model\Producer;
@@ -50,8 +51,11 @@ use yii\helpers\ArrayHelper;
\backend\assets\VuejsProducerUpdateAsset::register($this);

$userModule = UserModule::getInstance();
$userCurrent = GlobalParam::getCurrentUser();
$userGroupModule = UserGroupModule::getInstance();
$distributionExportManager = DistributionModule::getInstance()->getExportManager();

$userCurrent = GlobalParam::getCurrentUser();

$this->setTitle('Paramètres');
$this->addBreadcrumb($this->getTitle());

@@ -59,7 +63,7 @@ $this->addBreadcrumb($this->getTitle());

<script>
var appInitValues = {
isAdmin: <?= (int) $userModule->getAuthorizationChecker()->isGrantedAsAdministrator($userCurrent) ?>
isAdmin: <?= (int)$userModule->getAuthorizationChecker()->isGrantedAsAdministrator($userCurrent) ?>
};
</script>

@@ -67,8 +71,8 @@ $this->addBreadcrumb($this->getTitle());

<div id="nav-params">
<a v-for="section in sectionsArray" v-if="!section.isAdminSection || (section.isAdminSection && isAdmin)"
:class="'btn '+((currentSection == section.name) ? 'btn-primary' : 'btn-default')"
@click="changeSection(section)" :href="'#'+section.name">
:class="'btn '+((currentSection == section.name) ? 'btn-primary' : 'btn-default')"
@click="changeSection(section)" :href="'#'+section.name">
{{ section.nameDisplay }}
</a>
</div>
@@ -122,6 +126,10 @@ $this->addBreadcrumb($this->getTitle());
Producer::BEHAVIOR_HOME_POINT_SALE_DAY_LIST_INCOMING_DISTRIBUTIONS => 'Distributions à venir',
]); ?>
<?= $form->field($model, 'option_point_sale_wording') ?>

<h4>Groupes utilisateurs</h4>
<?= $form->field($model, 'id_user_group_default')
->dropDownList($userGroupModule->getRepository()->populateUserGroupDropdownList()); ?>
</div>
</div>

@@ -256,10 +264,10 @@ $this->addBreadcrumb($this->getTitle());

<h4>Divers</h4>
<?php
$choicesWeeksDistributionsActivatedInAdvanceArray = [null => '--'];
for($i = 1; $i < 13; $i++) {
$choicesWeeksDistributionsActivatedInAdvanceArray[$i] = $i.' semaine'.(($i > 1) ? 's' : '');
}
$choicesWeeksDistributionsActivatedInAdvanceArray = [null => '--'];
for ($i = 1; $i < 13; $i++) {
$choicesWeeksDistributionsActivatedInAdvanceArray[$i] = $i . ' semaine' . (($i > 1) ? 's' : '');
}
?>
<?= $form->field($model, 'option_weeks_distributions_activated_in_advance')
->dropDownList($choicesWeeksDistributionsActivatedInAdvanceArray)
@@ -279,25 +287,25 @@ $this->addBreadcrumb($this->getTitle());

<div v-show="currentSection == 'exports'" class="panel panel-default">
<div class="panel-body">
<h4>Exports affichés dans les distributions</h4>
<?= $distributionExportManager->getProducerFormCheckboxes($form, $model) ?>
<h4>Options exports</h4>
<?= $form->field($model, 'option_csv_separator')
->dropDownList([
';' => 'Point-virgule (;)',
',' => 'Virgule (,)'
], []); ?>
<?= $form->field($model, 'option_export_display_product_reference')
->dropDownList(Dropdown::noYesChoices()); ?>
<?= $form->field($model, 'option_export_display_column_delivery_note')
->dropDownList(Dropdown::noYesChoices()); ?>
<?= $form->field($model, 'option_csv_export_all_products')
->dropDownList(Dropdown::noYesChoices()); ?>
<?= $form->field($model, 'option_csv_export_by_piece')
->dropDownList(Dropdown::noYesChoices()); ?>
<?= $form->field($model, 'export_shopping_cart_labels_number_per_column')
->dropDownList(Dropdown::numberChoices(1, 20)); ?>
<h4>Exports affichés dans les distributions</h4>
<?= $distributionExportManager->getProducerFormCheckboxes($form, $model) ?>
<h4>Options exports</h4>
<?= $form->field($model, 'option_csv_separator')
->dropDownList([
';' => 'Point-virgule (;)',
',' => 'Virgule (,)'
], []); ?>
<?= $form->field($model, 'option_export_display_product_reference')
->dropDownList(Dropdown::noYesChoices()); ?>
<?= $form->field($model, 'option_export_display_column_delivery_note')
->dropDownList(Dropdown::noYesChoices()); ?>
<?= $form->field($model, 'option_csv_export_all_products')
->dropDownList(Dropdown::noYesChoices()); ?>
<?= $form->field($model, 'option_csv_export_by_piece')
->dropDownList(Dropdown::noYesChoices()); ?>
<?= $form->field($model, 'export_shopping_cart_labels_number_per_column')
->dropDownList(Dropdown::numberChoices(1, 20)); ?>
</div>
</div>

@@ -339,11 +347,14 @@ $this->addBreadcrumb($this->getTitle());
'template' => '{label}<div class="input-group">{input}<span class="input-group-addon"><span class="glyphicon glyphicon-euro"></span></span></div>{hint}',
])->hint('Limite de crédit que l\'utilisateur ne pourra pas dépasser. Laisser vide pour permettre un crédit négatif et infini.'); ?>

<?= $form->field($model, 'option_check_by_default_prevent_user_credit')
->dropDownList(Dropdown::noYesChoices()); ?>

<h4>Paiement en ligne</h4>
<?= $form->field($model, 'online_payment')
->dropDownList(Dropdown::noYesChoices()); ?>
<?= $form->field($model, 'option_online_payment_minimum_amount')
->hint('Valeur par défaut si non défini : '.Producer::ONLINE_PAYMENT_MINIMUM_AMOUNT_DEFAULT.' €')
->hint('Valeur par défaut si non défini : ' . Producer::ONLINE_PAYMENT_MINIMUM_AMOUNT_DEFAULT . ' €')
->textInput(); ?>
<?= $form->field($model, 'option_stripe_mode_test')->dropDownList(Dropdown::noYesChoices()); ?>
<?= $form->field($model, 'option_online_payment_type')
@@ -403,7 +414,7 @@ $this->addBreadcrumb($this->getTitle());
0 => 'Non',
1 => 'Oui'
]); ?>
<?= $form->field($model, 'option_document_height_logo')
<?= $form->field($model, 'option_document_width_logo')
->dropDownList(Dropdown::numberChoices(50, 250, true, 'px', 50)); ?>
<?= $form->field($model, 'document_display_orders_invoice')->dropDownList(Dropdown::noYesChoices()); ?>
<?= $form->field($model, 'document_display_orders_delivery_note')->dropDownList(Dropdown::noYesChoices()); ?>
@@ -413,6 +424,8 @@ $this->addBreadcrumb($this->getTitle());
2 => '2',
3 => '3'
]); ?>
<?= $form->field($model, 'option_document_display_price_unit_reference')
->dropDownList(Dropdown::noYesChoices()); ?>
<?= $form->field($model, 'document_infos_top')
->textarea(['rows' => 8])
->hint("Affichées juste en dessous de l'adresse"); ?>
@@ -433,7 +446,7 @@ $this->addBreadcrumb($this->getTitle());
<?php $urlAboutPage = Yii::$app->urlManagerFrontend->createAbsoluteUrl(['site/about']); ?>
<?= $form->field($model, 'option_testimony')
->textarea(['rows' => 7])
->hint("Écrivez ici votre témoignage concernant l'utilisation du logiciel. Il sera publié sur la page <a href=\"".$urlAboutPage."\" target=\"_blanck\">À propos</a> du site.") ; ?>
->hint("Écrivez ici votre témoignage concernant l'utilisation du logiciel. Il sera publié sur la page <a href=\"" . $urlAboutPage . "\" target=\"_blanck\">À propos</a> du site."); ?>
<?= $form->field($model, 'option_time_saved')
->dropDownList([
null => '--',
@@ -447,7 +460,7 @@ $this->addBreadcrumb($this->getTitle());
7 => '7 heures',
8 => '8 heures',
])
->hint("Sélectionnez le temps que vous estimez gagner chaque semaine en utilisant ce logiciel. Cette donnée sera utilisée sur la page <a href=\"".$urlAboutPage."\" target=\"_blanck\">À propos</a> du site.") ; ?>
->hint("Sélectionnez le temps que vous estimez gagner chaque semaine en utilisant ce logiciel. Cette donnée sera utilisée sur la page <a href=\"" . $urlAboutPage . "\" target=\"_blanck\">À propos</a> du site."); ?>
<?= $form->field($model, 'option_display_message_new_opendistrib_version')
->dropDownList(Dropdown::noYesChoices()); ?>
</div>

+ 1
- 0
backend/views/user-import/index.php 查看文件

@@ -56,6 +56,7 @@ $this->addBreadcrumb($this->getTitle());
]); ?>

<?= $form->field($model, 'file')->fileInput() ?>
<?= $form->field($model, 'send_mail_welcome')->checkbox() ?>

<div class="form-group">
<?= Html::submitButton('Envoyer', ['class' => 'btn btn-primary']) ?>

+ 3
- 0
backend/views/user/_form.php 查看文件

@@ -68,6 +68,9 @@ $distributionModule = DistributionModule::getInstance();
<?= $form->field($model, 'name')->textInput() ?>
<?= $form->field($model, 'phone')->textInput() ?>
<?= $form->field($model, 'email')->textInput() ?>
<?php if(!$model->email): ?>
<?= $form->field($model, 'send_mail_welcome')->checkbox() ?>
<?php endif; ?>
<?= $form->field($model, 'address')->textarea() ?>

<?php if ($producerModule->getSolver()->getConfig('option_export_evoliz')): ?>

+ 18
- 0
backend/views/user/index.php 查看文件

@@ -38,6 +38,7 @@

use common\helpers\GlobalParam;
use common\logic\Producer\Producer\Module\ProducerModule;
use common\logic\User\UserGroup\Module\UserGroupModule;
use yii\helpers\Html;
use yii\grid\GridView;
use common\logic\User\User\Module\UserModule;
@@ -47,6 +48,7 @@ use common\logic\User\UserProducer\Model\UserProducer;
$userModule = UserModule::getInstance();
$producerModule = ProducerModule::getInstance();
$userCurrent = GlobalParam::getCurrentUser();
$userGroupModule = UserGroupModule::getInstance();

$this->setTitle('Utilisateurs');
$this->addBreadcrumb($this->getTitle());
@@ -113,6 +115,22 @@ $this->render('_menu', [
return $html;
}
],
[
'attribute' => 'id_user_user_group',
'header' => 'Groupes',
'format' => 'raw',
'headerOptions' => ['class' => 'column-hide-on-mobile'],
'filterOptions' => ['class' => 'column-hide-on-mobile'],
'contentOptions' => ['class' => 'column-hide-on-mobile'],
'filter' => $userGroupModule->getRepository()->populateUserGroupDropdownList(false),
'value' => function ($user) {
$html = '';
foreach($user->userUserGroup as $userUserGroup) {
$html .= '<span class="label label-default">'.$userUserGroup->userGroup->name.'</span> ';
}
return $html;
}
],
[
'attribute' => 'newsletter',
'header' => "Inscrit au bulletin<br/>d'information",

+ 65
- 44
backend/web/css/document/download.css 查看文件

@@ -1,57 +1,70 @@
/* line 5, ../../sass/document/download.scss */
/* line 4, ../../sass/document/download.scss */
body {
padding-bottom: 200px;
}

/* line 9, ../../sass/document/download.scss */
/* line 8, ../../sass/document/download.scss */
.document-download {
font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
/* line 14, ../../sass/document/download.scss */
.document-download #block-addresses {
margin-bottom: 30px;
}
/* line 17, ../../sass/document/download.scss */
.document-download #block-addresses .producer {
margin-bottom: 15px;
text-align: left;
margin-bottom: 5px;
line-height: 21px;
}
/* line 18, ../../sass/document/download.scss */
/* line 22, ../../sass/document/download.scss */
.document-download #block-addresses .producer .logo {
margin-bottom: 20px;
float: left;
padding-right: 25px;
}
/* line 26, ../../sass/document/download.scss */
.document-download #block-addresses .user {
text-align: right;
}
/* line 31, ../../sass/document/download.scss */
.document-download #block-infos-document {
padding-top: 15px;
/* line 27, ../../sass/document/download.scss */
.document-download #block-addresses .producer .name {
font-weight: bold;
font-size: 18px;
margin-bottom: 8px;
}
/* line 34, ../../sass/document/download.scss */
.document-download #block-infos-document .date {
padding-bottom: 10px;
}
/* line 37, ../../sass/document/download.scss */
.document-download #block-infos-document .reference {
padding-bottom: 10px;
font-size: 15px;
font-weight: bold;
.document-download #block-addresses .user {
text-align: right;
}
/* line 42, ../../sass/document/download.scss */
.document-download #block-infos-document .reference .block-is-draft {
border: solid 2px black;
/* line 39, ../../sass/document/download.scss */
.document-download .block-is-draft {
padding: 10px;
margin-bottom: 15px;
text-transform: uppercase;
border: solid 1px black;
}
/* line 46, ../../sass/document/download.scss */
.document-download #block-infos-document {
padding: 10px;
margin-bottom: 15px;
font-size: 11px;
line-height: 18px;
background-color: #efefef;
}
/* line 53, ../../sass/document/download.scss */
.document-download #block-infos-document .type {
text-transform: uppercase;
padding-bottom: 10px;
}
/* line 59, ../../sass/document/download.scss */
.document-download #block-no-product {
padding: 10px;
margin-bottom: 15px;
font-weight: bold;
border: solid 2px black;
text-transform: uppercase;
padding: 10px;
}
/* line 60, ../../sass/document/download.scss */
/* line 67, ../../sass/document/download.scss */
.document-download #block-products {
padding-top: 20px;
margin-bottom: 15px;
}
/* line 63, ../../sass/document/download.scss */
/* line 70, ../../sass/document/download.scss */
.document-download #block-products table {
width: 100%;
padding: 0px;
@@ -60,7 +73,7 @@ body {
border-right: solid 1px #c0c0c0;
border-collapse: collapse;
}
/* line 71, ../../sass/document/download.scss */
/* line 78, ../../sass/document/download.scss */
.document-download #block-products table td, .document-download #block-products table th {
padding: 2px 5px;
border-top: solid 1px #c0c0c0;
@@ -68,48 +81,56 @@ body {
font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 12px;
}
/* line 78, ../../sass/document/download.scss */
/* line 85, ../../sass/document/download.scss */
.document-download #block-products table td.align-left, .document-download #block-products table th.align-left {
text-align: left;
}
/* line 81, ../../sass/document/download.scss */
/* line 89, ../../sass/document/download.scss */
.document-download #block-products table td.align-center, .document-download #block-products table th.align-center {
text-align: center;
}
/* line 84, ../../sass/document/download.scss */
/* line 93, ../../sass/document/download.scss */
.document-download #block-products table td.align-right, .document-download #block-products table th.align-right {
text-align: right;
}
/* line 89, ../../sass/document/download.scss */
/* line 98, ../../sass/document/download.scss */
.document-download #block-products table td {
font-size: 11px;
}
/* line 95, ../../sass/document/download.scss */
/* line 103, ../../sass/document/download.scss */
.document-download #block-products table td.column-unit-price {
width: 120px;
}
/* line 107, ../../sass/document/download.scss */
.document-download #block-products table td.column-tax-rate, .document-download #block-products table td.column-price {
width: 70px;
}
/* line 112, ../../sass/document/download.scss */
.document-download #block-products table td.column-quantity {
width: 80px;
}
/* line 119, ../../sass/document/download.scss */
.document-download .block-infos {
margin-top: 20px;
padding: 10px;
margin-bottom: 15px;
border: solid 1px #c0c0c0;
padding: 10px;
background-color: transparent;
font-size: 11px;
}
/* line 100, ../../sass/document/download.scss */
/* line 126, ../../sass/document/download.scss */
.document-download .block-infos strong {
font-size: 12px;
}

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

+ 6
- 0
backend/web/css/screen.css 查看文件

@@ -2796,6 +2796,12 @@ termes.
margin-top: 5px;
}

/* line 4, ../sass/feature-admin/_index.scss */
.feature-admin-index table th.only-for-selected-producers,
.feature-admin-index table td.only-for-selected-producers {
width: 100px;
}

/**
Copyright distrib (2018)


+ 62
- 56
backend/web/js/backend.js 查看文件

@@ -53,6 +53,8 @@ $(document).ready(function () {
opendistrib_dropdown_producers();
opendistrib_gridview_pagesize();
opendistrib_producers_admin();
opendistrib_user_form();
opendistrib_features_index();
});

var UrlManager = {
@@ -65,8 +67,31 @@ var UrlManager = {
}
};

function opendistrib_user_form() {
if($('#app-user-form').length) {
var $fieldUserEmail = $('#app-user-form .field-user-email input');
var $fieldSendMailWelcome = $('#app-user-form .field-user-send_mail_welcome');

opendistrib_user_form_event($fieldUserEmail, $fieldSendMailWelcome);
$fieldUserEmail.keyup(function () {
opendistrib_user_form_event($fieldUserEmail, $fieldSendMailWelcome);
});
}
}

function opendistrib_user_form_event($fieldUserEmail, $fieldSendMailWelcome) {
var val = $fieldUserEmail.val();

if (val.length > 0) {
$fieldSendMailWelcome.show();
}
else {
$fieldSendMailWelcome.hide();
}
}

function opendistrib_producers_admin() {
$('.producer-admin-index .btn-alwaysdata, .producer-admin-index .btn-dolibarr').click(function() {
$('.producer-admin-index .btn-alwaysdata, .producer-admin-index .btn-dolibarr').click(function () {
var $button = $(this);
$button.attr('disabled', 'disabled');
axios.get($button.attr('href'), {})
@@ -79,47 +104,44 @@ function opendistrib_producers_admin() {
}

function opendistrib_gridview_pagesize() {
$('.gridview-pagesize select').change(function() {
$('.gridview-pagesize select').change(function () {
$(this).parent().parent().submit();
});
}

function opendistrib_dropdown_producers() {

$('.producer-menu .dropdown-toggle').click(function() {
$('.producer-menu .dropdown-toggle').click(function () {
$('.producer-menu .search-producer').focus();
});

$('.producer-menu .search-producer').keyup(function() {
$('.producer-menu .search-producer').keyup(function () {
var $alertNoResults = $('.producer-menu .li-alert-no-results');
var searchWords = $(this).val().toLowerCase();
var count = 0;

if(searchWords && searchWords.length > 0) {
$('.producer-menu li.producer').each(function() {
if($(this).find('a').text().toLowerCase().indexOf(searchWords) >= 0 || !searchWords) {
if (searchWords && searchWords.length > 0) {
$('.producer-menu li.producer').each(function () {
if ($(this).find('a').text().toLowerCase().indexOf(searchWords) >= 0 || !searchWords) {
$(this).show();
count ++;
}
else {
count++;
} else {
$(this).hide();
}
});

if(count) {
if (count) {
$alertNoResults.hide();
}
else {
} else {
$alertNoResults.show();
}
}
else {
} else {
$alertNoResults.hide();
$('.producer-menu li.producer').show();
}
});

$('#link-display-producers-offline').click(function() {
$('#link-display-producers-offline').click(function () {
$(this).hide();
$('.producer-menu .offline').show();
return false;
@@ -152,7 +174,7 @@ function opendistrib_menu_treeview() {
}

function opendistrib_product_index() {
$('body.product-index .toggle input').change(function() {
$('body.product-index .toggle input').change(function () {
var id = $(this).data('id');
var checked = $(this).prop('checked');
$.get(UrlManager.getBaseUrl() + 'product/ajax-toggle-status', {
@@ -207,7 +229,7 @@ function opendistrib_products_event_price_with_tax() {
taxRateSelected = 0;
}

if($('#product-price').length) {
if ($('#product-price').length) {
var price = $('#product-price').val().replace(',', '.');
if (price) {
$('#product-price-with-tax').val(getPriceWithTax(price, taxRateSelected));
@@ -276,7 +298,7 @@ function opendistrib_product_prices() {
opendistrib_product_prices_event_price_with_tax();
$('#productprice-price').change(opendistrib_product_prices_event_price_with_tax);
$('#productprice-price-with-tax').change(opendistrib_product_prices_event_price);
$('#reduction-increase-percent').change(function() {
$('#reduction-increase-percent').change(function () {
opendistrib_product_prices_event_reduction_increase();
});
}
@@ -305,6 +327,7 @@ function opendistrib_product_prices_event_price() {
opendistrib_product_prices_update_reduction_increase();
}
}

function opendistrib_product_prices_update_reduction_increase() {
var productPriceBase = $('#reduction-increase-percent').data('price-base');
var productPriceSpecific = $('#productprice-price').val().replace(',', '.');
@@ -315,7 +338,7 @@ function opendistrib_product_prices_update_reduction_increase() {
function opendistrib_product_prices_event_reduction_increase() {
var productPriceBase = $('#reduction-increase-percent').data('price-base');
var reductionIncreasePercent = $('#reduction-increase-percent').val();
if(reductionIncreasePercent) {
if (reductionIncreasePercent) {
var newPrice = productPriceBase + productPriceBase * (reductionIncreasePercent / 100);
$('#productprice-price').val(parseFloat(newPrice).toFixed(5));
opendistrib_product_prices_event_price_with_tax();
@@ -421,44 +444,27 @@ function opendistrib_ordre_produits() {
'.btn-order',
'product/order'
);
}

/*var fixHelper = function(e, ui) {
ui.children().each(function() {
$(this).width($(this).width());
});
return ui;
};
$(".product-index table tbody").sortable({
items: "> tr",
appendTo: "parent",
cursor: "move",
placeholder: "ui-state-highlight",
handle: '.btn-order',
//helper: "clone"
helper: fixHelper,
stop: function(event, ui) {
var tab_ordre = {} ;
var ordre = 1 ;
if($('ul.pagination').size()) {
var page = parseInt($('ul.pagination li.active a').html()) ;
var nb_items_by_page = parseInt($('#page-size').html()) ;
if(page != 1) {
ordre = (page - 1) * nb_items_by_page ;
}
function opendistrib_features_index() {
$('body.feature-admin-index .toggle input').change(function () {
var id = $(this).data('id');
var checked = $(this).prop('checked');
/*$.get(UrlManager.getBaseUrl() + 'feature-admin/ajax-toggle-status', {
id: id,
status: checked ? 1 : 0
});*/

axios.get(UrlManager.getBaseUrlAbsolute() + "feature-admin/ajax-toggle-status", {
params: {
id: id,
status: checked ? 1 : 0
}
$(".product-index table tbody tr").each(function() {
tab_ordre[$(this).attr('data-key')] = ordre ;
ordre++ ;
}) ;
$.post(UrlManager.getBaseUrl()+'product/order',{
array: JSON.stringify(tab_ordre)
}) ;
}
}).disableSelection();*/
})
.then(function (response) {
appAlerts.alertResponse(response);
});
})
}

function opendistrib_datepicker() {

+ 123
- 102
backend/web/sass/document/download.scss 查看文件

@@ -1,121 +1,142 @@

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

body {
padding-bottom: 200px ;
padding-bottom: 200px;
}

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

#block-addresses {

.producer {
text-align: left ;
margin-bottom: 5px ;

.logo {
margin-bottom: 20px ;

}
.address {

}
}
.user {
text-align: right ;
}
$margin-bottom-block: 15px;
$padding-block: 10px;

font-family: $font-family;

#block-addresses {
margin-bottom: 2*$margin-bottom-block;

.producer {
margin-bottom: $margin-bottom-block;
text-align: left;
line-height: 21px;

.logo {
float: left;
padding-right: 25px;
}

.name {
font-weight: bold;
font-size: 18px;
margin-bottom: 8px;
}
}

.user {
text-align: right;
}
}

.block-is-draft {
padding: $padding-block;
margin-bottom: $margin-bottom-block;
text-transform: uppercase;
border: solid 1px black;
}

#block-infos-document {
padding: $padding-block;
margin-bottom: $margin-bottom-block;
font-size: 11px;
line-height: 18px;
background-color: #efefef;

.type {
text-transform: uppercase;
padding-bottom: 10px;
}
}

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

#block-products {
margin-bottom: $margin-bottom-block;

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

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

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

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

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

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

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

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

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

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

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

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

td {
font-size: 11px;
}
}
td {
font-size: 11px;

&.column-product {}

&.column-unit-price {
width: 120px;
}

.block-infos {
margin-top: 20px ;
padding: 10px ;
border: solid 1px $border-color ;
&.column-tax-rate,
&.column-price {
width: 70px;
}

strong {
font-size: 12px ;
}
&.column-quantity {
width: 80px;
}
}
}
}

.block-infos {
margin-bottom: $margin-bottom-block;
border: solid 1px $border-color;
padding: $padding-block;
background-color: transparent;
font-size: 11px;

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

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

.infos-bottom {
padding-bottom: 20px ;
margin-bottom: 40px ;
font-size: 12px ;
line-height: 18px ;
}
.reference-document {
font-weight: bold ;
}
font-family: $font-family;
text-align: center;
padding-top: 10px;
border-top: solid 1px gray;

.infos-bottom {
font-size: 12px;
line-height: 18px;
}
}

+ 9
- 0
backend/web/sass/feature-admin/_index.scss 查看文件

@@ -0,0 +1,9 @@

.feature-admin-index {
table {
th.only-for-selected-producers,
td.only-for-selected-producers {
width: 100px;
}
}
}

+ 1
- 0
backend/web/sass/screen.scss 查看文件

@@ -1534,4 +1534,5 @@ a.btn, button.btn {
@import "support/_index.scss";
@import "support/_view.scss";
@import "producer-admin/_index.scss";
@import "feature-admin/_index.scss";
@import "_responsive.scss" ;

+ 2
- 0
common/components/BusinessLogic.php 查看文件

@@ -15,6 +15,8 @@ class BusinessLogic
public function getModules()
{
return [
$this->getFeatureModule(),
$this->getFeatureProducerModule(),
$this->getUnitModule(),
$this->getTaxRateModule(),
$this->getUserUserGroupModule(),

+ 12
- 0
common/components/BusinessLogicTrait.php 查看文件

@@ -11,6 +11,8 @@ use common\logic\Document\DeliveryNote\Module\DeliveryNoteModule;
use common\logic\Document\Document\Module\DocumentModule;
use common\logic\Document\Invoice\Module\InvoiceModule;
use common\logic\Document\Quotation\Module\QuotationModule;
use common\logic\Feature\Feature\Module\FeatureModule;
use common\logic\Feature\FeatureProducer\Module\FeatureProducerModule;
use common\logic\Opinion\Module\OpinionModule;
use common\logic\Order\Order\Module\OrderModule;
use common\logic\Order\ProductOrder\Module\ProductOrderModule;
@@ -184,4 +186,14 @@ trait BusinessLogicTrait
{
return TicketUserModule::getInstance();
}

public function getFeatureModule(): FeatureModule
{
return FeatureModule::getInstance();
}

public function getFeatureProducerModule(): FeatureProducerModule
{
return FeatureProducerModule::getInstance();
}
}

+ 5
- 0
common/logic/AbstractRepository.php 查看文件

@@ -84,4 +84,9 @@ abstract class AbstractRepository extends AbstractService implements RepositoryI
{
return $this->createQuery()->find();
}

public function queryAll()
{
return $this->createQuery();
}
}

+ 14
- 0
common/logic/Distribution/Distribution/Service/ExportManager.php 查看文件

@@ -53,6 +53,20 @@ class ExportManager extends AbstractManager
];
}

public function getAllEnabled(): array
{
$exportsArray = $this->getAll();
$exportsEnabledArray = [];

foreach($exportsArray as $name => $export) {
if($this->isEnabled($name)) {
$exportsEnabledArray[$name] = $export;
}
}

return $exportsEnabledArray;
}

public function getExport(string $exportName): array
{
$exportsArray = $this->getAll();

+ 0
- 13
common/logic/Document/Document/Service/DocumentManager.php 查看文件

@@ -53,19 +53,6 @@ class DocumentManager extends AbstractManager

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

$marginBottom = 10;

+ 93
- 0
common/logic/Feature/Feature/Model/Feature.php 查看文件

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

/**
* Copyright distrib (2018)
*
* contact@opendistrib.net
*
* Ce logiciel est un programme informatique servant à aider les producteurs
* à distribuer leur production en circuits courts.
*
* Ce logiciel est régi par la licence CeCILL soumise au droit français et
* respectant les principes de diffusion des logiciels libres. Vous pouvez
* utiliser, modifier et/ou redistribuer ce programme sous les conditions
* de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
* sur le site "http://www.cecill.info".
*
* En contrepartie de l'accessibilité au code source et des droits de copie,
* de modification et de redistribution accordés par cette licence, il n'est
* offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
* seule une responsabilité restreinte pèse sur l'auteur du programme, le
* titulaire des droits patrimoniaux et les concédants successifs.
*
* A cet égard l'attention de l'utilisateur est attirée sur les risques
* associés au chargement, à l'utilisation, à la modification et/ou au
* développement et à la reproduction du logiciel par l'utilisateur étant
* donné sa spécificité de logiciel libre, qui peut le rendre complexe à
* manipuler et qui le réserve donc à des développeurs et des professionnels
* avertis possédant des connaissances informatiques approfondies. Les
* utilisateurs sont donc invités à charger et tester l'adéquation du
* logiciel à leurs besoins dans des conditions permettant d'assurer la
* sécurité de leurs systèmes et ou de leurs données et, plus généralement,
* à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
*
* Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
* pris connaissance de la licence CeCILL, et que vous en avez accepté les
* termes.
*/

namespace common\logic\Feature\Feature\Model;

use common\components\ActiveRecordCommon;
use common\logic\Feature\FeatureProducer\Model\FeatureProducer;
use yii\db\ActiveQuery;
use yii\db\Schema;

class Feature extends ActiveRecordCommon
{
const ALIAS_CONTACT = 'contact';
const ALIAS_PRODUCT_PRICE_IMPORT = 'product_price_import';

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

/**
* @inheritdoc
*/
public function rules()
{
return [
[['alias', 'name'], 'required'],
[['status', 'is_paid_feature', 'only_for_selected_producers'], 'boolean'],
[['price'], 'double'],
[['alias', 'name', 'description'], 'string'],
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'alias' => 'Alias',
'name' => 'Nom',
'description' => 'Description',
'status' => 'Statut',
'is_paid_feature' => "Fonctionnalité payante",
'price' => 'Prix',
'only_for_selected_producers' => 'Uniquement pour les producteurs sélectionnés'
];
}

public function getFeatureProducers(): ActiveQuery
{
return $this->hasMany(FeatureProducer::class, ['id_feature' => 'id']);
}
}

+ 49
- 0
common/logic/Feature/Feature/Module/FeatureModule.php 查看文件

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

namespace common\logic\Feature\Feature\Module;

use common\logic\AbstractModule;
use common\logic\Feature\Feature\Repository\FeatureRepository;
use common\logic\Feature\Feature\Service\FeatureBuilder;
use common\logic\Feature\Feature\Service\FeatureDefinition;
use common\logic\Feature\Feature\Service\FeatureImporter;
use common\logic\Feature\Feature\Service\FeatureManager;

class FeatureModule extends AbstractModule
{
public function getServices(): array
{
return [
FeatureDefinition::class,
FeatureRepository::class,
FeatureBuilder::class,
FeatureImporter::class,
FeatureManager::class
];
}

public function getDefinition(): FeatureDefinition
{
return FeatureDefinition::getInstance();
}

public function getRepository(): FeatureRepository
{
return FeatureRepository::getInstance();
}

public function getBuilder(): FeatureBuilder
{
return FeatureBuilder::getInstance();
}

public function getImporter(): FeatureImporter
{
return FeatureImporter::getInstance();
}

public function getManager(): FeatureManager
{
return FeatureManager::getInstance();
}
}

+ 40
- 0
common/logic/Feature/Feature/Repository/FeatureRepository.php 查看文件

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

namespace common\logic\Feature\Feature\Repository;

use common\logic\AbstractRepository;
use common\logic\Feature\Feature\Model\Feature;

class FeatureRepository extends AbstractRepository
{
protected FeatureRepositoryQuery $query;

public function loadDependencies(): void
{
$this->loadQuery(FeatureRepositoryQuery::class);
}
public function getDefaultOptionsSearch(): array
{
return [
self::WITH => ['featureProducers'],
self::JOIN_WITH => [],
self::ORDER_BY => '',
self::ATTRIBUTE_ID_PRODUCER => ''
];
}

public function findOneFeatureById(int $id): ?Feature
{
return $this->createQuery()
->filterById($id)
->findOne();
}

public function findOneFeatureByAlias(string $alias): ?Feature
{
return $this->createQuery()
->filterByAlias($alias)
->findOne();
}
}

+ 22
- 0
common/logic/Feature/Feature/Repository/FeatureRepositoryQuery.php 查看文件

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

namespace common\logic\Feature\Feature\Repository;

use common\logic\AbstractRepositoryQuery;
use common\logic\Feature\Feature\Service\FeatureDefinition;

class FeatureRepositoryQuery extends AbstractRepositoryQuery
{
protected FeatureDefinition $definition;

public function loadDependencies(): void
{
$this->loadDefinition(FeatureDefinition::class);
}

public function filterByAlias(string $alias): self
{
$this->andWhere(['alias' => $alias]);
return $this;
}
}

+ 60
- 0
common/logic/Feature/Feature/Service/FeatureBuilder.php 查看文件

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

namespace common\logic\Feature\Feature\Service;

use common\logic\AbstractBuilder;
use common\logic\Feature\Feature\Model\Feature;
use common\logic\Feature\Feature\Repository\FeatureRepository;

class FeatureBuilder extends AbstractBuilder
{
protected FeatureRepository $featureRepository;

public function loadDependencies(): void
{
$this->featureRepository = $this->loadService(FeatureRepository::class);
}

public function instanciateFeature(
string $alias,
string $name,
string $description,
bool $status = true,
bool $isPaidFeature = false,
float $price = null
): Feature
{
$feature = new Feature();
$feature->alias = $alias;
$feature->name = $name;
$feature->description = $description;
$feature->status = $status;
$feature->is_paid_feature = $isPaidFeature;
$feature->price = $price;

return $feature;
}

public function createFeature(
string $alias,
string $name,
string $description,
bool $status = true,
bool $isPaidFeature = false,
float $price = null
): Feature
{
$feature = $this->featureRepository->findOneFeatureByAlias($alias);
if(!$feature) {
$feature = $this->instanciateFeature($alias, $name, $description, $status, $isPaidFeature, $price);
$this->create($feature);
}
return $feature;
}

public function updateStatus(Feature $feature, bool $status)
{
$feature->status = $status;
$this->update($feature);
}
}

+ 31
- 0
common/logic/Feature/Feature/Service/FeatureDefinition.php 查看文件

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

namespace common\logic\Feature\Feature\Service;

use common\logic\AbstractDefinition;
use common\logic\Feature\Feature\Model\Feature;

class FeatureDefinition extends AbstractDefinition
{
public function getEntityFqcn(): string
{
return Feature::class;
}

public function getFeaturesBase(): array
{
return [
Feature::ALIAS_CONTACT => $this->buildFeatureArray('Formulaire de contact', true, false),
Feature::ALIAS_PRODUCT_PRICE_IMPORT => $this->buildFeatureArray('Produits : import prix', true, false),
];
}

public function buildFeatureArray(string $name, bool $status, bool $isPaidFeature): array
{
return [
'name' => $name,
'status' => $status,
'is_paid_feature' => $isPaidFeature
];
}
}

+ 32
- 0
common/logic/Feature/Feature/Service/FeatureImporter.php 查看文件

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

namespace common\logic\Feature\Feature\Service;

use common\logic\AbstractManager;

class FeatureImporter extends AbstractManager
{
protected FeatureDefinition $featureDefinition;
protected FeatureBuilder $featureBuilder;

public function loadDependencies(): void
{
$this->featureDefinition = $this->loadService(FeatureDefinition::class);
$this->featureBuilder = $this->loadService(FeatureBuilder::class);
}

public function importFromDefinition()
{
$featuresBaseArray = $this->featureDefinition->getFeaturesBase();

foreach($featuresBaseArray as $alias => $featureBase) {
$this->featureBuilder->createFeature(
$alias,
$featureBase['name'],
'',
$featureBase['status'],
$featureBase['is_paid_feature']
);
}
}
}

+ 80
- 0
common/logic/Feature/Feature/Service/FeatureManager.php 查看文件

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

namespace common\logic\Feature\Feature\Service;

use common\logic\AbstractManager;
use common\logic\Feature\Feature\Model\Feature;
use common\logic\Feature\Feature\Repository\FeatureRepository;
use common\logic\Feature\FeatureProducer\Repository\FeatureProducerRepository;
use common\logic\Feature\FeatureProducer\Service\FeatureProducerBuilder;
use yii\base\ErrorException;

class FeatureManager extends AbstractManager
{
protected FeatureRepository $featureRepository;
protected FeatureProducerRepository $featureProducerRepository;
protected FeatureBuilder $featureBuilder;
protected FeatureProducerBuilder $featureProducerBuilder;

public function loadDependencies(): void
{
$this->featureRepository = $this->loadService(FeatureRepository::class);
$this->featureProducerRepository = $this->loadService(FeatureProducerRepository::class);
$this->featureBuilder = $this->loadService(FeatureBuilder::class);
$this->featureProducerBuilder = $this->loadService(FeatureProducerBuilder::class);
}

public function isEnabled(string $aliasFeature): bool
{
$feature = $this->featureRepository->findOneFeatureByAlias($aliasFeature);
if(!$feature) {
throw new ErrorException("Fonctionnalité avec l'alias '".$aliasFeature."' non trouvée");
}

if(!$feature->status) {
return false;
}

$featureProducer = $this->featureProducerRepository->findOneFeatureProducer($feature);
if(!$featureProducer || is_null($featureProducer->status)) {
if($feature->is_paid_feature || $feature->only_for_selected_producers) {
return false;
}

return $feature->status;
}
else {
return $featureProducer->status;
}
}

public function isDisabled(string $aliasFeature): bool
{
return !$this->isEnabled($aliasFeature);
}

public function enable(Feature $feature): void
{
$this->featureBuilder->updateStatus($feature, true);
}

public function disable(Feature $feature): void
{
$this->featureBuilder->updateStatus($feature, false);
}

public function enableForProducer(Feature $feature)
{
$this->featureProducerBuilder->updateStatusByFeature($feature, true);
}

public function disableForProducer(Feature $feature)
{
$this->featureProducerBuilder->updateStatusByFeature($feature, false);
}

public function defaultForProducer(Feature $feature)
{
$this->featureProducerBuilder->updateStatusByFeature($feature, null);
}
}

+ 96
- 0
common/logic/Feature/FeatureProducer/Model/FeatureProducer.php 查看文件

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

/**
* Copyright distrib (2018)
*
* contact@opendistrib.net
*
* Ce logiciel est un programme informatique servant à aider les producteurs
* à distribuer leur production en circuits courts.
*
* Ce logiciel est régi par la licence CeCILL soumise au droit français et
* respectant les principes de diffusion des logiciels libres. Vous pouvez
* utiliser, modifier et/ou redistribuer ce programme sous les conditions
* de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
* sur le site "http://www.cecill.info".
*
* En contrepartie de l'accessibilité au code source et des droits de copie,
* de modification et de redistribution accordés par cette licence, il n'est
* offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
* seule une responsabilité restreinte pèse sur l'auteur du programme, le
* titulaire des droits patrimoniaux et les concédants successifs.
*
* A cet égard l'attention de l'utilisateur est attirée sur les risques
* associés au chargement, à l'utilisation, à la modification et/ou au
* développement et à la reproduction du logiciel par l'utilisateur étant
* donné sa spécificité de logiciel libre, qui peut le rendre complexe à
* manipuler et qui le réserve donc à des développeurs et des professionnels
* avertis possédant des connaissances informatiques approfondies. Les
* utilisateurs sont donc invités à charger et tester l'adéquation du
* logiciel à leurs besoins dans des conditions permettant d'assurer la
* sécurité de leurs systèmes et ou de leurs données et, plus généralement,
* à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
*
* Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
* pris connaissance de la licence CeCILL, et que vous en avez accepté les
* termes.
*/

namespace common\logic\Feature\FeatureProducer\Model;

use common\components\ActiveRecordCommon;
use common\logic\Feature\Feature\Model\Feature;
use common\logic\Producer\Producer\Model\Producer;
use yii\db\ActiveQuery;

class FeatureProducer extends ActiveRecordCommon
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'feature_producer';
}

/**
* @inheritdoc
*/
public function rules()
{
return [
[['id_producer', 'id_feature'], 'required'],
[['status'], 'boolean'],
];
}

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

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

public function populateProducer(Producer $producer): void
{
$this->populateFieldObject('id_producer', 'producer', $producer);
}

public function getFeature(): ActiveQuery
{
return $this->hasOne(Feature::class, ['id' => 'id_feature']);
}

public function populateFeature(Feature $feature): void
{
$this->populateFieldObject('id_feature', 'feature', $feature);
}
}

+ 35
- 0
common/logic/Feature/FeatureProducer/Module/FeatureProducerModule.php 查看文件

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

namespace common\logic\Feature\FeatureProducer\Module;

use common\logic\AbstractModule;
use common\logic\Feature\FeatureProducer\Repository\FeatureProducerRepository;
use common\logic\Feature\FeatureProducer\Service\FeatureProducerBuilder;
use common\logic\Feature\FeatureProducer\Service\FeatureProducerDefinition;

class FeatureProducerModule extends AbstractModule
{
public function getServices(): array
{
return [
FeatureProducerDefinition::class,
FeatureProducerRepository::class,
FeatureProducerBuilder::class
];
}

public function getDefinition(): FeatureProducerDefinition
{
return FeatureProducerDefinition::getInstance();
}

public function getRepository(): FeatureProducerRepository
{
return FeatureProducerRepository::getInstance();
}

public function getBuilder(): FeatureProducerBuilder
{
return FeatureProducerBuilder::getInstance();
}
}

+ 34
- 0
common/logic/Feature/FeatureProducer/Repository/FeatureProducerRepository.php 查看文件

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

namespace common\logic\Feature\FeatureProducer\Repository;

use common\logic\AbstractRepository;
use common\logic\Feature\Feature\Model\Feature;
use common\logic\Producer\Producer\Model\Producer;

class FeatureProducerRepository extends AbstractRepository
{
protected FeatureProducerRepositoryQuery $query;

public function loadDependencies(): void
{
$this->loadQuery(FeatureProducerRepositoryQuery::class);
}

public function getDefaultOptionsSearch(): array
{
return [
self::WITH => ['feature', 'producer'],
self::JOIN_WITH => [],
self::ORDER_BY => '',
self::ATTRIBUTE_ID_PRODUCER => 'feature_producer.id_producer'
];
}

public function findOneFeatureProducer(Feature $feature)
{
return $this->createDefaultQuery()
->filterByFeature($feature)
->findOne();
}
}

+ 23
- 0
common/logic/Feature/FeatureProducer/Repository/FeatureProducerRepositoryQuery.php 查看文件

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

namespace common\logic\Feature\FeatureProducer\Repository;

use common\logic\AbstractRepositoryQuery;
use common\logic\Feature\Feature\Model\Feature;
use common\logic\Feature\FeatureProducer\Service\FeatureProducerDefinition;

class FeatureProducerRepositoryQuery extends AbstractRepositoryQuery
{
protected FeatureProducerDefinition $definition;

public function loadDependencies(): void
{
$this->loadDefinition(FeatureProducerDefinition::class);
}

public function filterByFeature(Feature $feature): self
{
$this->andWhere(['id_feature' => $feature]);
return $this;
}
}

+ 58
- 0
common/logic/Feature/FeatureProducer/Service/FeatureProducerBuilder.php 查看文件

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

namespace common\logic\Feature\FeatureProducer\Service;

use common\logic\AbstractBuilder;
use common\logic\Feature\Feature\Model\Feature;
use common\logic\Feature\FeatureProducer\Model\FeatureProducer;
use common\logic\Feature\FeatureProducer\Repository\FeatureProducerRepository;
use common\logic\Producer\Producer\Model\Producer;

class FeatureProducerBuilder extends AbstractBuilder
{
protected FeatureProducerRepository $featureProducerRepository;

public function loadDependencies(): void
{
$this->featureProducerRepository = $this->loadService(FeatureProducerRepository::class);
}

public function instanciateFeatureProducer(
Feature $feature,
bool $status = null
): FeatureProducer
{
$featureProducer = new FeatureProducer();
$featureProducer->populateFeature($feature);
$featureProducer->populateProducer($this->getProducerContext());
$featureProducer->status = $status;

return $featureProducer;
}

public function createFeatureProducer(
Feature $feature,
bool $status = null
): FeatureProducer
{
$featureProducer = $this->featureProducerRepository->findOneFeatureProducer($feature);
if(!$featureProducer) {
$featureProducer = $this->instanciateFeatureProducer($feature, $status);
$this->create($featureProducer);
}

return $featureProducer;
}

public function updateStatus(FeatureProducer $featureProducer, bool $status = null)
{
$featureProducer->status = $status;
$this->update($featureProducer);
}

public function updateStatusByFeature(Feature $feature, bool $status = null)
{
$featureProducer = $this->createFeatureProducer($feature, $status);
$this->updateStatus($featureProducer, $status);
}
}

+ 25
- 0
common/logic/Feature/FeatureProducer/Service/FeatureProducerDefinition.php 查看文件

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

namespace common\logic\Feature\FeatureProducer\Service;

use common\logic\AbstractDefinition;
use common\logic\Feature\FeatureProducer\Model\FeatureProducer;
use common\logic\Feature\FeatureProducer\Repository\FeatureProducerRepository;

class FeatureProducerDefinition extends AbstractDefinition
{
public function getEntityFqcn(): string
{
return FeatureProducer::class;
}

public function getDefinition(): FeatureProducerDefinition
{
return FeatureProducerDefinition::getInstance();
}

public function getRepository(): FeatureProducerRepository
{
return FeatureProducerRepository::getInstance();
}
}

+ 1
- 1
common/logic/Order/Order/Service/OrderSolver.php 查看文件

@@ -170,7 +170,7 @@ class OrderSolver extends AbstractService implements SolverInterface
$comment .= '<br /><br />';
}

$comment .= '<strong>Livraison à domicile :</strong><br />';
$comment .= '<strong>Adresse :</strong><br />';
$comment .= nl2br($order->delivery_address);
}


+ 17
- 0
common/logic/Order/ProductOrder/Service/ProductOrderSolver.php 查看文件

@@ -69,4 +69,21 @@ class ProductOrderSolver extends AbstractService implements SolverInterface

return $productOrder->price;
}

public function getPriceUnitReference(ProductOrder $productOrder): ?float
{
if($productOrder->unit == 'piece') {
if($productOrder->product->weight) {
$price = (1000 * $productOrder->price) / $productOrder->product->weight;
}
else {
return null;
}
}
else {
$price = $productOrder->price;
}

return $price;
}
}

+ 3
- 1
common/logic/PointSale/PointSale/Model/PointSale.php 查看文件

@@ -80,7 +80,8 @@ class PointSale extends ActiveRecordCommon
[['point_production', 'credit', 'delivery_monday', 'delivery_tuesday',
'delivery_wednesday', 'delivery_thursday', 'delivery_friday',
'delivery_saturday', 'delivery_sunday', 'default', 'is_bread_box',
'button_generate_delivery_note_point_sale', 'button_generate_delivery_note_each_user', 'exclude_export_shopping_cart_labels'], 'boolean'],
'button_generate_delivery_note_point_sale', 'button_generate_delivery_note_each_user',
'exclude_export_shopping_cart_labels', 'is_home_delivery'], 'boolean'],
['point_production', 'default', 'value' => 0],
[['id_producer', 'id_user', 'maximum_number_orders', 'status'], 'integer'],
['id_producer', 'required'],
@@ -128,6 +129,7 @@ class PointSale extends ActiveRecordCommon
'button_generate_delivery_note_point_sale' => 'Activer le bouton de génération de bon de livraison par point de vente',
'button_generate_delivery_note_each_user' => 'Activer le bouton de génération de bon de livraison par client',
'exclude_export_shopping_cart_labels' => "Exclure de l'export d'étiquettes",
'is_home_delivery' => "Livraison à domicile"
];
}


+ 21
- 4
common/logic/Producer/Producer/Model/Producer.php 查看文件

@@ -40,6 +40,7 @@ namespace common\logic\Producer\Producer\Model;

use common\logic\Config\TaxRate\Model\TaxRate;
use common\logic\User\User\Model\User;
use common\logic\User\UserGroup\Model\UserGroup;
use common\logic\User\UserProducer\Model\UserProducer;
use common\components\ActiveRecordCommon;
use yii\web\UploadedFile;
@@ -165,8 +166,9 @@ class Producer extends ActiveRecordCommon
'dolibarr_socid',
'dolibarr_product_id',
'option_weeks_distributions_activated_in_advance',
'option_document_height_logo',
'export_shopping_cart_labels_number_per_column'
'option_document_width_logo',
'export_shopping_cart_labels_number_per_column',
'id_user_group_default'
],
'integer'
],
@@ -276,7 +278,9 @@ class Producer extends ActiveRecordCommon
'option_display_message_new_opendistrib_version',
'option_billing_permanent_transfer',
'option_export_display_column_delivery_note',
'option_invoice_only_based_on_delivery_notes'
'option_invoice_only_based_on_delivery_notes',
'option_document_display_price_unit_reference',
'option_check_by_default_prevent_user_credit'
],
'boolean'
],
@@ -449,8 +453,11 @@ class Producer extends ActiveRecordCommon
'dolibarr_product_id' => 'Dolibarr : id produit',
'option_weeks_distributions_activated_in_advance' => "Semaines de distributions à activer à l'avance",
'option_invoice_only_based_on_delivery_notes' => 'Facturer uniquement sur la base des bons de livraison',
'option_document_height_logo' => 'Hauteur du logo dans les documents',
'option_document_width_logo' => 'Largeur du logo dans les documents',
'export_shopping_cart_labels_number_per_column' => "Étiquettes (PDF) : nombre d'étiquettes par colonne",
'option_document_display_price_unit_reference' => "Afficher les prix au kilogramme",
'id_user_group_default' => "Groupe utilisateur par défaut attribué à l'inscription",
'option_check_by_default_prevent_user_credit' => "Par défaut, prévenir l'utilisateur quand on crédite son compte"
];
}

@@ -484,6 +491,16 @@ class Producer extends ActiveRecordCommon
$this->populateFieldObject('id_tax_rate', 'taxRate', $taxRate);
}

public function getUserGroupDefault()
{
return $this->hasOne(UserGroup::class, ['id' => 'id_user_group_default']);
}

public function populateUserGroupDefault(UserGroup $userGroup)
{
$this->populateFieldObject('id_user_group_default', 'userGroupDefault', $userGroup);
}

// ---

public static function getBillingTypePopulateDropdown()

+ 3
- 8
common/logic/Producer/Producer/Service/ProducerSolver.php 查看文件

@@ -24,23 +24,18 @@ class ProducerSolver extends AbstractService implements SolverInterface
return false;
}

public function getFullAddress(Producer $producer, bool $nl2br = false): string
public function getFullAddressAsHtml(Producer $producer): string
{
$address = '';
$address .= $producer->name . "\n";
$address = '<div class="name">'.$producer->name . '</div>';

if (strlen($producer->address)) {
$address .= $producer->address . "\n";
$address .= $producer->address . '<br>';
}

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

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

return $address;
}


+ 4
- 1
common/logic/User/User/Model/User.php 查看文件

@@ -78,6 +78,7 @@ class User extends ActiveRecordCommon implements IdentityInterface
var $one_name;
var $product_price_percent;
var $newsletter;
var $send_mail_welcome;

/**
* @inheritdoc
@@ -105,7 +106,8 @@ class User extends ActiveRecordCommon implements IdentityInterface
return [
[['no_mail', 'mail_distribution_monday', 'mail_distribution_tuesday', 'mail_distribution_wednesday',
'mail_distribution_thursday', 'mail_distribution_friday', 'mail_distribution_saturday',
'mail_distribution_sunday', 'is_main_contact', 'newsletter', 'exclude_export_shopping_cart_labels'], 'boolean'],
'mail_distribution_sunday', 'is_main_contact', 'newsletter', 'exclude_export_shopping_cart_labels',
'send_mail_welcome'], 'boolean'],
[['lastname', 'name', 'phone', 'address', 'type', 'name_legal_person', 'evoliz_code'], 'string'],
['lastname', 'verifyOneName', 'skipOnError' => false, 'skipOnEmpty' => false],
['email', 'email', 'message' => 'Cette adresse email n\'est pas valide'],
@@ -150,6 +152,7 @@ class User extends ActiveRecordCommon implements IdentityInterface
'evoliz_code' => 'Code client Evoliz',
'newsletter' => "Inscrit au bulletin d'information",
'exclude_export_shopping_cart_labels' => "Exclure de l'export d'étiquettes",
'send_mail_welcome' => "Envoyer un email de bienvenue"
];
}


+ 10
- 1
common/logic/User/User/Model/UserSearch.php 查看文件

@@ -50,13 +50,14 @@ class UserSearch extends User
var $inactive;
var $username;
var $contacts;
var $id_user_user_group;

public function rules()
{
return [
[['no_mail', 'mail_distribution_monday', 'mail_distribution_tuesday', 'mail_distribution_wednesday', 'mail_distribution_thursday', 'mail_distribution_friday', 'mail_distribution_saturday', 'mail_distribution_sunday'], 'boolean'],
[['lastname', 'name', 'phone', 'address', 'type', 'newsletter', 'contacts'], 'string'],
[['id_point_sale', 'inactive', 'subscribers'], 'integer'],
[['id_point_sale', 'inactive', 'subscribers', 'id_user_user_group'], 'integer'],
[['date_last_connection', 'id_point_sale', 'username'], 'safe'],
];
}
@@ -150,6 +151,14 @@ class UserSearch extends User
]);
}

if (isset($this->id_user_user_group) && is_numeric($this->id_user_user_group)) {
$query->innerJoin(
'user_user_group',
'user.id = user_user_group.id_user AND user_user_group.id_user_group = :id_user_group',
['id_user_group' => $this->id_user_user_group]
)->groupBy('user.id');
}

if ($userModule->isTypeValid($this->type)) {
$query->andWhere(['user.type' => $this->type]);
}

+ 14
- 2
common/logic/User/User/Service/UserBuilder.php 查看文件

@@ -10,19 +10,23 @@ use common\logic\Producer\Producer\Model\Producer;
use common\logic\User\User\Event\UserCreateEvent;
use common\logic\User\User\Model\User;
use common\logic\User\User\Repository\UserRepository;
use common\logic\User\UserGroup\Model\UserGroup;
use common\logic\User\UserProducer\Service\UserProducerBuilder;
use common\logic\User\UserUserGroup\Service\UserUserGroupBuilder;

class UserBuilder extends AbstractBuilder
{
protected UserRepository $userRepository;
protected UserNotifier $userNotifier;
protected UserProducerBuilder $userProducerBuilder;
protected UserUserGroupBuilder $userUserGroupBuilder;

public function loadDependencies(): void
{
$this->userRepository = $this->loadService(UserRepository::class);
$this->userNotifier = $this->loadService(UserNotifier::class);
$this->userProducerBuilder = $this->loadService(UserProducerBuilder::class);
$this->userUserGroupBuilder = $this->loadService(UserUserGroupBuilder::class);
}

public function instanciateUser(
@@ -60,7 +64,8 @@ class UserBuilder extends AbstractBuilder
string $phone = null,
string $address = null,
bool $newsletter = true,
string $password = null
string $password = null,
bool $sendMailWelcome = true
): User
{
$userExist = null;
@@ -82,7 +87,9 @@ class UserBuilder extends AbstractBuilder
);
$this->create($user);

$this->userNotifier->sendMailWelcome($user, $password);
if($sendMailWelcome) {
$this->userNotifier->sendMailWelcome($user, $password);
}
}

$user->triggerEvent(
@@ -188,4 +195,9 @@ class UserBuilder extends AbstractBuilder
$user->id_producer = $producer->id;
$this->update($user);
}

public function addUserGroup(User $user, UserGroup $userGroup)
{
$this->userUserGroupBuilder->createUserUserGroup($user, $userGroup);
}
}

+ 4
- 3
common/logic/User/User/Service/UserBulkImporter.php 查看文件

@@ -30,7 +30,7 @@ class UserBulkImporter extends AbstractManager
/**
* @throws ErrorException
*/
public function import(string $fileName): void
public function import(string $fileName, bool $sendMailWelcome = true): void
{
$usersArray = $this->loadCsv($fileName);

@@ -44,7 +44,8 @@ class UserBulkImporter extends AbstractManager
$userData[self::PHONE],
$userData[self::ADDRESS],
$userData[self::NEWSLETTER],
Password::generate()
Password::generate(),
$sendMailWelcome
);
}
}
@@ -53,7 +54,7 @@ class UserBulkImporter extends AbstractManager
{
$usersArray = CSV::csv2array($fileName);

if(count($usersArray) && count($usersArray[0]) != 6) {
if(count($usersArray) && count($usersArray[0]) != 8) {
throw new ErrorException("Le fichier n'a pas le bon nombre de colonnes.
Veuillez vous baser sur le fichier d'exemple téléchargeable ci-dessous.");
}

+ 6
- 3
common/logic/User/UserGroup/Repository/UserGroupRepository.php 查看文件

@@ -44,11 +44,14 @@ class UserGroupRepository extends AbstractRepository
return $this->createDefaultQuery()->find();
}

public function populateUserGroupDropdownList(): array
public function populateUserGroupDropdownList(bool $emptyOption = true): array
{
$userGroupsArrayDropdown = ['' => '--'];
$userGroupsArray = $this->findUserGroups();
$userGroupsArrayDropdown = [];
if($emptyOption) {
$userGroupsArrayDropdown = ['' => '--'];
}

$userGroupsArray = $this->findUserGroups();
foreach ($userGroupsArray as $userGroup) {
$userGroupsArrayDropdown[$userGroup['id']] = $userGroup['name'];
}

+ 1
- 1
common/logic/User/UserGroup/Service/UserGroupBuilder.php 查看文件

@@ -17,7 +17,7 @@ class UserGroupBuilder extends AbstractBuilder
public function createUserGroup(): UserGroup
{
$userGroup = $this->instanciateUserGroup();
$this->saveCreate($userGroup);
$this->create($userGroup);

return $userGroup;
}

+ 22
- 0
common/logic/User/UserUserGroup/Model/UserUserGroup.php 查看文件

@@ -39,6 +39,8 @@ termes.
namespace common\logic\User\UserUserGroup\Model;

use common\logic\PointSale\PointSale\Model\PointSale;
use common\logic\User\User\Model\User;
use common\logic\User\UserGroup\Model\UserGroup;
use Yii;
use common\components\ActiveRecordCommon ;

@@ -87,4 +89,24 @@ class UserUserGroup extends ActiveRecordCommon
{
$this->populateFieldObject('id_point_sale', 'pointSale', $pointSale);
}

public function getUserGroup()
{
return $this->hasOne(UserGroup::class, ['id' => 'id_user_group']);
}

public function populateUserGroup(UserGroup $userGroup): void
{
$this->populateFieldObject('id_user_group', 'userGroup', $userGroup);
}

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

public function populateUser(User $user): void
{
$this->populateFieldObject('id_user', 'user', $user);
}
}

+ 8
- 4
common/logic/User/UserUserGroup/Service/UserUserGroupBuilder.php 查看文件

@@ -3,21 +3,25 @@
namespace common\logic\User\UserUserGroup\Service;

use common\logic\AbstractBuilder;
use common\logic\User\User\Model\User;
use common\logic\User\UserGroup\Model\UserGroup;
use common\logic\User\UserUserGroup\Model\UserUserGroup;

class UserUserGroupBuilder extends AbstractBuilder
{
public function instanciateUserUserGroup(): UserUserGroup
public function instanciateUserUserGroup(User $user, UserGroup $userGroup): UserUserGroup
{
$userUserGroup = new UserUserGroup();
$userUserGroup->populateUser($user);
$userUserGroup->populateUserGroup($userGroup);

return $userUserGroup;
}

public function createUserUserGroup(): UserUserGroup
public function createUserUserGroup(User $user, UserGroup $userGroup): UserUserGroup
{
$userUserGroup = $this->instanciateUserUserGroup();
$this->saveCreate($userUserGroup);
$userUserGroup = $this->instanciateUserUserGroup($user, $userGroup);
$this->create($userUserGroup);

return $userUserGroup;
}

+ 17
- 0
console/commands/ImportFeaturesController.php 查看文件

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

namespace console\commands;

use common\logic\Feature\Feature\Module\FeatureModule;
use yii\console\Controller;

class ImportFeaturesController extends Controller
{
public function actionIndex()
{
$featureModule = FeatureModule::getInstance();
$featureModule->getImporter()->importFromDefinition();
}
}

?>

+ 26
- 0
console/migrations/m231108_092151_rename_column_producer_option_document_height_logo.php 查看文件

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

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

/**
* Class m231108_092151_rename_column_producer_option_document_height_logo
*/
class m231108_092151_rename_column_producer_option_document_height_logo extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->renameColumn('producer', 'option_document_height_logo', 'option_document_width_logo');
}

/**
* {@inheritdoc}
*/
public function safeDown()
{
$this->renameColumn('producer', 'option_document_width_logo', 'option_document_height_logo');
}
}

+ 26
- 0
console/migrations/m231108_131232_add_column_producer_option_document_display_price_unit_reference.php 查看文件

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

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

/**
* Class m231108_131232_add_column_producer_option_document_display_price_unit_reference
*/
class m231108_131232_add_column_producer_option_document_display_price_unit_reference extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn('producer', 'option_document_display_price_unit_reference', Schema::TYPE_BOOLEAN);
}

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

+ 26
- 0
console/migrations/m231109_072158_add_column_point_sale_home_delivery.php 查看文件

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

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

/**
* Class m231109_072158_add_column_point_sale_home_delivery
*/
class m231109_072158_add_column_point_sale_home_delivery extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn('point_sale', 'is_home_delivery', Schema::TYPE_BOOLEAN);
}

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

+ 28
- 0
console/migrations/m231109_090026_add_column_producer_id_user_group_default.php 查看文件

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

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

/**
* Class m231109_090026_add_column_producer_id_user_group_default
*/
class m231109_090026_add_column_producer_id_user_group_default extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn('producer', 'id_user_group_default', Schema::TYPE_INTEGER);
$this->addForeignKey('user_group_default_fk', 'producer', 'id_user_group_default', 'user_group', 'id');
}

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

+ 26
- 0
console/migrations/m231110_073749_add_column_producer_option_check_by_default_prevent_user_credit.php 查看文件

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

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

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

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

+ 46
- 0
console/migrations/m231110_084013_create_tables_feature_flag.php 查看文件

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

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

/**
* Class m231110_084013_create_tables_feature_flag
*/
class m231110_084013_create_tables_feature_flag extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->createTable('feature', [
'id' => 'pk',
'alias' => Schema::TYPE_STRING.' NOT NULL',
'name' => Schema::TYPE_STRING.' NOT NULL',
'description' => Schema::TYPE_TEXT,
'is_paid_feature' => Schema::TYPE_BOOLEAN,
'price' => Schema::TYPE_FLOAT,
'only_for_selected_producers' => Schema::TYPE_BOOLEAN,
'status' => Schema::TYPE_BOOLEAN.' DEFAULT 1',
]);

$this->createTable('feature_producer', [
'id' => 'pk',
'id_producer' => Schema::TYPE_INTEGER.' NOT NULL',
'id_feature' => Schema::TYPE_INTEGER.' NOT NULL',
'status' => Schema::TYPE_BOOLEAN.' DEFAULT 1',
]);

$this->addForeignKey('producer_fk', 'feature_producer', 'id_producer', 'producer', 'id');
$this->addForeignKey('feature_fk', 'feature_producer', 'id_feature', 'feature', 'id');
}

/**
* {@inheritdoc}
*/
public function safeDown()
{
$this->dropTable('feature');
$this->dropTable('feature_producer');
}
}

+ 9
- 1
frontend/forms/SignupForm.php 查看文件

@@ -43,6 +43,7 @@ use common\logic\Producer\Producer\Model\Producer;
use common\logic\Producer\Producer\Module\ProducerModule;
use common\logic\User\User\Model\User;
use common\logic\User\User\Module\UserModule;
use common\logic\User\UserGroup\Module\UserGroupModule;
use yii\base\Model;

/**
@@ -234,7 +235,8 @@ class SignupForm extends Model
*/
public function signup()
{
$userModule = \Yii::$app->logic->getUserModule();
$userGroupModule = UserGroupModule::getInstance();
$userModule = UserModule::getInstance();
$producerModule = \Yii::$app->logic->getProducerModule();

if ($this->validate()) {
@@ -255,6 +257,12 @@ class SignupForm extends Model

\Yii::$app->logic->setProducerContext($producer);

if(!$this->isProducer()) {
if($producer->id_user_group_default) {
$userGroupDefault = $userGroupModule->getRepository()->findOneUserGroupById($producer->id_user_group_default);
$userModule->getBuilder()->addUserGroup($user, $userGroupDefault);
}
}
$producerModule->addUser($user, $producer, true, $this->newsletter);
$userModule->sendEmailSignup($user, $producer);


+ 7
- 0
producer/controllers/OrderController.php 查看文件

@@ -394,6 +394,13 @@ class OrderController extends ProducerBaseController
$order->date_delete = null; // la commande est automatiquement réactivée lors d'une modification
$order->delivery_home = isset($posts['Order']['delivery_home']) ? $posts['Order']['delivery_home'] : false;
$order->delivery_address = (isset($posts['Order']['delivery_address']) && $order->delivery_home) ? $posts['Order']['delivery_address'] : null;

// on sauvegarde l'adresse de livraison dans le profil de l'utilisateur pour qu'il n'ait plus à la ressaisir
if($order->delivery_address && !$user->address) {
$user->address = $order->delivery_address;
$user->save();
}

$order->comment = isset($posts['Order']['comment']) ? $posts['Order']['comment'] : null;
if(!$isNewOrder) {
$order->date_update = date('Y-m-d H:i:s');

+ 6
- 5
producer/controllers/SiteController.php 查看文件

@@ -40,6 +40,7 @@ namespace producer\controllers;

use common\forms\ContactForm;
use common\helpers\GlobalParam;
use common\logic\Feature\Feature\Model\Feature;
use common\logic\Product\Product\Model\Product;
use yii\data\ActiveDataProvider;
use yii\helpers\Html;
@@ -178,14 +179,14 @@ class SiteController extends ProducerBaseController
*/
public function actionContact()
{
$model = new ContactForm();
$producer = $this->getProducerCurrent();

// @TODO : à gérer avec les feature flag
if($producer->id == 1) {
$featureModule = $this->getFeatureModule();
if($featureModule->getManager()->isDisabled(Feature::ALIAS_CONTACT)) {
return $this->redirect(['site/index']);
}

$model = new ContactForm();
$producer = $this->getProducerCurrent();

if ($model->load(\Yii::$app->request->post()) && $model->validate()) {
$isSent = false;
if ($producer->contact_email && strlen($producer->contact_email) > 0 && $model->sendEmail($producer)) {

+ 4
- 2
producer/views/layouts/main.php 查看文件

@@ -36,6 +36,8 @@
* termes.
*/

use common\logic\Feature\Feature\Model\Feature;
use common\logic\Feature\Feature\Module\FeatureModule;
use common\logic\Order\Order\Model\Order;
use common\logic\Producer\Producer\Module\ProducerModule;
use common\logic\User\User\Module\UserModule;
@@ -50,6 +52,7 @@ use yii\helpers\Html;
$userModule = UserModule::getInstance();
$userCurrent = GlobalParam::getCurrentUser();
$producerModule = ProducerModule::getInstance();
$featureModule = FeatureModule::getInstance();
$producerUser = null;
if($userModule->getAuthorizationChecker()->isGrantedAsProducer($userCurrent)) {
$producerUser = $producerModule->findOneProducerById($userCurrent->id_producer);
@@ -178,8 +181,7 @@ if (!Yii::$app->user->isGuest) {
'label' => '<span class="glyphicon glyphicon-envelope"></span> Contact',
'url' => $this->getUrlManagerProducer()->createUrl(['site/contact']),
'active' => $this->getControllerAction() == 'site/contact',
// @TODO : à gérer avec les feature flag
'visible' => $producer->id != 1
'visible' => $featureModule->getManager()->isEnabled(Feature::ALIAS_CONTACT)
],
],
]);

+ 1
- 5
producer/views/order/order.php 查看文件

@@ -439,11 +439,7 @@ $this->setTitle('Commander');
<div id="content-step-payment" v-if="step == 'payment'">
<div>
<div class="delivery">
<div class="delivery-home" v-if="producer.option_delivery">
<input type="checkbox" name="delivery" id="delivery" v-model="delivery"/>
<label for="delivery">Je souhaite être livré à domicile</label>
</div>
<div class="delivery-address" v-if="delivery">
<div class="delivery-home" v-if="pointSaleActive.is_home_delivery">
<label for="deliver-address">Adresse de livraison</label>
<textarea id="deliver-address" v-model="deliveryAddress" class="form-control"
required="required"></textarea>

+ 3
- 6
producer/web/js/vuejs/order-order.js 查看文件

@@ -276,7 +276,6 @@ var app = new Vue({
if(response.data.order) {
app.order = response.data.order ;
app.comment = app.order.comment ;
app.delivery = app.order.delivery_home ;
if(app.order.delivery_address && app.order.delivery_address.length > 0) {
app.deliveryAddress = app.order.delivery_address ;
}
@@ -284,7 +283,6 @@ var app = new Vue({
}
else {
app.comment = null ;
app.delivery = false ;
app.deliveryAddress = null ;
if(app.user.address && app.user.address.length > 0) {
app.deliveryAddress = app.user.address ;
@@ -516,7 +514,7 @@ var app = new Vue({
var app = this ;

// delivery
if(app.delivery && !app.deliveryAddress) {
if(app.pointSaleActive.is_home_delivery && !app.deliveryAddress) {
this.errors = [] ;
this.errors.push('Veuillez saisir une adresse de livraison') ;
return false ;
@@ -550,13 +548,13 @@ var app = new Vue({
}

app.disableConfirmButton = true ;
axios.post('ajax-process', {
Order: {
id_distribution : this.distribution.id,
id_point_sale: this.pointSaleActive.id,
comment: this.comment,
delivery_home: this.delivery,
delivery_home: this.pointSaleActive.is_home_delivery,
delivery_address: this.deliveryAddress
},
code_point_sale: this.pointsSaleCodes[this.pointSaleActive.id],
@@ -566,7 +564,6 @@ var app = new Vue({
}).then(function(response) {
if(response.data.status == 'success') {
app.errors = [] ;

if(response.data.redirect && response.data.redirect.length > 0) {
window.location.href = response.data.redirect ;
}

Loading…
取消
儲存