浏览代码

Merge branch 'dev'

prodstable
Guillaume Bourgeois 2 年前
父节点
当前提交
14fe76f89d
共有 32 个文件被更改,包括 1625 次插入437 次删除
  1. +8
    -1
      backend/controllers/DistributionController.php
  2. +137
    -1
      backend/controllers/DocumentController.php
  3. +3
    -3
      backend/controllers/ProducerAdminController.php
  4. +163
    -0
      backend/controllers/ProducerPriceRangeAdminController.php
  5. +1
    -0
      backend/controllers/QuotationController.php
  6. +4
    -2
      backend/views/document/_download_product_line.php
  7. +3
    -0
      backend/views/document/_form.php
  8. +20
    -4
      backend/views/document/download.php
  9. +10
    -1
      backend/views/invoice/index.php
  10. +1
    -0
      backend/views/layouts/left.php
  11. +63
    -46
      backend/views/producer-admin/index.php
  12. +59
    -0
      backend/views/producer-price-range-admin/create.php
  13. +94
    -0
      backend/views/producer-price-range-admin/index.php
  14. +59
    -0
      backend/views/producer-price-range-admin/update.php
  15. +32
    -2
      backend/views/producer/update.php
  16. +5
    -0
      backend/views/user/_form.php
  17. +1
    -0
      backend/web/.gitignore
  18. +51
    -36
      backend/web/js/vuejs/producer-update.js
  19. +1
    -1
      common/helpers/CSV.php
  20. +21
    -2
      common/helpers/Price.php
  21. +396
    -302
      common/models/Document.php
  22. +74
    -28
      common/models/Order.php
  23. +143
    -6
      common/models/Producer.php
  24. +95
    -0
      common/models/ProducerPriceRange.php
  25. +9
    -0
      common/models/ProductOrder.php
  26. +12
    -0
      common/models/TaxRate.php
  27. +3
    -2
      common/models/User.php
  28. +31
    -0
      console/migrations/m220914_091112_add_table_producer_price_range.php
  29. +27
    -0
      console/migrations/m220915_072309_producer_add_option_billing_frequency.php
  30. +29
    -0
      console/migrations/m220915_083713_producer_add_options_billing.php
  31. +42
    -0
      console/migrations/m220916_062206_add_column_document_tax_calculation_method.php
  32. +28
    -0
      console/migrations/m220919_084020_add_fields_export_evoliz.php

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

@@ -1475,6 +1475,7 @@ class DistributionController extends BackendController

