@@ -76,6 +76,11 @@ class BackendController extends CommonController | |||
{ | |||
return Producer::searchOne(); | |||
} | |||
public function redirectDashboard() | |||
{ | |||
return $this->redirect(['dashboard/index']); | |||
} | |||
} | |||
?> |
@@ -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.'); | |||
} | |||
} | |||
} |
@@ -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(); |
@@ -60,7 +60,7 @@ class SupportAdminController extends SupportController | |||
'matchCallback' => function ($rule, $action) { | |||
return $this->getUserModule() | |||
->getAuthorizationChecker() | |||
->isGrantedAsProducer($this->getUserCurrent()); | |||
->isGrantedAsAdministrator($this->getUserCurrent()); | |||
} | |||
] | |||
], |
@@ -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() |
@@ -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) { |
@@ -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" | |||
]; | |||
} | |||
} |
@@ -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; |
@@ -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> |
@@ -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"> |
@@ -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: ?> |
@@ -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; ?> |
@@ -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> '; | |||
} | |||
?> |
@@ -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> |
@@ -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], |
@@ -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> |
@@ -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> |
@@ -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']) ?> |
@@ -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')): ?> |
@@ -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", |
@@ -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; | |||
} |
@@ -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) | |||
@@ -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() { |
@@ -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; | |||
} | |||
} |
@@ -0,0 +1,9 @@ | |||
.feature-admin-index { | |||
table { | |||
th.only-for-selected-producers, | |||
td.only-for-selected-producers { | |||
width: 100px; | |||
} | |||
} | |||
} |
@@ -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" ; |
@@ -15,6 +15,8 @@ class BusinessLogic | |||
public function getModules() | |||
{ | |||
return [ | |||
$this->getFeatureModule(), | |||
$this->getFeatureProducerModule(), | |||
$this->getUnitModule(), | |||
$this->getTaxRateModule(), | |||
$this->getUserUserGroupModule(), |
@@ -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(); | |||
} | |||
} |
@@ -84,4 +84,9 @@ abstract class AbstractRepository extends AbstractService implements RepositoryI | |||
{ | |||
return $this->createQuery()->find(); | |||
} | |||
public function queryAll() | |||
{ | |||
return $this->createQuery(); | |||
} | |||
} |
@@ -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(); |
@@ -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; |
@@ -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']); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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 | |||
]; | |||
} | |||
} |
@@ -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'] | |||
); | |||
} | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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); | |||
} | |||
@@ -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; | |||
} | |||
} |
@@ -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" | |||
]; | |||
} | |||
@@ -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() |
@@ -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; | |||
} | |||
@@ -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" | |||
]; | |||
} | |||
@@ -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]); | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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."); | |||
} |
@@ -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']; | |||
} |
@@ -17,7 +17,7 @@ class UserGroupBuilder extends AbstractBuilder | |||
public function createUserGroup(): UserGroup | |||
{ | |||
$userGroup = $this->instanciateUserGroup(); | |||
$this->saveCreate($userGroup); | |||
$this->create($userGroup); | |||
return $userGroup; | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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; | |||
} |
@@ -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(); | |||
} | |||
} | |||
?> |
@@ -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'); | |||
} | |||
} |
@@ -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'); | |||
} | |||
} |
@@ -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'); | |||
} | |||
} |
@@ -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'); | |||
} | |||
} |
@@ -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'); | |||
} | |||
} |
@@ -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'); | |||
} | |||
} |
@@ -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); | |||
@@ -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'); |
@@ -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)) { |
@@ -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) | |||
], | |||
], | |||
]); |
@@ -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> |
@@ -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 ; | |||
} |