if (!$deliveryNote) {
$deliveryNote = new DeliveryNote();
$deliveryNote->initTaxCalculationMethod();
$deliveryNote->id_producer = GlobalParam::getCurrentProducerId();
$deliveryNote->id_user = $order->id_user;
$deliveryNote->name = 'Bon de livraison ' . $order->getUsername() . ' (' . date(
@@ -1560,6 +1561,7 @@ class DistributionController extends BackendController
// génération du BL
if (!$deliveryNote) {
$deliveryNote = new DeliveryNote;
$deliveryNote->initTaxCalculationMethod();
$deliveryNote->name = 'Bon de livraison ' . $firstOrder->pointSale->name . ' (' . date(
'd/m/Y',
strtotime(
@@ -1573,6 +1575,11 @@ class DistributionController extends BackendController
$user = User::searchOne([
'id' => $deliveryNote->id_user
]);
$userProducer = UserProducer::searchOne([
'id_user' => $deliveryNote->id_user,
'id_producer' => GlobalParam::getCurrentProducerId(
)
]);
} else {
$user = new User;
$user->type = User::TYPE_LEGAL_PERSON;
@@ -1603,7 +1610,7 @@ class DistributionController extends BackendController
$deliveryNote->address = $user->getFullAddress();
$deliveryNote->save();
} else {
// réinitialisation des order.id_delivery_order
// réinitialisation des order.id_delivery_note
Order::updateAll([
'id_delivery_note' => null
], [

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

@@ -39,13 +39,16 @@
namespace backend\controllers;

use common\models\DeliveryNote;
use common\models\Invoice;
use common\models\PointSale;
use common\models\Product;
use common\models\Quotation;
use common\models\User;
use common\models\Document;
use common\helpers\GlobalParam;
use common\models\Order;
use common\models\UserProducer;
use kartik\mpdf\Pdf;
use yii\base\UserException;
use yii;

@@ -74,10 +77,28 @@ class DocumentController extends BackendController
];
}

public function actionGeneratePdfValidatedDocuments()
{
set_time_limit(0);

$validatedDocumentsArray = array_merge(
Quotation::find()->where(['status' => Document::STATUS_VALID])->all(),
DeliveryNote::find()->where(['status' => Document::STATUS_VALID])->all(),
Invoice::find()->where(['status' => Document::STATUS_VALID])->all()
);

foreach($validatedDocumentsArray as $document) {
if(!file_exists($document->getFilenameComplete())) {
$document->generatePdf(Pdf::DEST_FILE);
}
}
}

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

if ($model->load(Yii::$app->request->post())) {
$model->id_producer = GlobalParam::getCurrentProducerId();
@@ -178,10 +199,121 @@ class DocumentController extends BackendController
$this->redirect([$this->getControllerUrl() . '/index']);
}

public function actionExportCsvEvoliz($id)
{
$datas = [];
$document = $this->findModel($id);

// données
$datas[] = [
'N° facture externe *',
'Date facture *',
'Client',
'Code client *',
'Total TVA',
'Total HT',
'Total TTC',
'Total réglé',
'Etat',
'Date Etat',
'Date de création',
'Objet',
'Date d\'échéance',
'Date d\'exécution',
'Taux de pénalité',
'Frais de recouvrement',
'Taux d\'escompte',
'Conditions de règlement *',
'Mode de paiement',
'Remise globale',
'Acompte',
'Nombre de relance',
'Commentaires',
'N° facture',
'Annulé',
'Catalogue',
'Réf.',
'Désignation *',
'Qté *',
'Unité',
'PU HT *',
'Remise',
'TVA',
'Total TVA',
'Total HT',
'Créateur',
];

foreach($document->getProductsOrders() as $productOrderArray) {
foreach($productOrderArray as $productOrder) {

$price = $productOrder->getPrice() ;
if($document->isInvoicePrice() && $productOrder->getInvoicePrice()) {
$price = $productOrder->getInvoicePrice() ;
}

$datas[] = [
$document->reference, // N° facture externe *
date('d/m/Y', strtotime($document->date)), // Date facture *
'', // Client
$document->user->evoliz_code, // Code client *
'', // Total TVA
'', // Total HT
'', // Total TTC
'', // Total réglé
'', // Etat
'', // Date Etat
'', // Date de création
$document->name, // Objet
'', // Date d'échéance
'', // Date d'exécution
'', // Taux de pénalité
'', // Frais de recouvrement
'', // Taux d\'escompte
'A réception', // Conditions de règlement *
'', // Mode de paiement
'', // Remise globale
'', // Acompte
'', // Nombre de relance
'', // Commentaires
'', // N° facture
'', // Annulé
'Non', // Catalogue
'', // Réf.
$productOrder->product->name, // Désignation *
$productOrder->quantity, // Qté *
'', // Product::strUnit($productOrder->unit, 'wording'), // Unité
$price, // PU HT *
'', // Remise
$productOrder->taxRate->value * 100, // TVA
'', // Total TVA
'', // Total HT
'', // Créateur
];
}
}

// nom fichier
$reference = $document->id;
if($document->reference && strlen($document->reference)) {
$reference = $document->reference;
}

// status
$status = '';
if($document->isStatusDraft()) {
$status = 'brouillon_';
}

CSV::downloadSendHeaders(strtolower($this->getDocumentType()).'_' . $status . $reference . '.csv');
echo CSV::array2csv($datas);
die();
}

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

public function actionSend($id)
@@ -273,6 +405,10 @@ class DocumentController extends BackendController
if ($document) {
$document->changeStatus(Document::STATUS_VALID);
$document->save();

// génération PDF
$document->generatePdf(Pdf::DEST_FILE);

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

+ 3
- 3
backend/controllers/ProducerAdminController.php 查看文件

@@ -99,14 +99,14 @@ class ProducerAdminController extends BackendController

$producersArray = Producer::find()->where('active = 1')->all();

$sumFreePrice = 0 ;
$sumPrices = 0;
foreach($producersArray as $producer) {
$sumFreePrice += $producer->free_price ;
$sumPrices += $producer->getAmountBilledLastMonth();
}

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

+ 163
- 0
backend/controllers/ProducerPriceRangeAdminController.php 查看文件

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

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

namespace backend\controllers;

use common\models\ProducerPriceRange;
use Yii;
use common\models\User;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use yii\data\ActiveDataProvider;

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

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

/**
* Liste les tranches de prix.
*
* @return mixed
*/
public function actionIndex()
{
$dataProvider = new ActiveDataProvider([
'query' => ProducerPriceRange::find()->orderBy('range_begin ASC')
]);

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

/**
* Crée une tranche de prix.
*
* @return mixed
*/
public function actionCreate()
{
$model = new ProducerPriceRange();

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

/**
* Édition d'une tranche de prix.
*
* @return mixed
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);

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

/**
* Supprime une tranche de prix.
*
* @param integer $id
*/
public function actionDelete($id)
{
$producerPriceRange = ProducerPriceRange::searchOne([
'id' => $id
]) ;
$producerPriceRange->delete();

Yii::$app->getSession()->setFlash('success', 'Tranche de prix supprimée.');
return $this->redirect(['producer-price-range-admin/index']);
}

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

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

@@ -90,6 +90,7 @@ class QuotationController extends DocumentController
if($quotation->isStatusValid()) {

$invoice = new Invoice ;
$invoice->initTaxCalculationMethod();
$invoice->id_producer = GlobalParam::getCurrentProducerId();
$invoice->id_user = $quotation->id_user ;
$invoice->address = $quotation->address ;

+ 4
- 2
backend/views/document/_download_product_line.php 查看文件

@@ -1,10 +1,12 @@
<tr class="<?php if(isset($displayOrders) && $displayOrders): ?>order<?php endif; ?>">
<td class="align-left">
<?= Html::encode($productOrder->product->name) ?>
<?php if($productOrder->product): ?>
<?= Html::encode($productOrder->product->name) ?>
<?php endif; ?>
<?php if($productOrder->unit == 'piece' && isset($productOrder->product->weight) && $productOrder->product->weight): ?>
<span class="weight"> / <?= $productOrder->product->weight ?> g</span>
<?php endif; ?>
<?php if(strlen($productOrder->product->description) && $displayProductDescription): ?>
<?php if($productOrder->product && strlen($productOrder->product->description) && $displayProductDescription): ?>
<br /><small><?= Html::encode($productOrder->product->description) ?></small>
<?php endif; ?>
</td>

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

@@ -155,6 +155,9 @@ use common\models\Producer;
<span class="info-box-icon bg-blue"><i class="fa fa-download"></i></span>
<div class="info-box-content">
<a href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl().'/download', 'id' => $model->id]) ?>" class="btn btn-default"><span class="glyphicon glyphicon-download-alt"></span> Télécharger (PDF)</a>
<?php if($model->getClass() == 'Invoice' && Producer::getConfig('option_export_evoliz')): ?>
<a href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl().'/export-csv-evoliz', 'id' => $model->id]) ?>" class="btn btn-default"><span class="glyphicon glyphicon-save-file"></span> Export Evoliz (CSV)</a>
<?php endif; ?>
</div>
</div>
<div v-if="document.status == 'draft'" id="" class="info-box">

+ 20
- 4
backend/views/document/download.php 查看文件

@@ -81,7 +81,9 @@ $displayProductDescription = Producer::getConfig('document_display_product_descr
<tr>
<td>
<strong><?= Html::encode($order->getUsername()) ; ?></strong>
le <?= date('d/m/Y', strtotime($order->distribution->date)) ?>
<?php if($order->distribution): ?>
le <?= date('d/m/Y', strtotime($order->distribution->date)) ?>
<?php endif; ?>
</td>
<?php if($displayPrices): ?>
<td class="align-center"></td>
@@ -128,10 +130,24 @@ $displayProductDescription = Producer::getConfig('document_display_product_descr
<?= Price::format($document->getAmount($typeAmount)); ?>
</td>
</tr>
<tr>

<?php
$taxRateArray = TaxRate::getTaxRateArray();
foreach($document->getTotalVatArray($typeAmount) as $idTaxRate => $totalVat): ?>
<tr>
<td class="align-right" colspan="5"><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($document->getAmountWithTax($typeAmount) - $document->getAmount($typeAmount)) ?></td>
</tr>
<td class="align-center">
<?= Price::format($document->getAmountWithTax($typeAmount) - $document->getAmount($typeAmount)) ?>
</td>
</tr>-->
<tr>
<td class="align-right" colspan="5"><strong>Total TTC</strong></td>
<td class="align-center"><?= Price::format($document->getAmountWithTax($typeAmount)) ?></td>

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

@@ -101,7 +101,7 @@ $this->addButton(['label' => 'Nouvelle facture <span class="glyphicon glyphicon-
],
[
'class' => 'yii\grid\ActionColumn',
'template' => '{validate} {update} {delete} {send} {download}',
'template' => '{validate} {update} {delete} {send} {download} {export-csv-evoliz}',
'headerOptions' => ['class' => 'column-actions'],
'contentOptions' => ['class' => 'column-actions'],
'buttons' => [
@@ -120,6 +120,15 @@ $this->addButton(['label' => 'Nouvelle facture <span class="glyphicon glyphicon-
'title' => 'Télécharger', 'class' => 'btn btn-default'
]);
},
'export-csv-evoliz' => function($url, $model) {
if(Producer::getConfig('option_export_evoliz')) {
return Html::a('<span class="glyphicon glyphicon-save-file"></span> Evoliz', $url, [
'title' => 'Export CSV Evoliz', 'class' => 'btn btn-default'
]);
}

return '';
},
'update' => function ($url, $model) {
return Html::a('<span class="glyphicon glyphicon-pencil"></span>', $url, [
'title' => 'Modifier', 'class' => 'btn btn-default'

+ 1
- 0
backend/views/layouts/left.php 查看文件

@@ -98,6 +98,7 @@ termes.
['label' => 'Administration', 'options' => ['class' => 'header'], 'visible' => User::isCurrentAdmin()],
['label' => 'Producteurs','icon' => 'th-list','url' => ['/producer-admin/index'], 'visible' => User::isCurrentAdmin()],
['label' => 'Tranches de prix','icon' => 'eur','url' => ['/producer-price-range-admin/index'], 'visible' => User::isCurrentAdmin()],
['label' => 'Taxes','icon' => 'eur','url' => ['/tax-rate-admin/index'], 'visible' => User::isCurrentAdmin()],
['label' => 'Communiquer','icon' => 'bullhorn','url' => ['/communicate-admin/index'], 'visible' => User::isCurrentAdmin()],

+ 63
- 46
backend/views/producer-admin/index.php 查看文件

@@ -49,28 +49,48 @@ $this->addButton(['label' => 'Nouveau producteur <span class="glyphicon glyphico
?>

<div class="alert alert-info">
Abonnements mensuels : <strong><?= $sumFreePrice ?> € HT</strong>
Facturé le mois dernier : <strong><?= $sumPrices ?> €</strong><br />
</div>

<?= GridView::widget([
'dataProvider' => $dataProviderProducer,
'columns' => [
'name',
[
'attribute' => 'active',
'format' => 'raw',
'value' => function($model) {
$html = '' ;
if($model->active) {
$html .= '<span class="label label-success">En ligne</span>' ;
}
else {
$html .= '<span class="label label-danger">Hors-ligne</span>' ;
}

if(strlen($model->code))
{
$html .= ' <span class="glyphicon glyphicon-lock" data-toggle="tooltip" data-placement="bottom" data-original-title="'.Html::encode($model->code).'"></span>' ;
}

return $html ;
}
],
'name',
/*[
'attribute' => 'date_creation',
'format' => 'raw',
'value' => function($model) {
return date('d/m/Y', strtotime($model->date_creation)) ;
}
],
[
],*/
/*[
'attribute' => 'Lieu',
'format' => 'raw',
'value' => function($model) {
return Html::encode($model->city.' ('.$model->postcode.')') ;
}
],
[
],*/
/*[
'attribute' => 'Utilisateurs',
'format' => 'raw',
'value' => function($model) {
@@ -87,7 +107,7 @@ $this->addButton(['label' => 'Nouveau producteur <span class="glyphicon glyphico
}
}
],
],*/
[
'attribute' => 'Contact',
'format' => 'raw',
@@ -111,63 +131,60 @@ $this->addButton(['label' => 'Nouveau producteur <span class="glyphicon glyphico
}
],
[
'attribute' => 'active',
'attribute' => 'Prix libre',
'label' => 'Prix libre',
'format' => 'raw',
'value' => function($model) {
$html = '' ;
if($model->active) {
$html .= '<span class="label label-success">En ligne</span>' ;
if(is_null($model->free_price)) {
return '' ;
}
else {
$html .= '<span class="label label-danger">Hors-ligne</span>' ;
}
if(strlen($model->code))
{
$html .= ' <span class="glyphicon glyphicon-lock" data-toggle="tooltip" data-placement="bottom" data-original-title="'.Html::encode($model->code).'"></span>' ;
$str = '';
if($model->isBillingTypeFreePrice()) {
$str .= '<strong>';
}

$str .= $model->getFreePrice();

if($model->isBillingTypeFreePrice()) {
$str .= '</strong>';
}

return $str;
}
return $html ;
}
],
[
'attribute' => 'Prix libre',
'label' => 'Prix libre',
'attribute' => 'À facturer / chiffre d\'affaire',
'label' => 'À facturer / chiffre d\'affaire',
'format' => 'raw',
'value' => function($model) {
if(is_null($model->free_price)) {
return '' ;
if($model->isBillingFrequencyMonthly()) {
return $model->getSummaryAmountsToBeBilled('Mois dernier', 1);
}
else {
return $model->getFreePrice() ;
elseif($model->isBillingFrequencyQuarterly()) {
return $model->getSummaryAmountsToBeBilled('3 derniers mois', 3);
}
elseif($model->isBillingFrequencyBiannual()) {
return $model->getSummaryAmountsToBeBilled('6 derniers mois', 6);
}
}
],
[
'label' => 'Dons (mois précédent)',
'attribute' => 'Facturation',
'label' => 'Détails facturation',
'format' => 'raw',
'value' => function($model) {
$productGift = Product::getProductGift() ;

$res = Yii::$app->db->createCommand("SELECT SUM(product_order.price * product_order.quantity) AS total
FROM `order`, product_order, distribution
WHERE distribution.id_producer = :id_producer
AND `order`.id_distribution = distribution.id
AND `order`.id = product_order.id_order
AND distribution.date >= :date_start
AND distribution.date <= :date_end
AND product_order.id_product = :id_product_gift
")
->bindValue(':id_producer', $model->id)
->bindValue(':date_start', date('Y-m-01', strtotime("-1 month")))
->bindValue(':date_end', date('Y-m-31', strtotime("-1 month")))
->bindValue(':id_product_gift', $productGift->id)
->queryOne();

return Price::format($res['total']) ;
$str = '';
$str .= '- '.Producer::$billingTypeArray[$model->option_billing_type].'<br />';
$str .= '- '.Producer::$billingFrequencyArray[$model->option_billing_frequency];

if($model->option_billing_reduction) {
$str .= '<br />- <u>Avec réduction</u>';
}

return $str;
}
],
]
],
]); ?>

+ 59
- 0
backend/views/producer-price-range-admin/create.php 查看文件

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

/**
Copyright distrib (2018)

contact@opendistrib.net

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

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

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

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

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

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

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

?>

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

+ 94
- 0
backend/views/producer-price-range-admin/index.php 查看文件

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

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

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

$this->setTitle('Tranches de prix');
$this->addBreadcrumb($this->getTitle());
$this->addButton(['label' => 'Nouvelle tranche de prix <span class="glyphicon glyphicon-plus"></span>', 'url' => 'producer-price-range-admin/create', 'class' => 'btn btn-primary']);

?>

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

+ 59
- 0
backend/views/producer-price-range-admin/update.php 查看文件

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

/**
Copyright distrib (2018)

contact@opendistrib.net

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

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

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

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

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

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

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

?>

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

+ 32
- 2
backend/views/producer/update.php 查看文件

@@ -48,10 +48,16 @@ $this->addBreadcrumb($this->getTitle()) ;

?>

<script>
var appInitValues = {
isAdmin: <?= (int) User::isCurrentAdmin() ?>
};
</script>

<div class="user-update" id="app-producer-update">
<div id="nav-params">
<button v-for="section in sectionsArray" :class="'btn '+((currentSection == section.name) ? 'btn-primary' : 'btn-default')" @click="changeSection(section)">
<button v-for="section in sectionsArray" v-if="!section.isAdminSection || (section.isAdminSection && isAdmin)" :class="'btn '+((currentSection == section.name) ? 'btn-primary' : 'btn-default')" @click="changeSection(section)">
{{ section.nameDisplay }}
<span class="glyphicon glyphicon-triangle-bottom"></span>
</button>
@@ -426,6 +432,12 @@ $this->addBreadcrumb($this->getTitle()) ;
<?= $form->field($model, 'id_tax_rate_default')
->dropDownList(ArrayHelper::map(TaxRate::find()->all(), 'id', function($model) { return $model->name; }))
->label('TVA à appliquer par défaut'); ?>
<?= $form->field($model, 'option_tax_calculation_method')
->dropDownList(Document::$taxCalculationMethodArray); ?>
<?= $form->field($model, 'option_export_evoliz')->dropDownList([
0 => 'Non',
1 => 'Oui'
]) ; ?>
<?= $form->field($model, 'document_quotation_prefix') ; ?>
<?= $form->field($model, 'document_quotation_first_reference') ; ?>
<?= $form->field($model, 'document_quotation_duration') ; ?>
@@ -459,7 +471,25 @@ $this->addBreadcrumb($this->getTitle()) ;
->textarea(['rows' => 15]) ?>
</div>
</div>

<?php if(User::isCurrentAdmin()): ?>
<div v-show="currentSection == 'administration'" class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Administration</h3>
</div>
<div class="panel-body">
<?= $form->field($model, 'option_billing_type')
->dropDownList(Producer::getBillingTypePopulateDropdown()); ?>
<?= $form->field($model, 'option_billing_frequency')
->dropDownList(Producer::getBillingFrequencyPopulateDropdown()); ?>
<?= $form->field($model, 'option_billing_reduction')
->dropDownList([
0 => 'Non',
1 => 'Oui'
]); ?>
</div>
</div>
<?php endif; ?>
<div class="form-group">
<?= Html::submitButton('Mettre à jour', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>

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

@@ -61,6 +61,11 @@ use common\models\ProductPrice ;
<?= $form->field($model, 'phone')->textInput() ?>
<?= $form->field($model, 'email')->textInput() ?>
<?= $form->field($model, 'address')->textarea() ?>

<?php if(Producer::getConfig('option_export_evoliz')): ?>
<?= $form->field($model, 'evoliz_code')->textInput() ?>
<?php endif; ?>

<?= $form->field($model, 'points_sale')->checkboxlist(
ArrayHelper::map($pointsSaleArray, 'id', function ($pointSale) use ($model) {
$commentUserPointSale = isset($pointSale->userPointSale[0]) ? $pointSale->userPointSale[0]->comment : '';

+ 1
- 0
backend/web/.gitignore 查看文件

@@ -1,2 +1,3 @@
/index.php
/index-test.php
/pdf/*

+ 51
- 36
backend/web/js/vuejs/producer-update.js 查看文件

@@ -37,42 +37,57 @@ termes.

var app = new Vue({
el: '#app-producer-update',
data: {
currentSection: 'general',
sectionsArray: [
{
name: 'general',
nameDisplay: 'Général'
},
{
name: 'tableau-bord',
nameDisplay: 'Tableau de bord'
},
{
name: 'prise-commande',
nameDisplay: 'Prise de commande'
},
{
name: 'abonnements',
nameDisplay: 'Abonnements'
},
{
name: 'credit-payment',
nameDisplay: 'Crédit'
},
{
name: 'infos',
nameDisplay: 'Informations légales'
},
{
name: 'logiciels-caisse',
nameDisplay: 'Logiciels de caisse'
},
{
name: 'facturation',
nameDisplay: 'Facturation'
}
]
data() {
return Object.assign({
currentSection: 'general',
sectionsArray: [
{
name: 'general',
nameDisplay: 'Général',
isAdminSection: 0
},
{
name: 'tableau-bord',
nameDisplay: 'Tableau de bord',
isAdminSection: 0
},
{
name: 'prise-commande',
nameDisplay: 'Prise de commande',
isAdminSection: 0
},
{
name: 'abonnements',
nameDisplay: 'Abonnements',
isAdminSection: 0
},
{
name: 'credit-payment',
nameDisplay: 'Crédit',
isAdminSection: 0
},
{
name: 'infos',
nameDisplay: 'Informations légales',
isAdminSection: 0
},
{
name: 'logiciels-caisse',
nameDisplay: 'Logiciels de caisse',
isAdminSection: 0
},
{
name: 'facturation',
nameDisplay: 'Facturation',
isAdminSection: 0
},
{
name: 'administration',
nameDisplay: 'Administration',
isAdminSection: 1
}
]
}, window.appInitValues);
},
methods: {
changeSection: function(section) {

+ 1
- 1
common/helpers/CSV.php 查看文件

@@ -52,7 +52,7 @@ class CSV
// clés
//fputcsv($df, array_keys(reset($array)));
foreach ($array as $row) {
fputcsv($df, $row);
fputcsv($df, $row, ";");
}
fclose($df);
return ob_get_clean();

+ 21
- 2
common/helpers/Price.php 查看文件

@@ -46,14 +46,33 @@ class Price
return self::numberTwoDecimals($number).' €';
}

public static function round($number)
{
return round($number, 2, PHP_ROUND_HALF_UP);
}

public static function getPrice($priceWithTax, $taxRate)
{
return floatval($priceWithTax) / ($taxRate + 1);
}

public static function getPriceWithTax($priceWithoutTax, $taxRate)
public static function getPriceWithTax($priceWithoutTax, $taxRate, $taxCalculationMethod = Document::TAX_CALCULATION_METHOD_DEFAULT)
{
return self::numberTwoDecimals(floatval($priceWithoutTax) * ($taxRate + 1)) ;
$priceWithoutTax = self::round($priceWithoutTax);
$vat = self::getVat($priceWithoutTax, $taxRate, $taxCalculationMethod);

return $priceWithoutTax + $vat;
}

public static function getVat($priceTotalWithoutTax, $taxRate, $taxCalculationMethod = Document::TAX_CALCULATION_METHOD_DEFAULT)
{
$vat = $priceTotalWithoutTax * $taxRate;

if($taxCalculationMethod == Document::TAX_CALCULATION_METHOD_SUM_OF_ROUNDINGS) {
$vat = self::round($vat);
}

return $vat;
}

public static function numberTwoDecimals($number)

+ 396
- 302
common/models/Document.php 查看文件

@@ -39,357 +39,451 @@
namespace common\models;

use common\helpers\GlobalParam;
use kartik\mpdf\Pdf;
use Symfony\Component\Finder\Exception\DirectoryNotFoundException;
use yii\base\ErrorException;

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

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

const TAX_CALCULATION_METHOD_SUM_OF_ROUNDINGS = 'sum-roundings';
const TAX_CALCULATION_METHOD_ROUNDING_OF_THE_SUM = 'rounding-sum';
const TAX_CALCULATION_METHOD_DEFAULT = self::TAX_CALCULATION_METHOD_ROUNDING_OF_THE_SUM;

public static $taxCalculationMethodArray = [
self::TAX_CALCULATION_METHOD_ROUNDING_OF_THE_SUM => 'Arrondi de la somme des lignes',
self::TAX_CALCULATION_METHOD_SUM_OF_ROUNDINGS => 'Somme des arrondis de chaque ligne'
];

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

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

/*
* Relations
*/

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

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

public function relationOrders($fieldIdDocument)
{
$defaultOptionsSearch = Order::defaultOptionsSearch();

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

/*
* Méthodes
*/

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

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

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

foreach ($ordersArray as $order) {
$order->init($this->tax_calculation_method);
$amount += $order->getAmount($type);
$totalVat += $order->getTotalVat($type);
}

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

/*
* Relations
*/

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

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

public function relationOrders($fieldIdDocument)
{
$defaultOptionsSearch = Order::defaultOptionsSearch();

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


/*
* Méthodes
*/

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

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

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

foreach ($ordersArray as $order) {
$order->init();
public function getTotalVatArray($typeTotal)
{
$totalVatArray = [];

if ($withTax) {
$amount += $order->getAmountWithTax($type);
}
else {
$amount += $order->getAmount($type);
}
}
$ordersArray = $this->orders;

if ($format) {
return Price::format($amount);
} else {
return $amount;
foreach ($ordersArray as $order) {
$order->init($this->tax_calculation_method);
$fieldNameVat = $order->getFieldNameAmount($typeTotal, 'vat');
foreach ($order->$fieldNameVat as $idTaxRate => $vat) {
if (!isset($totalVatArray[$idTaxRate])) {
$totalVatArray[$idTaxRate] = 0;
}
$totalVatArray[$idTaxRate] += $vat;
}
}

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

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

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

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

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

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

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

return '';
}

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

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

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

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

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

$prefix = Producer::getConfig('document_' . $classLower . '_prefix');
$oneDocumentExist = $class::searchOne(['status' => Document::STATUS_VALID] , ['orderby' => 'reference DESC']);
public function isValidClass($typeDocument)
{
return in_array($typeDocument, ['Invoice', 'DeliveryNote', 'Quotation']);
}

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

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

if (strlen($firstReference) > 0) {
return $firstReference;
} else {
return $prefix . '00001';
}
}
public function generateReference()
{
$class = $this->getClass();
$classLower = strtolower($class);
if ($classLower == 'deliverynote') {
$classLower = 'delivery_note';
}

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

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

$marginBottom = 10 ;
if(strlen(Producer::getConfig('document_infos_bottom')) > 0) {
$marginBottom = 40 ;
}

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

return $pdf->render();
$prefix = Producer::getConfig('document_' . $classLower . '_prefix');
$oneDocumentExist = $class::searchOne(['status' => Document::STATUS_VALID], ['orderby' => 'reference DESC']);

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

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

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

public function send()
{
if(isset($this->user) && strlen($this->user->email) > 0) {
$producer = GlobalParam::getCurrentProducer();

$subjectEmail = $this->getType() ;
if($this->isStatusValid()) {
$subjectEmail .= ' N°'.$this->reference ;
}
public function downloadPdf()
{
$filenameComplete = $this->getFilenameComplete();

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

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

return $email->send() ;
}

return false ;
if (!file_exists($filenameComplete)) {
$this->generatePdf(Pdf::DEST_FILE);
}

public function changeStatus($status)
{
if ($status == Document::STATUS_VALID) {
$this->status = $status;
$this->reference = $this->generateReference();
}
if (file_exists($filenameComplete)) {
return Yii::$app->response->sendFile($filenameComplete, $this->getFilename(), ['inline' => true]);
} else {
throw new ErrorException('File ' . $filenameComplete . ' not found');
}

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

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

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

public function getStatusCssClass()
{
return ($this->status == self::STATUS_DRAFT) ? 'default' : 'success';
$marginBottom = 10;
if (strlen(Producer::getConfig('document_infos_bottom')) > 0) {
$marginBottom = 40;
}

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

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

return $pdf->render();
}

public function send()
{
if (isset($this->user) && strlen($this->user->email) > 0) {
$producer = GlobalParam::getCurrentProducer();

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

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

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

return $email->send();
}

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

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

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

public function getProductsOrders()
{
$productsOrdersArray = [];
$ordersArray = $this->orders ;
if ($ordersArray && count($ordersArray)) {
foreach ($ordersArray as $order) {
foreach ($order->productOrder as $productOrder) {
$indexProductOrder = $productOrder->product->order ;
$newProductOrder = clone $productOrder ;

if (!isset($productsOrdersArray[$indexProductOrder])) {
$productsOrdersArray[$indexProductOrder] = [$newProductOrder];
} else {
$productOrderMatch = false;
foreach ($productsOrdersArray[$indexProductOrder] as &$theProductOrder) {
if ($theProductOrder->unit == $productOrder->unit
&& ( (!$this->isInvoicePrice() && $theProductOrder->price == $productOrder->price)
|| ($this->isInvoicePrice() && $theProductOrder->invoice_price == $productOrder->invoice_price)
)) {

$theProductOrder->quantity += $productOrder->quantity;
$productOrderMatch = true;
}
}
if (!$productOrderMatch) {
$productsOrdersArray[$indexProductOrder][] = $newProductOrder;
}
}
}

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

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

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

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

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

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

public function getProductsOrders()
{
$productsOrdersArray = [];
$ordersArray = $this->orders;
if ($ordersArray && count($ordersArray)) {
foreach ($ordersArray as $order) {
foreach ($order->productOrder as $productOrder) {
if ($productOrder->product) {
$indexProductOrder = $productOrder->product->order;
$newProductOrder = clone $productOrder;

if (!isset($productsOrdersArray[$indexProductOrder])) {
$productsOrdersArray[$indexProductOrder] = [$newProductOrder];
} else {
$productOrderMatch = false;
foreach ($productsOrdersArray[$indexProductOrder] as &$theProductOrder) {
if ($theProductOrder->unit == $productOrder->unit
&& ((!$this->isInvoicePrice() && $theProductOrder->price == $productOrder->price)
|| ($this->isInvoicePrice() && $theProductOrder->invoice_price == $productOrder->invoice_price)
)) {

$theProductOrder->quantity += $productOrder->quantity;
$productOrderMatch = true;
}
}
if (!$productOrderMatch) {
$productsOrdersArray[$indexProductOrder][] = $newProductOrder;
}
}
}
}
}
}

// tri des orderProduct par product.order
ksort($productsOrdersArray);
// tri des orderProduct par product.order
ksort($productsOrdersArray);

return $productsOrdersArray;
}
return $productsOrdersArray;
}

public function isDisplayOrders()
{
$displayOrders = ($this->getClass() == 'Invoice') ?
Producer::getConfig('document_display_orders_invoice') :
Producer::getConfig('document_display_orders_delivery_note') ;
public function isDisplayOrders()
{
$displayOrders = ($this->getClass() == 'Invoice') ?
Producer::getConfig('document_display_orders_invoice') :
Producer::getConfig('document_display_orders_delivery_note');

return $displayOrders ;
}
return $displayOrders;
}

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

public function isInvoicePrice()
{
return $this->getClass() == 'Invoice' || $this->getClass() == 'DeliveryNote' ;
public function initDirectoryPdf()
{
$aliasDirectoryBase = $this->getAliasDirectoryBase();
$directoryPdf = Yii::getAlias($aliasDirectoryBase);
if (!file_exists($directoryPdf)) {
mkdir($directoryPdf, 0755);
}

}

public function getFilename()
{
return $this->getType() . '-' . $this->reference . '.pdf';
}

public function getFilenameComplete()
{
return Yii::getAlias($this->getAliasDirectoryBase() . $this->getFilename());
}

public function isInvoicePrice()
{
return $this->getClass() == 'Invoice' || $this->getClass() == 'DeliveryNote';
}

public function isTaxCalculationMethodSumOfRoundings()
{
return $this->tax_calculation_method == self::TAX_CALCULATION_METHOD_SUM_OF_ROUNDINGS;
}

public function isTaxCalculationMethodRoundingOfTheSum()
{
return $this->tax_calculation_method == self::TAX_CALCULATION_METHOD_ROUNDING_OF_THE_SUM;
}

public function initTaxCalculationMethod()
{
$producerTaxCalculationMethod = Producer::getConfig('option_tax_calculation_method');

if ($producerTaxCalculationMethod) {
$this->tax_calculation_method = $producerTaxCalculationMethod;
} else {
$this->tax_calculation_method = self::TAX_CALCULATION_METHOD_DEFAULT;
}
}
}

+ 74
- 28
common/models/Order.php 查看文件

@@ -63,8 +63,10 @@ class Order extends ActiveRecordCommon
{
var $amount = 0;
var $amount_with_tax = 0;
var $amount_vat = [];
var $invoice_amount = 0;
var $invoice_amount_with_tax = 0;
var $invoice_amount_vat = [];
var $paid_amount = 0;
var $weight = 0;

@@ -223,9 +225,9 @@ class Order extends ActiveRecordCommon
* Initialise le montant total, le montant déjà payé et le poids de la
* commande.
*/
public function init()
public function init($taxCalculationMethod = Document::TAX_CALCULATION_METHOD_DEFAULT)
{
$this->initAmount();
$this->initAmount($taxCalculationMethod);
$this->initPaidAmount();

return $this;
@@ -235,46 +237,90 @@ class Order extends ActiveRecordCommon
* Initialise le montant de la commande.
*
*/
public function initAmount()
public function initAmount($taxCalculationMethod = Document::TAX_CALCULATION_METHOD_DEFAULT)
{
$this->amount = 0;
$this->amount_with_tax = 0;
$this->amount_vat = [];
$this->invoice_amount = 0;
$this->invoice_amount_with_tax = 0;
$this->invoice_amount_vat = [];
$this->weight = 0;

if (isset($this->productOrder)) {
foreach ($this->productOrder as $productOrder) {
$this->amount += $productOrder->price * $productOrder->quantity;
$this->amount_with_tax += Price::getPriceWithTax(
$productOrder->price,
$productOrder->taxRate->value
) * $productOrder->quantity;

if($productOrder->invoice_price) {
$invoicePrice = $productOrder->invoice_price;
}
else {
$invoicePrice = $productOrder->price;
}

$this->invoice_amount += $invoicePrice * $productOrder->quantity;
$this->invoice_amount_with_tax += Price::getPriceWithTax(
$invoicePrice,
$productOrder->taxRate->value
) * $productOrder->quantity;
$this->addAmount(self::AMOUNT_TOTAL, $productOrder, $taxCalculationMethod);
$this->addAmount(self::INVOICE_AMOUNT_TOTAL, $productOrder, $taxCalculationMethod);
$this->addWeight($productOrder);
}
}
}

if ($productOrder->unit == 'piece') {
if (isset($productOrder->product)) {
$this->weight += ($productOrder->quantity * $productOrder->product->weight) / 1000;
}
} else {
$this->weight += $productOrder->quantity;
}
public function addWeight($productOrder)
{
if ($productOrder->unit == 'piece') {
if (isset($productOrder->product)) {
$this->weight += ($productOrder->quantity * $productOrder->product->weight) / 1000;
}
} else {
$this->weight += $productOrder->quantity;
}
}

public function addAmount($typeTotal, $productOrder, $taxCalculationMethod)
{
$fieldNameAmount = $this->getFieldNameAmount($typeTotal);
$fieldNameAmountWithTax = $this->getFieldNameAmount($typeTotal, 'with_tax');
$price = $productOrder->getPriceByTypeTotal($typeTotal);
$this->$fieldNameAmount += $price * $productOrder->quantity;
$this->$fieldNameAmountWithTax += Price::getPriceWithTax(
$price,
$productOrder->taxRate->value,
$taxCalculationMethod
) * $productOrder->quantity;
$this->addVat($typeTotal, $price * $productOrder->quantity, $productOrder->taxRate, $taxCalculationMethod);
}

public function addVat($typeTotal, $priceTotalWithoutTax, $taxRate, $taxCalculationMethod)
{
$fieldName = $this->getFieldNameAmount($typeTotal, 'vat');

if(!isset($this->$fieldName[$taxRate->id])) {
$this->$fieldName[$taxRate->id] = 0;
}

$this->$fieldName[$taxRate->id] += Price::getVat($priceTotalWithoutTax, $taxRate->value, $taxCalculationMethod);
}

public function getTotalVat($typeTotal = self::AMOUNT_TOTAL)
{
$fieldName = $this->getFieldNameAmount($typeTotal, 'vat');
$totalVat = 0;

foreach($this->$fieldName as $vat) {
$totalVat += $vat;
}

return $totalVat;
}

public function getFieldNameAmount($typeTotal = self::AMOUNT_TOTAL, $typeField = '')
{
$fieldName = 'amount';
if($typeTotal == self::INVOICE_AMOUNT_TOTAL) {
$fieldName = 'invoice_amount';
}

if($typeField == 'vat') {
$fieldName = $fieldName.'_vat';
}
elseif($typeField == 'with_tax') {
$fieldName = $fieldName.'_with_tax';
}

return $fieldName;
}

/**
* Initialise le montant payé de la commande et le retourne.
*

+ 143
- 6
common/models/Producer.php 查看文件

@@ -98,6 +98,24 @@ class Producer extends ActiveRecordCommon
const ORDER_ENTRY_POINT_DATE = 'date';
const ORDER_ENTRY_POINT_POINT_SALE = 'point-sale';

const BILLING_FREQUENCY_MONTHLY = 'monthly';
const BILLING_FREQUENCY_QUARTERLY = 'quarterly';
const BILLING_FREQUENCY_BIANNUAL = 'biannual';

public static $billingFrequencyArray = [
self::BILLING_FREQUENCY_MONTHLY => 'Mensuelle',
self::BILLING_FREQUENCY_QUARTERLY => 'Trimestrielle',
self::BILLING_FREQUENCY_BIANNUAL => 'Biannuelle',
];

const BILLING_TYPE_CLASSIC = 'classic';
const BILLING_TYPE_FREE_PRICE = 'free-price';

public static $billingTypeArray = [
self::BILLING_TYPE_CLASSIC => 'Classique',
self::BILLING_TYPE_FREE_PRICE => 'Prix libre',
];

var $secret_key_payplug;

/**
@@ -205,7 +223,8 @@ class Producer extends ActiveRecordCommon
'option_stripe_public_key',
'option_stripe_private_key',
'option_stripe_endpoint_secret',
'option_online_payment_type'
'option_online_payment_type',
'option_tax_calculation_method'
],
'string'
],
@@ -232,7 +251,9 @@ class Producer extends ActiveRecordCommon
'option_delivery',
'option_display_export_grid',
'option_stripe_mode_test',
'option_notify_producer_order_summary'
'option_notify_producer_order_summary',
'option_billing_reduction',
'option_export_evoliz'
],
'boolean'
],
@@ -253,7 +274,9 @@ class Producer extends ActiveRecordCommon
'document_invoice_prefix',
'document_invoice_first_reference',
'document_delivery_note_prefix',
'document_delivery_note_first_reference'
'document_delivery_note_first_reference',
'option_billing_type',
'option_billing_frequency',
],
'string',
'max' => 255
@@ -267,7 +290,6 @@ class Producer extends ActiveRecordCommon
'type' => 'number',
'message' => 'Prix libre doit être supérieur ou égal à 0'
],
//[['option_dashboard_date_start', 'option_dashboard_date_end'], 'date', 'format' => 'php:d/m/Y'],
[['option_dashboard_date_start', 'option_dashboard_date_end'], 'safe'],
];
}
@@ -363,7 +385,12 @@ class Producer extends ActiveRecordCommon
'option_delivery' => 'Proposer la livraison à domicile',
'option_display_export_grid' => 'Afficher l\'export grille dans les distributions',
'document_display_product_description' => 'Documents : afficher la description des produits',
'option_notify_producer_order_summary' => 'Recevoir les récapitulatifs de commande par email'
'option_notify_producer_order_summary' => 'Recevoir les récapitulatifs de commande par email',
'option_billing_type' => 'Type de facturation',
'option_billing_frequency' => 'Fréquence de facturation',
'option_billing_reduction' => 'Réduction appliquée au moment de la facturation',
'option_tax_calculation_method' => 'Méthode de calcul de la TVA',
'option_export_evoliz' => 'Activer l\'export vers Evoliz'
];
}

@@ -491,6 +518,82 @@ class Producer extends ActiveRecordCommon
}
}

public function getAmountToBeBilledByTurnover($turnover, $format = false)
{
$amountToBeBilled = 0;
$producerPriceRangeArray = ProducerPriceRange::find()->all();
foreach($producerPriceRangeArray as $priceRange) {
if($turnover >= $priceRange->range_begin && $turnover < $priceRange->range_end) {
$amountToBeBilled = $priceRange->price;
}
}

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

public function getAmountToBeBilledByMonth($month, $format = false)
{
$turnover = $this->getTurnover($month);
return $this->getAmountToBeBilledByTurnover($turnover, $format);
}

public function getSummaryAmountsToBeBilled($label, $numberOfMonths = 1)
{
$text = '';
$numMonthCurrent = date('m');

if($numberOfMonths == 1
|| ($numberOfMonths == 3 && (in_array($numMonthCurrent, [1, 4, 7, 10])))
|| ($numberOfMonths == 6 && (in_array($numMonthCurrent, [1, 7])))) {

for ($i = 1; $i <= $numberOfMonths; $i++) {
$month = date('Y-m', strtotime('-' . $i . ' month'));
$turnover = $this->getTurnover($month);

if ($turnover) {
if ($this->isBillingTypeClassic()) {
$text .= '<strong>';
}

$text .= $this->getAmountToBeBilledByTurnover($turnover, true);

if ($this->isBillingTypeClassic()) {
$text .= '</strong>';
}

$text .= ' / '.Price::format($turnover);

$text .= '<br />';
}
}

if (strlen($text)) {
$text = $label . ' : <br />' . $text;
}

}

return $text;
}

public function getAmountBilledLastMonth()
{
if($this->isBillingTypeClassic()) {
$month = date('Y-m', strtotime('-1 month'));
return $this->getAmountToBeBilledByMonth($month);
}
elseif($this->isBillingTypeFreePrice()) {
return $this->free_price;
}

return 0;
}

/**
* Retourne le montant à facturer pour une période donnée.
*
@@ -572,7 +675,7 @@ class Producer extends ActiveRecordCommon
{
if (!is_null($this->free_price)) {
if ($format) {
return number_format($this->free_price, 2, ',', false) . ' € HT';
return number_format($this->free_price, 2, ',', false) . ' €';
} else {
return $this->free_price;
}
@@ -832,5 +935,39 @@ class Producer extends ActiveRecordCommon
return $this->isOnlinePaymentActive() && $this->option_online_payment_type == 'order' ;
}

public static function getBillingFrequencyPopulateDropdown()
{
return self::$billingFrequencyArray;
}

public function isBillingFrequencyMonthly()
{
return $this->option_billing_frequency == self::BILLING_FREQUENCY_MONTHLY;
}

public function isBillingFrequencyQuarterly()
{
return $this->option_billing_frequency == self::BILLING_FREQUENCY_QUARTERLY;
}

public function isBillingFrequencyBiannual()
{
return $this->option_billing_frequency == self::BILLING_FREQUENCY_BIANNUAL;
}

public static function getBillingTypePopulateDropdown()
{
return self::$billingTypeArray;
}

public function isBillingTypeClassic()
{
return $this->option_billing_type == self::BILLING_TYPE_CLASSIC;
}

public function isBillingTypeFreePrice()
{
return $this->option_billing_type == self::BILLING_TYPE_FREE_PRICE;
}
}

+ 95
- 0
common/models/ProducerPriceRange.php 查看文件

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

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

namespace common\models;

use common\components\ActiveRecordCommon;

/**
* This is the model class for table "producer_price_range".
*
* @property integer $id
*/
class ProducerPriceRange extends ActiveRecordCommon
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'producer_price_range';
}

/**
* @inheritdoc
*/
public function rules()
{
return [
[['range_begin', 'range_end', 'price'], 'double'],
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'range_begin' => 'Début',
'range_end' => 'Fin',
'price' => 'Tarif (HT)',
];
}

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

+ 9
- 0
common/models/ProductOrder.php 查看文件

@@ -149,4 +149,13 @@ class ProductOrder extends ActiveRecordCommon
return Price::getPriceWithTax($this->price, $this->taxRate->value);
}

public function getPriceByTypeTotal($typeTotal = Order::AMOUNT_TOTAL)
{
if($typeTotal == Order::INVOICE_AMOUNT_TOTAL && $this->invoice_price) {
return $this->invoice_price;
}

return $this->price;
}

}

+ 12
- 0
common/models/TaxRate.php 查看文件

@@ -58,4 +58,16 @@ class TaxRate extends ActiveRecordCommon
'attribute_id_producer' => ''
] ;
}

public static function getTaxRateArray()
{
$taxRateArrayReturn = [];
$taxRateArray = TaxRate::find()->all();

foreach($taxRateArray as $taxRate) {
$taxRateArrayReturn[$taxRate->id] = $taxRate;
}

return $taxRateArrayReturn;
}
}

+ 3
- 2
common/models/User.php 查看文件

@@ -105,7 +105,7 @@ 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'], 'boolean'],
[['lastname', 'name', 'phone', 'address', 'type', 'name_legal_person'], 'string'],
[['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'],
['email', 'verifyEmail'],
@@ -145,7 +145,8 @@ class User extends ActiveRecordCommon implements IdentityInterface
'name_legal_person' => 'Libellé',
'is_main_contact' => 'Contact principal',
'product_price_percent' => 'Prix produits : pourcentage',
'user_groups' => "Groupes d'utilisateurs"
'user_groups' => "Groupes d'utilisateurs",
'evoliz_code' => 'Code client Evoliz'
];
}


+ 31
- 0
console/migrations/m220914_091112_add_table_producer_price_range.php 查看文件

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

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

/**
* Class m220914_091112_add_table_producer_price_range
*/
class m220914_091112_add_table_producer_price_range extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->createTable('producer_price_range', [
'id' => 'pk',
'range_begin' => Schema::TYPE_DOUBLE . ' NOT NULL',
'range_end' => Schema::TYPE_DOUBLE,
'price' => Schema::TYPE_DOUBLE . ' NOT NULL',
]);
}

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

+ 27
- 0
console/migrations/m220915_072309_producer_add_option_billing_frequency.php 查看文件

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

use yii\db\Migration;
use yii\db\Schema;
use common\models\Producer;

/**
* Class m220915_072309_producer_add_option_billing_frequency
*/
class m220915_072309_producer_add_option_billing_frequency extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn('producer', 'option_billing_frequency', Schema::TYPE_STRING.' DEFAULT \''.Producer::BILLING_FREQUENCY_MONTHLY.'\'');
}

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

+ 29
- 0
console/migrations/m220915_083713_producer_add_options_billing.php 查看文件

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

use yii\db\Migration;
use yii\db\Schema;
use common\models\Producer;

/**
* Class m220915_083713_producer_add_options_billing
*/
class m220915_083713_producer_add_options_billing extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn('producer', 'option_billing_type', Schema::TYPE_STRING.' DEFAULT \''.Producer::BILLING_TYPE_CLASSIC.'\'');
$this->addColumn('producer', 'option_billing_reduction', Schema::TYPE_BOOLEAN.' DEFAULT 0');
}

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

+ 42
- 0
console/migrations/m220916_062206_add_column_document_tax_calculation_method.php 查看文件

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

use yii\db\Migration;
use yii\db\Schema;
use common\models\Document;

/**
* Class m220916_062206_add_column_document_tax_calculation_method
*/
class m220916_062206_add_column_document_tax_calculation_method extends Migration
{
public static $tableDocumentArray = ['invoice', 'delivery_note', 'quotation'];

/**
* {@inheritdoc}
*/
public function safeUp()
{
$schemaTaxCalculationMethod = Schema::TYPE_STRING.' DEFAULT \''.Document::TAX_CALCULATION_METHOD_DEFAULT.'\'';

// producer
$this->addColumn('producer', 'option_tax_calculation_method', $schemaTaxCalculationMethod);

// documents
$columnTaxCalculationMethod = 'tax_calculation_method';
foreach(self::$tableDocumentArray as $tableName) {
$this->addColumn($tableName, $columnTaxCalculationMethod, $schemaTaxCalculationMethod);
}
}

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

foreach(self::$tableDocumentArray as $tableName) {
$this->dropColumn($tableName, 'tax_calculation_method');
}
}
}

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

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

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

/**
* Class m220919_084020_add_fields_export_evoliz
*/
class m220919_084020_add_fields_export_evoliz extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn('producer', 'option_export_evoliz', Schema::TYPE_BOOLEAN .' DEFAULT 0');
$this->addColumn('user', 'evoliz_code', Schema::TYPE_STRING);
}

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

正在加载...
取消
保存