Ver código fonte

Merge branch 'develop'

master
Guillaume Bourgeois 1 ano atrás
pai
commit
cbc5a5ce4a
65 arquivos alterados com 1477 adições e 1256 exclusões
  1. +1
    -1
      backend/controllers/CronController.php
  2. +267
    -916
      backend/controllers/DistributionController.php
  3. +21
    -19
      backend/controllers/OrderController.php
  4. +1
    -2
      backend/controllers/SiteController.php
  5. +8
    -11
      backend/controllers/UserController.php
  6. +12
    -17
      backend/models/CreditForm.php
  7. +1
    -1
      backend/views/development/index.php
  8. +1
    -0
      backend/views/distribution/index.php
  9. +8
    -1
      backend/views/document/download.php
  10. +7
    -4
      backend/views/producer/update.php
  11. +1
    -1
      backend/views/stats-admin/matomo.php
  12. +2
    -2
      backend/views/support/index.php
  13. +16
    -6
      backend/web/css/screen.css
  14. +1
    -1
      backend/web/js/vuejs/distribution-index.js
  15. +17
    -4
      backend/web/sass/development/_index.scss
  16. +64
    -0
      common/components/MailerService.php
  17. +35
    -0
      common/components/ParameterBag.php
  18. +6
    -0
      common/config/main.php
  19. +2
    -2
      common/config/params.php
  20. +7
    -7
      common/helpers/Alwaysdata.php
  21. +5
    -4
      common/helpers/GlobalParam.php
  22. +37
    -0
      common/logic/Distribution/Distribution/Repository/DistributionRepository.php
  23. +238
    -0
      common/logic/Distribution/Distribution/Service/DistributionReportCsvGenerator.php
  24. +164
    -0
      common/logic/Distribution/Distribution/Service/DistributionReportGridPdfGenerator.php
  25. +113
    -0
      common/logic/Distribution/Distribution/Service/DistributionReportPdfGenerator.php
  26. +7
    -16
      common/logic/Distribution/Distribution/Wrapper/DistributionContainer.php
  27. +6
    -0
      common/logic/Distribution/Distribution/Wrapper/DistributionManager.php
  28. +15
    -1
      common/logic/Distribution/ProductDistribution/Service/ProductDistributionBuilder.php
  29. +0
    -1
      common/logic/Document/Document/Service/DocumentUtils.php
  30. +1
    -0
      common/logic/Order/Order/Repository/OrderRepository.php
  31. +24
    -3
      common/logic/PointSale/PointSale/Repository/PointSaleRepository.php
  32. +2
    -0
      common/logic/Producer/Producer/Model/Producer.php
  33. +3
    -0
      common/logic/Producer/Producer/Service/ProducerSolver.php
  34. +2
    -2
      common/logic/Producer/Producer/Service/ProducerUtils.php
  35. +27
    -9
      common/logic/Product/Product/Repository/ProductRepository.php
  36. +26
    -0
      common/logic/Product/Product/Service/ProductSolver.php
  37. +1
    -1
      common/logic/User/User/Repository/UserRepository.php
  38. +1
    -1
      common/logic/User/User/Service/UserSolver.php
  39. +23
    -31
      common/logic/User/User/Service/UserUtils.php
  40. +2
    -2
      common/mail/signup-html.php
  41. +2
    -2
      common/mail/signup-text.php
  42. +24
    -22
      common/versions/22.10.A.php
  43. +8
    -6
      common/versions/22.11.A.php
  44. +9
    -7
      common/versions/22.11.B.php
  45. +6
    -4
      common/versions/22.12.A.php
  46. +7
    -5
      common/versions/23.1.A.php
  47. +7
    -5
      common/versions/23.3.A.php
  48. +7
    -5
      common/versions/23.4.A.php
  49. +10
    -8
      common/versions/23.6.A.php
  50. +16
    -14
      common/versions/23.6.B.php
  51. +6
    -4
      common/versions/23.7.A.php
  52. +7
    -5
      common/versions/23.8.A.php
  53. +10
    -8
      common/versions/23.8.B.php
  54. +27
    -0
      common/versions/23.9.A.php
  55. +22
    -8
      common/versions/_macros.php
  56. +2
    -2
      common/views/matomo.php
  57. +2
    -1
      composer.json
  58. +35
    -1
      composer.lock
  59. +26
    -0
      console/migrations/m230829_081058_add_column_producer_option_document_infos_top.php
  60. +2
    -2
      frontend/controllers/SiteController.php
  61. +1
    -1
      frontend/views/site/index.php
  62. +1
    -1
      frontend/views/site/service.php
  63. +39
    -56
      producer/controllers/CreditController.php
  64. +23
    -21
      producer/controllers/OrderController.php
  65. +3
    -2
      producer/views/order/order.php

+ 1
- 1
backend/controllers/CronController.php Ver arquivo

@@ -193,7 +193,7 @@ class CronController extends BackendController
'orders' => $arrayOrders
]
)
->setFrom([Yii::$app->params['adminEmail'] => 'distrib']);
->setFrom([Yii::$app->parameterBag->get('adminEmail') => 'distrib']);

if (is_array($arrayOrders) && count($arrayOrders)) {
$subject = '[Opendistrib] Commandes du ' . date('d/m', strtotime($date));

+ 267
- 916
backend/controllers/DistributionController.php
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 21
- 19
backend/controllers/OrderController.php Ver arquivo

@@ -826,26 +826,28 @@ class OrderController extends BackendController

foreach ($products as $key => $dataProductOrder) {
$product = $productManager->findOneProductById($key);
$quantity = $dataProductOrder->quantity / Product::$unitsArray[$dataProductOrder->unit]['coefficient'];
if ($product && $quantity) {
$productOrder = new ProductOrder;
$productOrder->id_order = $order->id;
$productOrder->id_product = $key;
$productOrder->quantity = $quantity;
$productOrder->unit = $product->unit;
$productOrder->step = $product->step;
if ($dataProductOrder->price) {
$productOrder->price = $dataProductOrder->price;
} else {
$productOrder->price = $productManager->getPrice($product, [
'user' => $user,
'user_producer' => $userProducer,
'point_sale' => $order->pointSale,
'quantity' => $productOrder->quantity
]);
if(isset(Product::$unitsArray[$dataProductOrder->unit]) && Product::$unitsArray[$dataProductOrder->unit]['coefficient']) {
$quantity = $dataProductOrder->quantity / Product::$unitsArray[$dataProductOrder->unit]['coefficient'];
if ($product && $quantity) {
$productOrder = new ProductOrder;
$productOrder->id_order = $order->id;
$productOrder->id_product = $key;
$productOrder->quantity = $quantity;
$productOrder->unit = $product->unit;
$productOrder->step = $product->step;
if ($dataProductOrder->price) {
$productOrder->price = $dataProductOrder->price;
} else {
$productOrder->price = $productManager->getPrice($product, [
'user' => $user,
'user_producer' => $userProducer,
'point_sale' => $order->pointSale,
'quantity' => $productOrder->quantity
]);
}
$productOrder->id_tax_rate = $product->taxRate->id;
$productOrder->save();
}
$productOrder->id_tax_rate = $product->taxRate->id;
$productOrder->save();
}
}


+ 1
- 2
backend/controllers/SiteController.php Ver arquivo

@@ -108,7 +108,7 @@ class SiteController extends BackendController

/**
* Affiche le tableau de bord du backend avec les dernières commandes
* réalisée, les dernières inscriptions, la liste des clients ayant un crédit
* réalisées, les dernières inscriptions, la liste des clients ayant un crédit
* négatif etc.
*
* @return mixed
@@ -137,7 +137,6 @@ class SiteController extends BackendController
$queryDistributions->andWhere(['>=', 'distribution.date', date('Y-m-d')]);
}


$distributionsArray = $queryDistributions->andWhere([
'distribution.id_producer' => GlobalParam::getCurrentProducerId(),
'distribution.active' => 1

+ 8
- 11
backend/controllers/UserController.php Ver arquivo

@@ -218,20 +218,17 @@ class UserController extends BackendController

$producer = $this->getProducerCurrent();

Mailjet::sendMail([
'from_email' => $producerManager->getEmailOpendistrib($producer),
'from_name' => $producer->name,
'to_email' => $model->email,
'to_name' => $userManager->getUsername($user),
'subject' => '[' . $producer->name . '] Nouveau mot de passe',
'content_view_text' => '@common/mail/newPasswordUserAdmin-text.php',
'content_view_html' => '@common/mail/newPasswordUserAdmin-html.php',
'content_params' => [
\Yii::$app->mailerService->sendFromProducer(
'Nouveau mot de passe',
'newPasswordUserAdmin',
[
'user' => $user,
'producer' => $producer,
'password' => $password,
]
]);
],
$model->email,
$producer
);

$this->setFlash('success', 'Nouveau mot de passe envoyé à <strong>'.Html::encode($userManager->getUsername($model)).'</strong>.');


+ 12
- 17
backend/models/CreditForm.php Ver arquivo

@@ -117,23 +117,18 @@ class CreditForm extends Model
$producer = GlobalParam::getCurrentProducer() ;
$userProducer = $userProducerManager->findOneUserProducer($user);

$paramsEmail = [
'from_email' => $producerManager->getEmailOpendistrib($producer),
'from_name' => $producer->name,
'to_email' => $user->email,
'to_name' => $userManager->getUsername($user),
'subject' => '['.$producer->name.'] Mouvement de crédit',
'content_view_text' => '@common/mail/creditUser-text.php',
'content_view_html' => '@common/mail/creditUser-html.php',
'content_params' => [
'user' => $user,
'producer' => $producer,
'userProducer' => $userProducer,
'creditForm' => $this
]
] ;

Mailjet::sendMail($paramsEmail);
\Yii::$app->mailerService->sendFromProducer(
'Mouvement de crédit',
'creditUser',
[
'user' => $user,
'producer' => $producer,
'userProducer' => $userProducer,
'creditForm' => $this
],
$user->email,
$producer
);
}
}
}

+ 1
- 1
backend/views/development/index.php Ver arquivo

@@ -80,7 +80,7 @@ $this->addBreadcrumb($this->getTitle());
<ul class="contacts">
<li>
<span class="glyphicon glyphicon-earphone"></span>
<p><?= Html::a('Prendre rendez-vous', Yii::$app->params['appointmentUrl'], ['class' => '', 'target' => '_blank']); ?></p>
<p><?= Html::a('Prendre rendez-vous', Yii::$app->parameterBag->get('appointmentUrl'), ['class' => '', 'target' => '_blank']); ?></p>
</li>
<li>
<span class="glyphicon glyphicon-envelope"></span>

+ 1
- 0
backend/views/distribution/index.php Ver arquivo

@@ -303,6 +303,7 @@ $this->setPageTitle('Distributions') ;
</div>

<div class="alert alert-danger" v-if="distribution && !distribution.active && orders && orders.length > 0">
{{ distribution }}
Attention, ce jour de distribution n'est pas activé et vous avez quand même des commandes enregistrées.
</div>


+ 8
- 1
backend/views/document/download.php Ver arquivo

@@ -24,7 +24,14 @@ $documentPriceDecimals = (int) $producerManager->getConfig('option_document_pric
<img style="max-height: 80px;" src="<?= $producerManager->getUrlLogo($producer) ?>"/>
</div>
<?php endif; ?>
<div class="address"><?= $producerManager->getFullAddress($producer, true); ?></div>
<div class="address">
<?= $producerManager->getFullAddress($producer, true); ?>
</div>
<?php if (strlen($producer->document_infos_top)): ?>
<div class="infos-top">
<?= nl2br(Html::encode($producer->document_infos_top)) ?>
</div>
<?php endif; ?>
</div>
<div class="user">
<?php if ($document->address && strlen($document->address) > 0): ?>

+ 7
- 4
backend/views/producer/update.php Ver arquivo

@@ -464,14 +464,17 @@ $this->addBreadcrumb($this->getTitle());
2 => '2',
3 => '3'
]); ?>
<?= $form->field($model, 'document_infos_top')
->textarea(['rows' => 8])
->hint("Affichées juste en dessous de l'adresse"); ?>
<?= $form->field($model, 'document_infos_bottom')
->textarea(['rows' => 15]) ?>
->textarea(['rows' => 8]) ?>
<?= $form->field($model, 'document_infos_quotation')
->textarea(['rows' => 15]) ?>
->textarea(['rows' => 8]) ?>
<?= $form->field($model, 'document_infos_invoice')
->textarea(['rows' => 15]) ?>
->textarea(['rows' => 8]) ?>
<?= $form->field($model, 'document_infos_delivery_note')
->textarea(['rows' => 15]) ?>
->textarea(['rows' => 8]) ?>
</div>
</div>


+ 1
- 1
backend/views/stats-admin/matomo.php Ver arquivo

@@ -5,4 +5,4 @@ $this->addBreadcrumb('Statistiques Matomo') ;

?>

<iframe id="matomoframe" src="<?= Yii::$app->params['matomoWidgetDashbordUrl']; ?>" frameborder="0" marginheight="0" marginwidth="0" width="100%" height="800px"></iframe>
<iframe id="matomoframe" src="<?= Yii::$app->parameterBag->get('matomoWidgetDashbordUrl'); ?>" frameborder="0" marginheight="0" marginwidth="0" width="100%" height="800px"></iframe>

+ 2
- 2
backend/views/support/index.php Ver arquivo

@@ -58,7 +58,7 @@ $this->addBreadcrumb($this->getTitle());
<span class="info-box-text">Me contacter directement</span>
<span class="info-box-text">
<br/>
<strong><?= Yii::$app->params['adminPhoneNumber'] ?></strong>
<strong><?= Yii::$app->parameterBag->get('adminPhoneNumber'); ?></strong>
</span>
</div>
</div>
@@ -68,7 +68,7 @@ $this->addBreadcrumb($this->getTitle());
<span class="info-box-icon bg-yellow"><i class="fa fa-calendar"></i></span>
<div class="info-box-content">
<span class="info-box-text"><br/>
<?= Html::a('Prendre rendez-vous', Yii::$app->params['appointmentUrl'], ['class' => 'btn btn-sm btn-default', 'target' => '_blank']); ?>
<?= Html::a('Prendre rendez-vous', Yii::$app->parameterBag->get('appointmentUrl'), ['class' => 'btn btn-sm btn-default', 'target' => '_blank']); ?>
</span>
</div>
</div>

+ 16
- 6
backend/web/css/screen.css Ver arquivo

@@ -2660,27 +2660,37 @@ termes.
border-bottom: solid 1px #e0e0e0;
padding-bottom: 4px;
}
/* line 20, ../sass/development/_index.scss */
.development-index #versions-list .panel .block ul {
/* line 21, ../sass/development/_index.scss */
.development-index #versions-list .panel .block.block-release-date ul {
padding: 0px;
list-style-type: none;
}
/* line 33, ../sass/development/_index.scss */
/* line 29, ../sass/development/_index.scss */
.development-index #versions-list .panel .block.block-features ul, .development-index #versions-list .panel .block.block-maintenance ul {
list-style-type: circle;
padding: 0px;
padding-left: 15px;
}
/* line 35, ../sass/development/_index.scss */
.development-index #versions-list .panel .block.block-features ul li.admin, .development-index #versions-list .panel .block.block-maintenance ul li.admin {
color: gray;
}
/* line 46, ../sass/development/_index.scss */
.development-index #panel-participate ul.contacts {
padding: 0px;
padding-left: 10px;
margin: 0px;
list-style-type: none;
}
/* line 39, ../sass/development/_index.scss */
/* line 52, ../sass/development/_index.scss */
.development-index #panel-participate ul.contacts li {
padding-bottom: 10px;
}
/* line 42, ../sass/development/_index.scss */
/* line 55, ../sass/development/_index.scss */
.development-index #panel-participate ul.contacts li .glyphicon {
float: left;
}
/* line 46, ../sass/development/_index.scss */
/* line 59, ../sass/development/_index.scss */
.development-index #panel-participate ul.contacts li p {
padding-left: 25px;
}

+ 1
- 1
backend/web/js/vuejs/distribution-index.js Ver arquivo

@@ -997,7 +997,7 @@ Vue.component('order-form',{
price = getPrice(priceWithTax, taxRateValue);
}
else {
price = priceValue.toFixed(3);
price = priceValue.toFixed(5);
priceWithTax = getPriceWithTax(price, taxRateValue);
}


+ 17
- 4
backend/web/sass/development/_index.scss Ver arquivo

@@ -17,12 +17,25 @@
padding-bottom: 4px;
}

ul {
padding: 0px;
list-style-type: none;
&.block-release-date {
ul {
padding: 0px;
list-style-type: none;
}
}

li {
&.block-features,
&.block-maintenance {
ul {
list-style-type: circle;
padding: 0px;
padding-left: 15px;

li {
&.admin {
color: gray;
}
}
}
}
}

+ 64
- 0
common/components/MailerService.php Ver arquivo

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

namespace common\components;

use common\logic\Producer\Producer\Model\Producer;
use yii\mail\MessageInterface;

class MailerService
{
public function sendFromProducer(string $subject, string $view, array $params, string $toEmail, Producer $producer)
{
$message = $this->composeBase($toEmail, $view, $params);
$this->initMessageFromProducer($message, $subject, $producer);
$message->send();
}

public function sendFromSite(string $subject, string $view, array $params, string $toEmail)
{
$message = $this->composeBase($toEmail, $view, $params);
$this->initMessageFromSite($message, $subject);
$message->send();
}

public function sendAdmin(string $subject, string $view, array $params = [])
{
$message = $this->composeBase(\Yii::$app->parameterBag->get('adminEmail'), $view, $params);
$this->initMessageFromSite($message, $subject);
$message->send();
}

private function composeBase(string $toEmail, string $view, array $params = [])
{
return \Yii::$app->mailer
->compose([
'html' => '@common/mail/'.$view.'-html.php',
'text' => '@common/mail/'.$view.'-text.php'
], $params)
->setTo($toEmail);
}

private function initMessageFromSite(MessageInterface $message, string $subject)
{
$message->setFrom([\Yii::$app->parameterBag->get('adminEmail') => \Yii::$app->parameterBag->get('siteName')]);
$message->setSubject($this->buildSubject(\Yii::$app->parameterBag->get('siteName'), $subject));
return $message;
}

private function initMessageFromProducer(MessageInterface $message, string $subject, Producer $producer)
{
$message->setFrom([$this->getEmailOpendistrib($producer) => $producer->name]);
$message->setSubject($this->buildSubject($producer->name, $subject));
return $message;
}

private function getEmailOpendistrib(Producer $producer): string
{
return $producer->slug . '@opendistrib.net';
}

private function buildSubject(string $prefix, string $subject)
{
return '['.$prefix.'] '.$subject;
}
}

+ 35
- 0
common/components/ParameterBag.php Ver arquivo

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

namespace common\components;

use yii\base\ErrorException;

class ParameterBag
{
protected array $parameters = [];

public function __construct()
{
$this->parameters = \Yii::$app->params;
}

public function get(string $name)
{
if(isset($this->parameters[$name])) {
return $this->parameters[$name];
}
else {
throw new ErrorException('Paramètre '.$name.' non défini.');
}
}

public function has(string $name)
{
return \array_key_exists($name, $this->parameters);
}

public function set(string $name, $value)
{
$this->parameters[$name] = $value;
}
}

+ 6
- 0
common/config/main.php Ver arquivo

@@ -60,6 +60,9 @@ return [
}
},
'components' => [
'parameterBag' => [
'class' => 'common\components\ParameterBag'
],
'assetManager' => [
'linkAssets' => YII_ENV == "dev" ? 'true' : false,
],
@@ -88,6 +91,9 @@ return [
'class' => 'yii\image\ImageDriver',
'driver' => 'GD', //GD or Imagick
],
'mailerService' => [
'class' => 'common\components\MailerService'
],
'urlManagerProducer' => [
'class' => 'producer\components\UrlManagerProducer',
'subDomain' => Yii::getAlias('@producerSubdomain'),

+ 2
- 2
common/config/params.php Ver arquivo

@@ -37,7 +37,8 @@
*/

return [
'version' => '23.8.B',
'version' => '23.9.A',
'siteName' => 'Opendistrib',
'adminEmail' => 'contact@opendistrib.net',
'supportEmail' => 'contact@opendistrib.net',
'user.passwordResetTokenExpire' => 3600,
@@ -93,5 +94,4 @@ return [
]

]

];

+ 7
- 7
common/helpers/Alwaysdata.php Ver arquivo

@@ -11,7 +11,7 @@ class Alwaysdata
public static function createProducerEmailRedirection(Producer $producer)
{
return self::post('mailbox',[
'domain' => \Yii::$app->params['alwaysdataDomainOpendistribId'],
'domain' => \Yii::$app->parameterBag->get('alwaysdataDomainOpendistribId'),
'name' => $producer->slug,
'password' => Password::generate(13),
'redirect_enabled' => true,
@@ -44,17 +44,17 @@ class Alwaysdata
self::checkConfiguration();

return new Client([
'base_uri' => \Yii::$app->params['alwaysdataApiUrl'].$resource.'/',
'auth' => [\Yii::$app->params['alwaysdataApiKey'].' account='.\Yii::$app->params['alwaysdataAccount'], ''],
'base_uri' => \Yii::$app->parameterBag->get('alwaysdataApiUrl').$resource.'/',
'auth' => [\Yii::$app->parameterBag->get('alwaysdataApiKey').' account='.\Yii::$app->parameterBag->get('alwaysdataAccount'), ''],
]);
}

private static function checkConfiguration()
{
if(!isset(\Yii::$app->params['alwaysdataApiUrl'])
|| !isset(\Yii::$app->params['alwaysdataAccount'])
|| !isset(\Yii::$app->params['alwaysdataApiKey'])
|| !isset(\Yii::$app->params['alwaysdataDomainOpendistribId'])) {
if(!\Yii::$app->parameterBag->has('alwaysdataApiUrl')
|| !\Yii::$app->parameterBag->has('alwaysdataAccount')
|| !\Yii::$app->parameterBag->has('alwaysdataApiKey')
|| !\Yii::$app->parameterBag->has('alwaysdataDomainOpendistribId')) {

throw new ErrorException('Configuration API Alwaysdata absente ou incomplète dans params-local.php');
}

+ 5
- 4
common/helpers/GlobalParam.php Ver arquivo

@@ -49,7 +49,7 @@ class GlobalParam
return self::getCurrentProducer();
} else {

return \Yii::$app->params[$key];
return \Yii::$app->parameterBag->get($key);
}
}

@@ -60,10 +60,11 @@ class GlobalParam

public static function getCurrentProducer()
{
if (\Yii::$app->params['producer'] == false) {
\Yii::$app->params['producer'] = Producer::searchOne();
if(!\Yii::$app->parameterBag->has('producer') || !\Yii::$app->parameterBag->get('producer')) {
\Yii::$app->parameterBag->set('producer', Producer::searchOne());
}
return \Yii::$app->params['producer'];

return \Yii::$app->parameterBag->get('producer');
}

/**

+ 37
- 0
common/logic/Distribution/Distribution/Repository/DistributionRepository.php Ver arquivo

@@ -2,6 +2,7 @@

namespace common\logic\Distribution\Distribution\Repository;

use common\helpers\GlobalParam;
use common\logic\AbstractRepository;
use common\logic\Distribution\Distribution\Model\Distribution;
use common\logic\Distribution\Distribution\Service\DistributionSolver;
@@ -125,4 +126,40 @@ class DistributionRepository extends AbstractRepository
return false;
}

public function isOneDistributionWeekActive(string $date): bool
{
$oneDistributionWeekActive = false;
$week = sprintf('%02d', date('W', strtotime($date)));
$start = strtotime(date('Y', strtotime($date)) . 'W' . $week);
$dateMonday = date('Y-m-d', strtotime('Monday', $start));
$dateTuesday = date('Y-m-d', strtotime('Tuesday', $start));
$dateWednesday = date('Y-m-d', strtotime('Wednesday', $start));
$dateThursday = date('Y-m-d', strtotime('Thursday', $start));
$dateFriday = date('Y-m-d', strtotime('Friday', $start));
$dateSaturday = date('Y-m-d', strtotime('Saturday', $start));
$dateSunday = date('Y-m-d', strtotime('Sunday', $start));

$weekDistribution = Distribution::find()
->andWhere([
'id_producer' => $this->getProducerContextId(),
'active' => 1,
])
->andWhere([
'or',
['date' => $dateMonday],
['date' => $dateTuesday],
['date' => $dateWednesday],
['date' => $dateThursday],
['date' => $dateFriday],
['date' => $dateSaturday],
['date' => $dateSunday],
])
->one();
if ($weekDistribution) {
$oneDistributionWeekActive = true;
}

return $oneDistributionWeekActive;
}
}

+ 238
- 0
common/logic/Distribution/Distribution/Service/DistributionReportCsvGenerator.php Ver arquivo

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

namespace common\logic\Distribution\Distribution\Service;

use common\helpers\CSV;
use common\logic\AbstractGenerator;
use common\logic\Distribution\Distribution\Model\Distribution;
use common\logic\Order\Order\Repository\OrderRepository;
use common\logic\Order\Order\Service\OrderBuilder;
use common\logic\Order\Order\Service\OrderSolver;
use common\logic\PointSale\PointSale\Repository\PointSaleRepository;
use common\logic\Producer\Producer\Repository\ProducerRepository;
use common\logic\Product\Product\Model\Product;
use common\logic\Product\Product\Repository\ProductRepository;
use common\logic\Product\Product\Service\ProductSolver;

class DistributionReportCsvGenerator extends AbstractGenerator
{
protected ProducerRepository $producerRepository;
protected ProductRepository $productRepository;
protected ProductSolver $productSolver;
protected OrderRepository $orderRepository;
protected OrderSolver $orderSolver;
protected PointSaleRepository $pointSaleRepository;
protected OrderBuilder $orderBuilder;

public function loadDependencies(): void
{
$this->producerRepository = $this->loadService(ProducerRepository::class);
$this->productRepository = $this->loadService(ProductRepository::class);
$this->productSolver = $this->loadService(ProductSolver::class);
$this->orderRepository = $this->loadService(OrderRepository::class);
$this->orderSolver = $this->loadService(OrderSolver::class);
$this->pointSaleRepository = $this->loadService(PointSaleRepository::class);
$this->orderBuilder = $this->loadService(OrderBuilder::class);
}

public function generateDistributionReportCsv(Distribution $distribution)
{
$datas = [];
$ordersArray = $this->orderRepository->findOrdersByDistribution($distribution);
$productsArray = $this->productRepository->findProductsByDistribution($distribution);
$optionCsvExportAllProducts = $this->producerRepository->getConfig('option_csv_export_all_products');
$optionCsvExportByPiece = $this->producerRepository->getConfig('option_csv_export_by_piece');
$pointsSaleArray = $this->pointSaleRepository->findPointSales();
foreach ($pointsSaleArray as $pointSale) {
$this->orderBuilder->initPointSaleOrders($pointSale, $ordersArray);
}

// produits en colonne
$productsNameArray = ['', 'Commentaire'];
$productsIndexArray = [];
$productsHasQuantity = [];
$cpt = 2;
foreach ($productsArray as $product) {
$productsHasQuantity[$product->id] = 0;
foreach (Product::$unitsArray as $unit => $dataUnit) {
$quantity = $this->orderSolver->getProductQuantity($product, $ordersArray, true, $unit);
if ($quantity) {
$productsHasQuantity[$product->id] += $quantity;
}
}
if ($productsHasQuantity[$product->id] > 0 || $optionCsvExportAllProducts) {
$productName = $this->productSolver->getNameExport($product);

if ($optionCsvExportByPiece) {
$productUnit = 'piece';
} else {
$productUnit = $product->unit;
}

$productName .= ' (' . $this->productSolver->strUnit($productUnit, 'wording_short', true) . ')';

$productsNameArray[] = $productName;
$productsIndexArray[$product->id] = $cpt++;
}
}
$datas[] = $productsNameArray;

// points de vente
foreach ($pointsSaleArray as $pointSale) {
if (count($pointSale->orders)) {
// listing commandes
$datas[] = ['> ' . $pointSale->name];
foreach ($pointSale->orders as $order) {
$orderLine = [$this->orderSolver->getOrderUsername($order), $this->orderSolver->getCommentReport($order)];

if ($optionCsvExportByPiece) {
foreach ($order->productOrder as $productOrder) {
$orderLine[$productsIndexArray[$productOrder->id_product]] = $this->orderSolver->getProductQuantityPieces(
$productOrder->product,
[$order]
);
}
} else {
foreach ($productsIndexArray as $idProduct => $indexProduct) {
$orderLine[$indexProduct] = '';
}

foreach ($order->productOrder as $productOrder) {
if (strlen($orderLine[$productsIndexArray[$productOrder->id_product]])) {
$orderLine[$productsIndexArray[$productOrder->id_product]] .= ' + ';
}
$orderLine[$productsIndexArray[$productOrder->id_product]] .= $productOrder->quantity;
if ($productOrder->product->unit != $productOrder->unit) {
$orderLine[$productsIndexArray[$productOrder->id_product]] .= $productManager->strUnit(
$productOrder->unit,
'wording_short',
true
);
}
}
}

$datas[] = $this->lineOrderReport($orderLine, $cpt);
}

// total point de vente
if ($optionCsvExportByPiece) {
$totalsPointSaleArray = $this->totalReportPieces(
'Total',
$pointSale->orders,
$productsArray,
$productsIndexArray
);
} else {
$totalsPointSaleArray = $this->totalReport(
'Total',
$pointSale->orders,
$productsArray,
$productsIndexArray
);
}

$datas[] = $this->lineOrderReport($totalsPointSaleArray, $cpt);

$datas[] = [];
}
}

// global
if ($optionCsvExportByPiece) {
$totalsGlobalArray = $this->totalReportPieces(
'> Totaux',
$ordersArray,
$productsArray,
$productsIndexArray
);
} else {
$totalsGlobalArray = $this->totalReport(
'> Totaux',
$ordersArray,
$productsArray,
$productsIndexArray
);
}

$datas[] = $this->lineOrderReport($totalsGlobalArray, $cpt);

CSV::send('Commandes_' . $distribution->date . '.csv', $datas);
}

private function totalReport($label, $ordersArray, $productsArray, $productsIndexArray)
{
$totalsPointSaleArray = [$label];
foreach ($productsArray as $product) {
foreach (Product::$unitsArray as $unit => $dataUnit) {
$quantity = $this->orderSolver->getProductQuantity($product, $ordersArray, false, $unit);
if ($quantity) {
$index = $productsIndexArray[$product->id];
if (!isset($totalsPointSaleArray[$index])) {
$totalsPointSaleArray[$index] = '';
}

if (strlen($totalsPointSaleArray[$index])) {
$totalsPointSaleArray[$index] .= ' + ';
}

$totalsPointSaleArray[$index] .= $quantity;

if ($product->unit != $unit) {
$totalsPointSaleArray[$index] .= '' . $this->productSolver->strUnit($unit, 'wording_short', true);
}
}
}
}
return $totalsPointSaleArray;
}

private function totalReportPieces($label, $ordersArray, $productsArray, $productsIndexArray)
{
$totalsPointSaleArray = [$label];
foreach ($productsArray as $product) {
$quantity = 0;
foreach (Product::$unitsArray as $unit => $dataUnit) {
$quantityProduct = $this->orderSolver->getProductQuantity($product, $ordersArray, false, $unit);

if ($unit == 'piece') {
$quantity += $quantityProduct;
} else {
if ($product->weight > 0) {
$quantity += ($quantityProduct * $dataUnit['coefficient']) / $product->weight;
}
}
}

if ($quantity) {
$index = $productsIndexArray[$product->id];
$totalsPointSaleArray[$index] = $quantity;
}
}

return $totalsPointSaleArray;
}

private function lineOrderReport($orderLine, $cptMax, $showTotal = false)
{
$line = [];
$cptTotal = 0;

for ($i = 0; $i <= $cptMax; $i++) {
if (isset($orderLine[$i]) && $orderLine[$i]) {
$line[] = $orderLine[$i];
if (is_numeric($orderLine[$i])) {
$cptTotal += $orderLine[$i];
}
} else {
$line[] = '';
}
}

if ($cptTotal > 0 && $showTotal) {
$line[] = $cptTotal;
}

return $line;
}
}

+ 164
- 0
common/logic/Distribution/Distribution/Service/DistributionReportGridPdfGenerator.php Ver arquivo

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

namespace common\logic\Distribution\Distribution\Service;

use common\logic\AbstractGenerator;
use common\logic\Distribution\Distribution\Model\Distribution;
use common\logic\Distribution\ProductDistribution\Repository\ProductDistributionRepository;
use common\logic\Order\Order\Repository\OrderRepository;
use common\logic\Order\Order\Service\OrderBuilder;
use common\logic\PointSale\PointSale\Repository\PointSaleRepository;
use common\logic\Product\Product\Repository\ProductRepository;
use common\logic\Product\ProductCategory\Repository\ProductCategoryRepository;
use kartik\mpdf\Pdf;

class DistributionReportGridPdfGenerator extends AbstractGenerator
{
protected OrderRepository $orderRepository;
protected OrderBuilder $orderBuilder;
protected ProductDistributionRepository $productDistributionRepository;
protected PointSaleRepository $pointSaleRepository;
protected ProductCategoryRepository $productCategoryRepository;
protected ProductRepository $productRepository;

public function loadDependencies(): void
{
$this->orderRepository = $this->loadService(OrderRepository::class);
$this->orderBuilder = $this->loadService(OrderBuilder::class);
$this->productDistributionRepository = $this->loadService(ProductDistributionRepository::class);
$this->pointSaleRepository = $this->loadService(PointSaleRepository::class);
$this->productCategoryRepository = $this->loadService(ProductCategoryRepository::class);
$this->productRepository = $this->loadService(ProductRepository::class);
}

public function generateDistributionReportGridPdf(Distribution $distribution, bool $save = false)
{
$producer = $this->getProducerContext();
$ordersArray = $this->orderRepository->findOrdersByDistribution($distribution);
$selectedProductsArray = $this->productDistributionRepository->findProductDistributionsByDistribution($distribution);
$pointsSaleArray = $this->pointSaleRepository->findPointSales();
foreach ($pointsSaleArray as $pointSale) {
$this->orderBuilder->initPointSaleOrders($pointSale, $ordersArray);
}

$ordersByPage = 22;
$ordersArrayPaged = [];

foreach ($pointsSaleArray as $pointSale) {
$index = 0;
$indexPage = 0;

foreach ($pointSale->orders as $order) {
if (!isset($ordersArrayPaged[$pointSale->id])) {
$ordersArrayPaged[$pointSale->id] = [];
}
if (!isset($ordersArrayPaged[$pointSale->id][$indexPage])) {
$ordersArrayPaged[$pointSale->id][$indexPage] = [];
}
$ordersArrayPaged[$pointSale->id][$indexPage][] = $order;

$index++;

if ($index == $ordersByPage) {
$index = 0;
$indexPage++;
}
}
}

$categoriesArray = $this->productCategoryRepository->findProductCategories();
array_unshift($categoriesArray, null);
$productsArray = $this->productRepository->findProductsByDistribution($distribution);

$viewPdf = '@backend/views/distribution/report-grid';
$orientationPdf = Pdf::ORIENT_PORTRAIT;

if ($producer->slug == 'bourlinguepacotille') {
$viewPdf = '@backend/views/distribution/report-bourlingue';
$orientationPdf = Pdf::ORIENT_LANDSCAPE;
}

// get your HTML raw content without any layouts or scripts
$content = \Yii::$app->getView()->render($viewPdf, [
'date' => $distribution->date,
'distribution' => $distribution,
'selectedProductsArray' => $selectedProductsArray,
'pointsSaleArray' => $pointsSaleArray,
'categoriesArray' => $categoriesArray,
'productsArray' => $productsArray,
'ordersArray' => $ordersArrayPaged,
'producer' => $producer
]);

$dateStr = date('d/m/Y', strtotime($distribution->date));

if ($save) {
$destination = Pdf::DEST_FILE;
} else {
$destination = Pdf::DEST_BROWSER;
}

$pdf = new Pdf([
'mode' => Pdf::MODE_UTF8,
'format' => Pdf::FORMAT_A4,
'orientation' => $orientationPdf,
'destination' => $destination,
'filename' => \Yii::getAlias(
'@app/web/pdf/Commandes-' . $distribution->date . '-' . $producer->id . '.pdf'
),
'content' => $content,
//'cssFile' => Yii::getAlias('@web/css/distribution/report.css'),
'cssInline' => '
table {
border-spacing : 0px ;
border-collapse : collapse ;
width: 100% ;
}
table tr th,
table tr td {
padding: 0px ;
margin: 0px ;
border: solid 1px #e0e0e0 ;
padding: 3px ;
vertical-align : top;
page-break-inside: avoid !important;
}

table tr th {
font-size: 10px ;
}
table tr td {
font-size: 10px ;
}
table thead tr {
line-height: 220px;
text-align:left;
}
.th-user,
.td-nb-products {
/* width: 35px ; */
text-align: center ;
}
.th-user {
padding: 10px ;
}
.category-name {
font-weight: bold ;
}
',
'methods' => [
'SetHeader' => ['Commandes du ' . $dateStr],
'SetFooter' => ['{PAGENO}'],
]
]);

return $pdf->render();
}
}

+ 113
- 0
common/logic/Distribution/Distribution/Service/DistributionReportPdfGenerator.php Ver arquivo

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

namespace common\logic\Distribution\Distribution\Service;

use common\logic\AbstractGenerator;
use common\logic\Distribution\Distribution\Model\Distribution;
use common\logic\Distribution\ProductDistribution\Repository\ProductDistributionRepository;
use common\logic\Order\Order\Repository\OrderRepository;
use common\logic\Order\Order\Service\OrderBuilder;
use common\logic\PointSale\PointSale\Repository\PointSaleRepository;
use common\logic\Product\Product\Repository\ProductRepository;
use kartik\mpdf\Pdf;

class DistributionReportPdfGenerator extends AbstractGenerator
{
protected OrderRepository $orderRepository;
protected OrderBuilder $orderBuilder;
protected ProductRepository $productRepository;
protected ProductDistributionRepository $productDistributionRepository;
protected PointSaleRepository $pointSaleRepository;

public function loadDependencies(): void
{
$this->orderRepository = $this->loadService(OrderRepository::class);
$this->orderBuilder = $this->loadService(OrderBuilder::class);
$this->productRepository = $this->loadService(ProductRepository::class);
$this->productDistributionRepository = $this->loadService(ProductDistributionRepository::class);
$this->pointSaleRepository = $this->loadService(PointSaleRepository::class);
}

public function generateDistributionReportPdf(Distribution $distribution, bool $save = false)
{
$producer = $this->getProducerContext();
$ordersArray = $this->orderRepository->findOrdersByDistribution($distribution);
$productsArray = $this->productRepository->findProductsByDistribution($distribution);
$selectedProductsArray = $this->productDistributionRepository->findProductDistributionsByDistribution($distribution);
$pointsSaleArray = $this->pointSaleRepository->findPointSales();
foreach ($pointsSaleArray as $pointSale) {
$this->orderBuilder->initPointSaleOrders($pointSale, $ordersArray);
}

$viewPdf = '@backend/views/distribution/report';
$orientationPdf = Pdf::ORIENT_PORTRAIT;

if ($producer->slug == 'bourlinguepacotille') {
$viewPdf = '@backend/views/distribution/report-bourlingue';
$orientationPdf = Pdf::ORIENT_LANDSCAPE;
}

// get your HTML raw content without any layouts or scripts
$content = \Yii::$app->getView()->render($viewPdf, [
'date' => $distribution->date,
'distribution' => $distribution,
'selectedProductsArray' => $selectedProductsArray,
'pointsSaleArray' => $pointsSaleArray,
'productsArray' => $productsArray,
'ordersArray' => $ordersArray,
'producer' => $producer
]);

$dateStr = date('d/m/Y', strtotime($distribution->date));

if ($save) {
$destination = Pdf::DEST_FILE;
} else {
$destination = Pdf::DEST_BROWSER;
}

$pdf = new Pdf([
'mode' => Pdf::MODE_UTF8,
'format' => Pdf::FORMAT_A4,
'orientation' => $orientationPdf,
'destination' => $destination,
'filename' => \Yii::getAlias(
'@app/web/pdf/Commandes-' . $distribution->date . '-' . $this->getProducerContextId() . '.pdf'
),
'content' => $content,
//'cssFile' => Yii::getAlias('@web/css/distribution/report.css'),
'cssInline' => '
table {
border-spacing : 0px ;
border-collapse : collapse ;
width: 100% ;
}
table tr th,
table tr td {
padding: 0px ;
margin: 0px ;
border: solid 1px #e0e0e0 ;
padding: 3px 8px ;
vertical-align : top;
page-break-inside: avoid !important;
color: black;
}

table tr th {
font-size: 13px ;
}

table tr td {
font-size: 13px ;
}
',
'methods' => [
'SetHeader' => ['Commandes du ' . $dateStr],
'SetFooter' => ['{PAGENO}'],
]
]);

return $pdf->render();
}
}

+ 7
- 16
common/logic/Distribution/Distribution/Wrapper/DistributionContainer.php Ver arquivo

@@ -6,6 +6,9 @@ use common\logic\AbstractContainer;
use common\logic\Distribution\Distribution\Repository\DistributionRepository;
use common\logic\Distribution\Distribution\Service\DistributionBuilder;
use common\logic\Distribution\Distribution\Service\DistributionDefinition;
use common\logic\Distribution\Distribution\Service\DistributionReportCsvGenerator;
use common\logic\Distribution\Distribution\Service\DistributionReportGridPdfGenerator;
use common\logic\Distribution\Distribution\Service\DistributionReportPdfGenerator;
use common\logic\Distribution\Distribution\Service\DistributionSolver;

class DistributionContainer extends AbstractContainer
@@ -16,7 +19,10 @@ class DistributionContainer extends AbstractContainer
DistributionDefinition::class,
DistributionSolver::class,
DistributionRepository::class,
DistributionBuilder::class
DistributionBuilder::class,
DistributionReportCsvGenerator::class,
DistributionReportGridPdfGenerator::class,
DistributionReportPdfGenerator::class,
];
}

@@ -24,19 +30,4 @@ class DistributionContainer extends AbstractContainer
{
return DistributionDefinition::getInstance();
}

public function getSolver(): DistributionSolver
{
return DistributionSolver::getInstance();
}

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

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

+ 6
- 0
common/logic/Distribution/Distribution/Wrapper/DistributionManager.php Ver arquivo

@@ -6,6 +6,9 @@ use common\logic\AbstractManager;
use common\logic\Distribution\Distribution\Repository\DistributionRepository;
use common\logic\Distribution\Distribution\Service\DistributionBuilder;
use common\logic\Distribution\Distribution\Service\DistributionDefinition;
use common\logic\Distribution\Distribution\Service\DistributionReportCsvGenerator;
use common\logic\Distribution\Distribution\Service\DistributionReportGridPdfGenerator;
use common\logic\Distribution\Distribution\Service\DistributionReportPdfGenerator;
use common\logic\Distribution\Distribution\Service\DistributionSolver;

/**
@@ -13,6 +16,9 @@ use common\logic\Distribution\Distribution\Service\DistributionSolver;
* @mixin DistributionSolver
* @mixin DistributionRepository
* @mixin DistributionBuilder
* @mixin DistributionReportCsvGenerator
* @mixin DistributionReportGridPdfGenerator
* @mixin DistributionReportPdfGenerator
*/
class DistributionManager extends AbstractManager
{

+ 15
- 1
common/logic/Distribution/ProductDistribution/Service/ProductDistributionBuilder.php Ver arquivo

@@ -46,10 +46,11 @@ class ProductDistributionBuilder extends AbstractBuilder
return $this->productDistributionRepository->findOneProductDistribution($distribution, $product)
?? $this->createProductDistribution($distribution, $product);
}

public function updateProductDistribution(ProductDistribution $productDistribution): ProductDistribution
{
$this->initProductDistribution($productDistribution);
$this->saveUpdate($productDistribution);
$this->update($productDistribution);

return $productDistribution;
}
@@ -82,4 +83,17 @@ class ProductDistributionBuilder extends AbstractBuilder
return $productDistribution;
}

public function updateProductDistributionQuantityMax(ProductDistribution $productDistribution, float $quantityMax)
{
$productDistribution->quantity_max = ($quantityMax == -1) ? null : (float) abs($quantityMax);
$this->update($productDistribution);

return $productDistribution;
}

public function updateProductDistributionActive(ProductDistribution $productDistribution, int $active)
{
$productDistribution->active = $active;
$this->update($productDistribution);
}
}

+ 0
- 1
common/logic/Document/Document/Service/DocumentUtils.php Ver arquivo

@@ -81,7 +81,6 @@ class DocumentUtils extends AbstractService implements UtilsInterface
$aliasDirectoryBase = $this->documentSolver->getAliasDirectoryBase($document);
$directoryPdf = \Yii::getAlias($aliasDirectoryBase);
if (!file_exists($directoryPdf)) {
//die('dir : '.$directoryPdf);
mkdir($directoryPdf, 0755);
}
}

+ 1
- 0
common/logic/Order/Order/Repository/OrderRepository.php Ver arquivo

@@ -109,6 +109,7 @@ class OrderRepository extends AbstractRepository
->filterByDistributionDate($distribution->date)
->filterIsValid()
->filterByCondition($conditionAppend)
->orderBy('user.lastname ASC, user.name ASC, comment_point_sale ASC')
->find();
}


+ 24
- 3
common/logic/PointSale/PointSale/Repository/PointSaleRepository.php Ver arquivo

@@ -50,14 +50,35 @@ class PointSaleRepository extends AbstractRepository
->findOne();
}

public function findPointSalesByDistribution(Distribution $distribution)
public function queryPointSalesByDistribution(Distribution $distribution)
{
return $this->createDefaultQuery()
->filterIsOnline()
->with(['pointSaleDistribution' => function ($q) use ($distribution) {
$q->where(['id_distribution' => $distribution->id]);
}])
->find();
}]);
}

public function findPointSalesByDistribution(Distribution $distribution)
{
return $this->queryPointSalesByDistribution($distribution)->find();
}

public function findPointSalesByDistributionAsArray(Distribution $distribution)
{
return $this->queryPointSalesByDistribution($distribution)->asArray()->find();
}

public function findOnePointSaleDefaultByDistribution(Distribution $distribution): ?PointSale
{
$pointSalesArray = $this->findPointSalesByDistribution($distribution);
foreach($pointSalesArray as $pointSale) {
if($pointSale->default) {
return $pointSale;
}
}

return null;
}

/**

+ 2
- 0
common/logic/Producer/Producer/Model/Producer.php Ver arquivo

@@ -201,6 +201,7 @@ class Producer extends ActiveRecordCommon
'tiller_provider_token',
'tiller_restaurant_token',
'status',
'document_infos_top',
'document_infos_bottom',
'document_infos_quotation',
'document_infos_invoice',
@@ -368,6 +369,7 @@ class Producer extends ActiveRecordCommon
'document_invoice_first_reference' => 'Première référence des factures',
'document_delivery_note_prefix' => 'Préfixe des bons de livraison',
'document_delivery_note_first_reference' => 'Première référence des bons de livraison',
'document_infos_top' => 'Informations affichées en haut des documents',
'document_infos_bottom' => 'Informations affichées en bas des documents',
'document_infos_quotation' => 'Informations affichées en bas des devis',
'document_infos_invoice' => 'Informations affichées en bas des factures',

+ 3
- 0
common/logic/Producer/Producer/Service/ProducerSolver.php Ver arquivo

@@ -59,6 +59,9 @@ class ProducerSolver extends AbstractService implements SolverInterface
return \Yii::$app->urlManagerProducer->getHostInfo() . '/' . \Yii::$app->urlManagerProducer->baseUrl . '/uploads/' . $producer->logo;
}

/**
* @deprecated Déplacé dans MailerService
*/
public function getEmailOpendistrib(Producer $producer): string
{
return $producer->slug . '@opendistrib.net';

+ 2
- 2
common/logic/Producer/Producer/Service/ProducerUtils.php Ver arquivo

@@ -17,8 +17,8 @@ class ProducerUtils extends AbstractService implements UtilsInterface
], [
'producer' => $producer
])
->setTo(\Yii::$app->params['adminEmail'])
->setFrom([\Yii::$app->params['adminEmail'] => 'distrib'])
->setTo(\Yii::$app->parameterBag->get('adminEmail'))
->setFrom([\Yii::$app->parameterBag->get('adminEmail') => 'Opendistrib'])
->setSubject('[Opendistrib] Nouveau producteur')
->send();
}

+ 27
- 9
common/logic/Product/Product/Repository/ProductRepository.php Ver arquivo

@@ -66,19 +66,37 @@ class ProductRepository extends AbstractRepository
return $this->createDefaultQuery()->count();
}

public function queryProductsByDistribution(Distribution $distribution)
{
return $this->createDefaultQuery()
->joinWith([
'productDistribution' => function ($query) use ($distribution) {
$query->andOnCondition(
'product_distribution.id_distribution = ' . $distribution->id
);
}
])
->orderBy('product_distribution.active DESC, product.order ASC');
}

/**
* Retourne les produits d'une production donnée.
*/
public function findProductsByDistribution(Distribution $distribution)
{
$productArray = $this->createDefaultQuery()
->leftJoin('product_distribution', 'product.id = product_distribution.id_product')
->filterByDistribution($distribution)
->orderBy('product_distribution.active DESC, product.order ASC')
->find();
$productArray = $this->queryProductsByDistribution($distribution)->find();
return $this->buildProductsArrayById($productArray);
}

public function findProductsByDistributionAsArray(Distribution $distribution)
{
return $this->queryProductsByDistribution($distribution)->asArray()->find();
}

public function buildProductsArrayById(array $productsArray): array
{
$productArrayById = [];
foreach($productArray as $product) {
foreach($productsArray as $product) {
$productArrayById[$product->id] = $product;
}

@@ -123,7 +141,7 @@ class ProductRepository extends AbstractRepository
'user_producer' => $userProducer,
'point_sale' => $pointSale,
'quantity' => $specificPrice->from_quantity
]), 3),
]), 5),
'price_with_tax' => number_format($this->productSolver->getPriceWithTax($product, [
'user' => $user,
'user_producer' => $userProducer,
@@ -137,8 +155,8 @@ class ProductRepository extends AbstractRepository
// base price
$priceArray[] = [
'from_quantity' => 0,
'price' => $this->productSolver->getPrice($product),
'price_with_tax' => $this->productSolver->getPriceWithTax($product),
'price' => number_format($this->productSolver->getPrice($product), 5),
'price_with_tax' => number_format($this->productSolver->getPriceWithTax($product), 2),
];
}


+ 26
- 0
common/logic/Product/Product/Service/ProductSolver.php Ver arquivo

@@ -243,4 +243,30 @@ class ProductSolver extends AbstractService implements SolverInterface

return $productArrayFilter;
}

public function getProductDistributionPotentialRevenues(array $productsArray)
{
$potentialRevenues = 0;

foreach($productsArray as $product) {
if ($product['productDistribution'][0]['active'] && $product['productDistribution'][0]['quantity_max']) {
$potentialRevenues += $product['productDistribution'][0]['quantity_max'] * $product['price'];
}
}

return $potentialRevenues;
}

public function getProductDistributionPotentialWeight(array $productsArray)
{
$potentialWeight = 0;

foreach($productsArray as $product) {
if ($product['productDistribution'][0]['active'] && $product['productDistribution'][0]['quantity_max']) {
$potentialWeight += $product['productDistribution'][0]['quantity_max'] * $product['weight'] / 1000;
}
}

return $potentialWeight;
}
}

+ 1
- 1
common/logic/User/User/Repository/UserRepository.php Ver arquivo

@@ -163,7 +163,7 @@ class UserRepository extends AbstractRepository
{
return $this->queryUsersBy()
->andWhere('user_producer.credit < 0')
->orderBy('credit ASC');
->orderBy('lastname, name ASC');
}

public function findUsersWithNegativeCredit()

+ 1
- 1
common/logic/User/User/Service/UserSolver.php Ver arquivo

@@ -99,7 +99,7 @@ class UserSolver extends AbstractService implements SolverInterface
if (empty($token)) {
return false;
}
$expire = \Yii::$app->params['user.passwordResetTokenExpire'];
$expire = \Yii::$app->parameterBag->get('user.passwordResetTokenExpire');
$parts = explode('_', $token);
$timestamp = (int)end($parts);
return $timestamp + $expire >= time();

+ 23
- 31
common/logic/User/User/Service/UserUtils.php Ver arquivo

@@ -21,19 +21,15 @@ class UserUtils extends AbstractService implements UtilsInterface

public function sendEmailSignup(User $user, Producer $producer)
{
Mailjet::sendMail([
'from_email' => \Yii::$app->params['adminEmail'],
'from_name' => 'Opendistrib',
'to_email' => $user->email,
'to_name' => $this->userSolver->getUsername($user),
'subject' => '[Opendistrib] Inscription',
'content_view_text' => '@common/mail/signup-text.php',
'content_view_html' => '@common/mail/signup-html.php',
'content_params' => [
\Yii::$app->mailerService->sendFromSite(
'Inscription',
'signup',
[
'user' => $user,
'producer' => $producer
]
]);
],
$user->email
);
}

/**
@@ -44,32 +40,28 @@ class UserUtils extends AbstractService implements UtilsInterface
{
if (strlen($user->email)) {
$producer = Producer::findOne(GlobalParam::getCurrentProducerId());
\Yii::$app->mailer->compose();
$mail = \Yii::$app->mailer->compose(
['html' => 'createUserAdmin-html', 'text' => 'createUserAdmin-text'], ['user' => $user, 'producer' => $producer, 'password' => $password]
)
->setTo($user->email)
->setFrom(['contact@opendistrib.net' => 'distrib'])
->setSubject('[Opendistrib] Inscription')
->send();
\Yii::$app->mailerService->sendFromProducer(
'Inscription',
'createUserAdmin',
[
'user' => $user,
'producer' => $producer,
'password' => $password
],
$user->email,
$producer
);
}
}

public function sendMailNewTicketAdmin(Ticket $ticket)
{
$adminEmail = \Yii::$app->params['adminEmail'];

Mailjet::sendMail([
'from_email' => $adminEmail,
'from_name' => 'Opendistrib',
'to_email' => $adminEmail,
'to_name' => 'Opendistrib',
'subject' => '[Opendistrib] Nouveau ticket',
'content_view_text' => '@common/mail/newTicketAdmin-text.php',
'content_view_html' => '@common/mail/newTicketAdmin-html.php',
'content_params' => [
\Yii::$app->mailerService->sendAdmin(
'Nouveau ticket',
'newTicketAdmin',
[
'ticket' => $ticket,
]
]);
);
}
}

+ 2
- 2
common/mail/signup-html.php Ver arquivo

@@ -50,7 +50,7 @@ use common\logic\User\User\Model\User;

<?php if($user->status == User::STATUS_PRODUCER): ?>
<p>Vous pouvez dès maintenant vous connecter à l'<a href="<?= Yii::$app->urlManagerBackend->createAbsoluteUrl(['site/index']); ?>">administration</a> pour configurer votre compte producteur.</p>
<p>Si vous avez des questions ou si vous avez besoin d'être accompagné lors de cette étape, n'hésitez pas à me contacter en réponse à ce mail ou directement au <strong><?= Yii::$app->params['adminPhoneNumber'] ?></strong>.</p>
<p>Si vous avez des questions ou si vous avez besoin d'être accompagné lors de cette étape, n'hésitez pas à me contacter en réponse à ce mail ou directement au <strong><?= Yii::$app->parameterBag->get('adminPhoneNumber') ?></strong>.</p>
<?php else: ?>
<?php if(!is_null($producer)): ?>
<p>Vous pouvez maintenant <a href="<?= Yii::$app->urlManagerProducer->createAbsoluteUrl(['site/index', 'slug_producer' => $producer->slug]); ?>">passer commande</a> chez votre producteur <strong><?= Html::encode($producer->name); ?></strong>.</p>
@@ -60,4 +60,4 @@ use common\logic\User\User\Model\User;
<?php endif; ?>

<p>À bientôt,<br />
<?= Yii::$app->params['adminFirstname'] ?></p>
<?= Yii::$app->parameterBag->get('adminFirstname') ?></p>

+ 2
- 2
common/mail/signup-text.php Ver arquivo

@@ -51,7 +51,7 @@ Voici votre identifiant de connexion :
Vous pouvez dès maintenant vous connecter à l'administration pour configurer votre compte :
<?= Yii::$app->urlManagerBackend->createAbsoluteUrl(['site/index']); ?>

Si vous avez des questions ou si vous avez besoin d'être accompagné lors de cette étape, n'hésitez pas à me contacter en réponse à ce mail ou directement au <?= Yii::$app->params['adminPhoneNumber'] ?>.
Si vous avez des questions ou si vous avez besoin d'être accompagné lors de cette étape, n'hésitez pas à me contacter en réponse à ce mail ou directement au <?= Yii::$app->parameterBag->get('adminPhoneNumber'); ?>.
<?= Yii::$app->urlManagerBackend->createAbsoluteUrl(['site/index']); ?>
<?php else: ?>
<?php if(!is_null($producer)): ?>
@@ -63,4 +63,4 @@ Vous pouvez maintenant passer commande chez votre producteur.
<?php endif; ?>

À bientôt,
<?= Yii::$app->params['adminFirstname'] ?>
<?= Yii::$app->parameterBag->get('adminFirstname') ?>

+ 24
- 22
common/versions/22.10.A.php Ver arquivo

@@ -5,29 +5,31 @@ require_once dirname(__FILE__).'/_macros.php';
version(
'25/10/2022',
[
"[Administration] Distributions > commandes : ajout ligne avec montant total et poids par point de vente",
"[Administration] Distributions > formulaire commande : ajout champs prix HT",
"[Administration] Produits, Utilisateurs, Statistiques et Documents : accès rapide en un clic",
"[Administration] Produits > liste : possibilité de modifier directement le champs 'actif'",
"[Administration] Utilisateurs > commandes : ajout lien vers modification",
"[Administration] Documents > modification : mise en évidence des prix incohérents par rapport à ceux définis au niveau des produits",
"[Administration] Documents > liste : ajout champs 'Envoyé'",
"[Administration] Documents > factures > liste : filtre par utilisateur",
"[Administration] Paramètres : tri et réagencement",
"[Administration] Développement : page de suivi des versions du logiciel (liste des évolutions et correctifs)",
"[Espace producteur] Formulaire de contact avec protection par captcha"
],
[
[
"[Administration] Distributions > commandes : ajout ligne avec montant total et poids par point de vente",
"[Administration] Distributions > formulaire commande : ajout champs prix HT",
"[Administration] Produits, Utilisateurs, Statistiques et Documents : accès rapide en un clic",
"[Administration] Produits > liste : possibilité de modifier directement le champs 'actif'",
"[Administration] Utilisateurs > commandes : ajout lien vers modification",
"[Administration] Documents > modification : mise en évidence des prix incohérents par rapport à ceux définis au niveau des produits",
"[Administration] Documents > liste : ajout champs 'Envoyé'",
"[Administration] Documents > factures > liste : filtre par utilisateur",
"[Administration] Paramètres : tri et réagencement",
"[Administration] Développement : page de suivi des versions du logiciel (liste des évolutions et correctifs)",
"[Espace producteur] Formulaire de contact avec protection par captcha"
],
[
"[Administration] Produits > modification : prise en compte des prix spécifiques lors de la mise à jour automatique des commandes des distributions futures",
"[Administration] Produits > prix spécifiques : prise en compte des prix par groupe d'utilisateur et point de vente",
"[Administration] Utilisateurs > crédit : correctif champs 'Commentaire' trop long",
"[Administration] Utilisateurs > liste : correctif nombre de commandes",
"[Administration] Distributions > modification commande : correctif modification prix",
"[Administration] Distributions > modification commande : adaptation changement du point de vente lors de la sélection d'un utilisateur",
"[Administration] Haut de page : utilisateurs vides dans le bloc 'Utilisateurs au crédit négatif'",
"[Administration] Abonnements : ne pas générer de commandes pour le jour même",
"[Backend] Facture > créer : tri des utilisateurs par ordre alphabétique",
"Correctif connexion personnes morales"
"[Administration] Produits > prix spécifiques : prise en compte des prix par groupe d'utilisateur et point de vente",
"[Administration] Utilisateurs > crédit : correctif champs 'Commentaire' trop long",
"[Administration] Utilisateurs > liste : correctif nombre de commandes",
"[Administration] Distributions > modification commande : correctif modification prix",
"[Administration] Distributions > modification commande : adaptation changement du point de vente lors de la sélection d'un utilisateur",
"[Administration] Haut de page : utilisateurs vides dans le bloc 'Utilisateurs au crédit négatif'",
"[Administration] Abonnements : ne pas générer de commandes pour le jour même",
"[Backend] Facture > créer : tri des utilisateurs par ordre alphabétique",
"Correctif connexion personnes morales"
]
]
);


+ 8
- 6
common/versions/22.11.A.php Ver arquivo

@@ -5,12 +5,14 @@ require_once dirname(__FILE__) . '/_macros.php';
version(
'08/11/2022',
[
"[Administration] Documents > édition : liens vers les commandes associées",
"[Administration] Distributions > édition commande : bouton de réinitialisation des prix facturés"
],
[
"[Administration] Abonnements : suppression des commandes après la date de fin lors de l'arrêt d'un abonnement",
"[Administration] Distributions > calendrier : amélioration chargement automatique des distributions (affichage pastilles vertes)"
[
"[Administration] Documents > édition : liens vers les commandes associées",
"[Administration] Distributions > édition commande : bouton de réinitialisation des prix facturés"
],
[
"[Administration] Abonnements : suppression des commandes après la date de fin lors de l'arrêt d'un abonnement",
"[Administration] Distributions > calendrier : amélioration chargement automatique des distributions (affichage pastilles vertes)"
]
]
);


+ 9
- 7
common/versions/22.11.B.php Ver arquivo

@@ -5,13 +5,15 @@ require_once dirname(__FILE__) . '/_macros.php';
version(
'22/11/2022',
[
"[Administration] Documents > factures : gestion des bons de livraison associés",
"[Administration] Communiquer : possibilité de ne pas inclure la liste des produits dans le message",
"[Administration] Paramètres : possibilité de configurer le séparateur CSV",
"[Administration] Paramètres > paiement en ligne : montant minimum configurable",
"[Administration] Développement : mise en avant des nouvelles versions et des informations de contact"
],
[]
[
"[Administration] Documents > factures : gestion des bons de livraison associés",
"[Administration] Communiquer : possibilité de ne pas inclure la liste des produits dans le message",
"[Administration] Paramètres : possibilité de configurer le séparateur CSV",
"[Administration] Paramètres > paiement en ligne : montant minimum configurable",
"[Administration] Développement : mise en avant des nouvelles versions et des informations de contact"
],
[]
]
);

?>

+ 6
- 4
common/versions/22.12.A.php Ver arquivo

@@ -5,10 +5,12 @@ require_once dirname(__FILE__) . '/_macros.php';
version(
'06/12/2022',
[
"[Administration] Listes d'utilisateurs : ordre alphabétique + champs de recherche rapide (commandes, abonnements, documents, points de vente)",
"[Administration] Abonnements : comportement paiement automatique (déduit, oui, non)"
],
[]
[
"[Administration] Listes d'utilisateurs : ordre alphabétique + champs de recherche rapide (commandes, abonnements, documents, points de vente)",
"[Administration] Abonnements : comportement paiement automatique (déduit, oui, non)"
],
[]
]
);

?>

+ 7
- 5
common/versions/23.1.A.php Ver arquivo

@@ -5,11 +5,13 @@ require_once dirname(__FILE__) . '/_macros.php';
version(
'23/01/2023',
[
"[Administration] Documents : possibilité de regénérer les PDF"
],
[
"[Administration] Documents > listes : optimisation chargement",
"[Espace producteur] Commander : ajustement ordre des points de vente"
[
"[Administration] Documents : possibilité de regénérer les PDF"
],
[
"[Administration] Documents > listes : optimisation chargement",
"[Espace producteur] Commander : ajustement ordre des points de vente"
]
]
);


+ 7
- 5
common/versions/23.3.A.php Ver arquivo

@@ -5,13 +5,15 @@ require_once dirname(__FILE__) . '/_macros.php';
version(
'27/03/2023',
[
"[Administration] Distributions > édition/création commande : bouton unique 'Créer' ou 'Modifier'.
[
"[Administration] Distributions > édition/création commande : bouton unique 'Créer' ou 'Modifier'.
La gestion du crédit est désormais automatiquement déduite du contexte (utilisateur, point de vente).",
"[Administration] Paramètres : ajout d'une option pour configurer le libellé 'Points de vente' affiché sur l'accueil
"[Administration] Paramètres : ajout d'une option pour configurer le libellé 'Points de vente' affiché sur l'accueil
et le tunnel de commande de l'espace producteur.",
"[Administration] Export vers le logiciel Evoliz : ajout de la TVA + code classification vente"
],
[]
"[Administration] Export vers le logiciel Evoliz : ajout de la TVA + code classification vente"
],
[]
]
);

?>

+ 7
- 5
common/versions/23.4.A.php Ver arquivo

@@ -5,11 +5,13 @@ require_once dirname(__FILE__) . '/_macros.php';
version(
'27/04/2023',
[
"[Administration] Distributions > édition commande : possibilité de modifier les prix facturés",
"[Administration] Produits > import prix : possibilité d'importer des prix sur base d'un fichier CSV"
],
[
"Logiciel de caisse Tiller : synchronisation des commandes partiellement payées"
[
"[Administration] Distributions > édition commande : possibilité de modifier les prix facturés",
"[Administration] Produits > import prix : possibilité d'importer des prix sur base d'un fichier CSV"
],
[
"Logiciel de caisse Tiller : synchronisation des commandes partiellement payées"
]
]
);


+ 10
- 8
common/versions/23.6.A.php Ver arquivo

@@ -4,15 +4,17 @@ require_once dirname(__FILE__) . '/_macros.php';

version(
'12/06/2023',
[],
[
"[Administration] Logiciel de caisse Tiller : synchroniser automatiquement les commandes payées avec le crédit",
"[Administration] Correction affichage des points de vente supprimés",
"[Administration] Distribution > ajout commande : gestion de 5 chiffres après la virgule pour les prix HT",
"[Administration] Produits > liste : amélioration responsive",
"[Espace producteur] Produits : mise en évidence des noms de produit",
"[Site] Profil utilisateur : permettre édition adresse email"
],
[],
[
"[Administration] Logiciel de caisse Tiller : synchroniser automatiquement les commandes payées avec le crédit",
"[Administration] Correction affichage des points de vente supprimés",
"[Administration] Distribution > ajout commande : gestion de 5 chiffres après la virgule pour les prix HT",
"[Administration] Produits > liste : amélioration responsive",
"[Espace producteur] Produits : mise en évidence des noms de produit",
"[Site] Profil utilisateur : permettre édition adresse email"
],
]
);

?>

+ 16
- 14
common/versions/23.6.B.php Ver arquivo

@@ -5,20 +5,22 @@ require_once dirname(__FILE__) . '/_macros.php';
version(
'22/06/2023',
[
"[Administration et Espace producteur] Calendrier pour le choix du jour de distribution : affichage du lundi en premier",
"[Administration] Distribution : alerte remboursement commandes lors de la désactivation d'une distribution",
"[Administration] Distribution > édition commande : alerte si quantité max d'un produit dépassée",
"[Administration] Distributions > liste commandes : ajout lien vers fiche client (crédit, profil, commandes)",
"[Administration] Documents > Bons de livraison : alerte suppression produits",
"[Administration] Distributions > formulaire commande : raccourci 'Entrée' pour passer à la ligne du dessous",
"[Administration] Utilisateur > édition : ajout info contact facturation",
"[Administration] Responsive > listes : accès facilité aux boutons d'action",
"[Espace producteur] Accueil : gestion visibilité produits présents uniquement sur un point de vente à accès restreint",
"[Espace producteur] Commande > choix du point de vente : ajout informations en fonction du jour choisi"
],
[
"[Espace producteur] Abonnements : correctif disponibilité produits par point de vente",
"Abonnements > ajout/modification : prise en compte des contraintes de délai et d'heure limite de commande dans la génération des commandes des distributions à venir"
[
"[Administration et Espace producteur] Calendrier pour le choix du jour de distribution : affichage du lundi en premier",
"[Administration] Distribution : alerte remboursement commandes lors de la désactivation d'une distribution",
"[Administration] Distribution > édition commande : alerte si quantité max d'un produit dépassée",
"[Administration] Distributions > liste commandes : ajout lien vers fiche client (crédit, profil, commandes)",
"[Administration] Documents > Bons de livraison : alerte suppression produits",
"[Administration] Distributions > formulaire commande : raccourci 'Entrée' pour passer à la ligne du dessous",
"[Administration] Utilisateur > édition : ajout info contact facturation",
"[Administration] Responsive > listes : accès facilité aux boutons d'action",
"[Espace producteur] Accueil : gestion visibilité produits présents uniquement sur un point de vente à accès restreint",
"[Espace producteur] Commande > choix du point de vente : ajout informations en fonction du jour choisi"
],
[
"[Espace producteur] Abonnements : correctif disponibilité produits par point de vente",
"Abonnements > ajout/modification : prise en compte des contraintes de délai et d'heure limite de commande dans la génération des commandes des distributions à venir"
]
]
);


+ 6
- 4
common/versions/23.7.A.php Ver arquivo

@@ -4,11 +4,13 @@ require_once dirname(__FILE__) . '/_macros.php';

version(
'03/07/2023',
[],
[
'[Administration] Calendrier : couleur du jour sélectionné plus prononcée',
'[Administration] Distributions > Produits : possibilité de définir une quantité maximum à 0',
'[Technique] Réécriture requêtes bases de données'
[],
[
'[Administration] Calendrier : couleur du jour sélectionné plus prononcée',
'[Administration] Distributions > Produits : possibilité de définir une quantité maximum à 0',
'[Technique] Réécriture requêtes bases de données'
]
]
);


+ 7
- 5
common/versions/23.8.A.php Ver arquivo

@@ -5,12 +5,14 @@ require_once dirname(__FILE__).'/_macros.php';
version(
'17/08/2023',
[
[
'[Administration] Système de support',
'[Site] Évolution du contenu et mise en page : carte et liste des producteurs, à propos, fonctionnalités, code source.',
'[Site] Lien "Je demande une démo"',
'[Site & espace producteur] Barre de navigation en haut du site'
],
[]
'[Site] Évolution du contenu et mise en page : carte et liste des producteurs, à propos, fonctionnalités, code source.',
'[Site] Lien "Je demande une démo"',
'[Site & espace producteur] Barre de navigation en haut du site'
],
[]
]
);

?>

+ 10
- 8
common/versions/23.8.B.php Ver arquivo

@@ -5,15 +5,17 @@ require_once dirname(__FILE__).'/_macros.php';
version(
'28/08/2023',
[
"[Administration] Utilisateurs : page crédit (somme totale en crédit, liste des clients à relancer, exports CSV)",
"[Administration et espace producteur] Témoignages producteurs : possibilité de saisir un témoignage sur l'utilisation du logiciel dans 'Paramètres > Opendistrib' puis affichage des témoignages sur la page 'À propos'.",
"[Administration] Utilisateur : retour à la liste après modification",
'[Espace producteur] Produits : lien "En savoir plus" pour afficher la description longue',
"[Espace producteur] Commande : affichage d'un message s'il n'y a aucune distributions à venir",
[
"[Administration] Utilisateurs : page crédit (somme totale en crédit, liste des clients à relancer, exports CSV)",
"[Administration et espace producteur] Témoignages producteurs : possibilité de saisir un témoignage sur l'utilisation du logiciel dans 'Paramètres > Opendistrib' puis affichage des témoignages sur la page 'À propos'.",
"[Administration] Utilisateur : retour à la liste après modification",
'[Espace producteur] Produits : lien "En savoir plus" pour afficher la description longue',
"[Espace producteur] Commande : affichage d'un message s'il n'y a aucune distributions à venir",
],
[
"[Administration et espace producteur] Produits : optimisation de l'affichage des images"
]
],
[
"[Administration et espace producteur] Produits : optimisation de l'affichage des images"
]
);

?>

+ 27
- 0
common/versions/23.9.A.php Ver arquivo

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

require_once dirname(__FILE__).'/_macros.php';

version(
'04/09/2023',
[
[
"[Administration] Documents : pouvoir ajouter des informations supplémentaires en dessous de l'adresse",
],
[
"[Administration] Utilisateurs au crédit négatif : tri par ordre alphabétique"
]
],
[
[
"[Administration] Développement : gestion des features et maintenances visibles uniquement aux admin"
],
[
"[Technique] Mise en place d'un Mailer générique",
"[Technique] Administration : refactoring DistributionController",
"[Technique] ParameterBag : service dédié à la récupération des paramètres système"
]
],
);

?>

+ 22
- 8
common/versions/_macros.php Ver arquivo

@@ -1,41 +1,55 @@
<?php

function version(string $date, array $featuresArray, array $maintenanceArray) {
use common\logic\User\User\Wrapper\UserManager;

function version(string $date, array $featuresMaintenanceArray, array $featuresMaintenanceAdminArray = []) {
release_date($date);
features($featuresArray);
maintenance($maintenanceArray);
features($featuresMaintenanceArray[0] ?? [], $featuresMaintenanceAdminArray[0] ?? []);
maintenance($featuresMaintenanceArray[1] ?? [], $featuresMaintenanceAdminArray[1] ?? []);
}

function release_date(string $date) {
$html = '<div class="block">';
$html = '<div class="block block-release-date">';
$html .= '<h4><span class="glyphicon glyphicon-calendar"></span> Date de sortie</h4>';
$html .= '<ul><li>'.$date.'</li></ul>';
$html .= '</div>';
echo $html;
}

function features(array $featuresArray) {
function features(array $featuresArray, array $featuresAdminArray) {
$userManager = UserManager::getInstance();
if(count($featuresArray) > 0) {
$html = '<div class="block">';
$html = '<div class="block block-features">';
$html .= '<h4><span class="glyphicon glyphicon-flash"></span> Évolutions</h4>';
$html .= '<ul>';
foreach($featuresArray as $feature) {
$html .= '<li>'.$feature.'</li>';
}
if($userManager->isCurrentAdmin()) {
foreach($featuresAdminArray as $feature) {
$html .= '<li class="admin">'.$feature.'</li>';
}
}
$html .= '</ul>';
$html .= '</div>';
echo $html;
}
}

function maintenance(array $maintenanceArray) {
function maintenance(array $maintenanceArray, array $maintenanceAdminArray) {
$userManager = UserManager::getInstance();
if(count($maintenanceArray) > 0) {
$html = '<div class="block">';
$html = '<div class="block block-maintenance">';
$html .= '<h4><span class="glyphicon glyphicon-wrench"></span> Maintenance</h4>';
$html .= '<ul>';
foreach($maintenanceArray as $maintenance) {
$html .= '<li>'.$maintenance.'</li>';
}
if($userManager->isCurrentAdmin()) {
foreach ($maintenanceAdminArray as $maintenance) {
$html .= '<li class="admin">' . $maintenance . '</li>';
}
}
$html .= '</ul>';
$html .= '</div>';
echo $html;

+ 2
- 2
common/views/matomo.php Ver arquivo

@@ -5,9 +5,9 @@
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="//<?= Yii::$app->params['matomoUrl']; ?>/";
var u="//<?= Yii::$app->parameterBag->get('matomoUrl'); ?>/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '<?= Yii::$app->params['matomoIdSite']; ?>']);
_paq.push(['setSiteId', '<?= Yii::$app->parameterBag->get('matomoIdSite'); ?>']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();

+ 2
- 1
composer.json Ver arquivo

@@ -33,7 +33,8 @@
"stripe/stripe-php": "^7.95",
"loveorigami/yii2-bootstrap-toggle": "*",
"justcoded/yii2-event-listener": "*",
"ext-pdo": "*"
"ext-pdo": "*",
"weluse/yii2-mailjet": "^0.2.0"
},
"require-dev": {
"yiisoft/yii2-codeception": "*",

+ 35
- 1
composer.lock Ver arquivo

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "7da17be4685def1e9635cc5ab5e5a7d9",
"content-hash": "cf81ea895f037844a4e20f4780fd7e7e",
"packages": [
{
"name": "2amigos/yii2-chartjs-widget",
@@ -2464,6 +2464,40 @@
],
"time": "2022-11-03T14:55:06+00:00"
},
{
"name": "weluse/yii2-mailjet",
"version": "v0.2.0",
"source": {
"type": "git",
"url": "https://github.com/weluse/yii2-mailjet.git",
"reference": "ec68afa94a5f9cef2b1ed6197b733b7a9fa8f601"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/weluse/yii2-mailjet/zipball/ec68afa94a5f9cef2b1ed6197b733b7a9fa8f601",
"reference": "ec68afa94a5f9cef2b1ed6197b733b7a9fa8f601",
"shasum": ""
},
"require": {
"mailjet/mailjet-apiv3-php": "^1.1.5"
},
"type": "library",
"autoload": {
"psr-4": {
"weluse\\mailjet\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Mailjet client",
"support": {
"issues": "https://github.com/weluse/yii2-mailjet/issues",
"source": "https://github.com/weluse/yii2-mailjet/tree/v0.2.0"
},
"time": "2019-06-19T21:18:00+00:00"
},
{
"name": "yidas/yii2-bower-asset",
"version": "2.0.13.1",

+ 26
- 0
console/migrations/m230829_081058_add_column_producer_option_document_infos_top.php Ver arquivo

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

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

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

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

+ 2
- 2
frontend/controllers/SiteController.php Ver arquivo

@@ -183,7 +183,7 @@ class SiteController extends FrontendController
$countUsersActive = $userManager->countUsersActiveLastThreeMonths();
$averageOrdersPerDay = $orderManager->countGlobalUserOrdersAverageLastSevenDays();
$averageTurnover = $orderManager->getAverageTurnoverLastThreeMonths();
$resultMatomoApiVisitSummary = json_decode(file_get_contents(Yii::$app->params['matomoApiVisitSummaryUrl']));
$resultMatomoApiVisitSummary = json_decode(file_get_contents(Yii::$app->parameterBag->get('matomoApiVisitSummaryUrl')));
$numberVisitsMonth = $resultMatomoApiVisitSummary->nb_uniq_visitors;

return $this->renderPartial('_about_few_numbers', [
@@ -296,7 +296,7 @@ class SiteController extends FrontendController
$model = new ContactForm();

if ($model->load(Yii::$app->request->post()) && $model->validate()) {
if ($model->sendEmail(Yii::$app->params['adminEmail'])) {
if ($model->sendEmail(Yii::$app->parameterBag->get('adminEmail'))) {
$this->setFlash('success', 'Votre message a bien été envoyé. Nous vous répondrons dès que possible.');
}
else {

+ 1
- 1
frontend/views/site/index.php Ver arquivo

@@ -69,7 +69,7 @@ $this->setMeta('description', 'Simplifiez la distribution de vos produits en cir
<span class="glyphicon glyphicon-plus-sign"></span> En savoir plus
</a>
<?php if (Yii::$app->user->isGuest): ?><br /><?php endif; ?>
<a class="btn btn-default" href="<?= \Yii::$app->params['appointmentUrl']; ?>" target="_blank">
<a class="btn btn-default" href="<?= \Yii::$app->parameterBag->get('appointmentUrl'); ?>" target="_blank">
<span class="glyphicon glyphicon-education"></span> Je demande une démo
</a>
<?php if (Yii::$app->user->isGuest): ?>

+ 1
- 1
frontend/views/site/service.php Ver arquivo

@@ -161,7 +161,7 @@ $this->setIcon('console');
href="<?= $this->getUrlManagerFrontend()->createUrl(['site/producer', 'id' => 32]); ?>">
<span class="glyphicon glyphicon-check"></span> Je teste le logiciel
</a>
<a class="btn btn-default" href="<?= \Yii::$app->params['appointmentUrl']; ?>"
<a class="btn btn-default" href="<?= \Yii::$app->parameterBag->get('appointmentUrl'); ?>"
target="_blank">
<span class="glyphicon glyphicon-education"></span> Je demande une démo
</a>

+ 39
- 56
producer/controllers/CreditController.php Ver arquivo

@@ -241,58 +241,48 @@ class CreditController extends ProducerBaseController

$creditHistoryManager->payOrder($order, $user, true);


// client : envoi d'un email de confirmation de paiement
$paramsEmail = [
'from_email' => $producerManager->getEmailOpendistrib($producer),
'from_name' => $producer->name,
'to_email' => $user->email,
'to_name' => $userManager->getUsername($user),
'subject' => '[' . $producer->name . '] Confirmation de paiement',
'content_view_text' => '@common/mail/paymentOrderConfirm-text.php',
'content_view_html' => '@common/mail/paymentOrderConfirm-html.php',
'content_params' => [
/*\Yii::$app->mailerService->sendFromProducer(
'Confirmation de commande',
'paymentOrderConfirm',
[
'amount' => $amount,
'user' => $user,
'producer' => $producer,
]
];
//Mailjet::sendMail($paramsEmail);
],
$user->email,
$producer
);*/

// producteur : mail de confirmation
Mailjet::sendMail([
'from_email' => $producerManager->getEmailOpendistrib($producer),
'from_name' => $producer->name,
'to_email' => $contactProducer->email,
'to_name' => $contactProducer->name,
'subject' => '[' . $producer->name . '] Confirmation de commande',
'content_view_text' => '@common/mail/orderConfirmProducer-text.php',
'content_view_html' => '@common/mail/orderConfirmProducer-html.php',
'content_params' => [
\Yii::$app->mailerService->sendFromSite(
'Confirmation de commande',
'orderConfirmProducer',
[
'order' => $order,
'pointSale' => $pointSale,
'distribution' => $distribution,
'user' => $user,
'producer' => $producer
]
]);
],
$contactProducer->email
);
} else {
$userProducer = $this->getUserProducerManager()->findOneUserProducer($user);

Mailjet::sendMail([
'from_email' => $producerManager->getEmailOpendistrib($producer),
'from_name' => $producer->name,
'to_email' => $user->email,
'to_name' => $userManager->getUsername($user),
'subject' => '[' . $producer->name . '] Alimentation de votre crédit',
'content_view_text' => '@common/mail/creditConfirm-text.php',
'content_view_html' => '@common/mail/creditConfirm-html.php',
'content_params' => [
\Yii::$app->mailerService->sendFromProducer(
'Alimentation de votre crédit',
'creditConfirm',
[
'user' => $user,
'userProducer' => $userProducer,
'producer' => $producer,
'amount' => $amount,
]
]);
],
$user->email,
$producer
);
}
}

@@ -301,39 +291,32 @@ class CreditController extends ProducerBaseController
case 'charge.failed':

// client
Mailjet::sendMail([
'from_email' => $producerManager->getEmailOpendistrib($producer),
'from_name' => $producer->name,
'to_email' => $user->email,
'to_name' => $userManager->getUsername($user),
'subject' => '[' . $producer->name . '] Erreur de paiement',
'content_view_text' => '@common/mail/paymentError-text.php',
'content_view_html' => '@common/mail/paymentError-html.php',
'content_params' => [
\Yii::$app->mailerService->sendFromProducer(
'Erreur de paiement',
'paymentError',
[
'amount' => $amount,
'user' => $user,
'producer' => $producer,
]
]);
],
$user->email,
$producer
);

// producteur
if (isset($order) && $order) {
Mailjet::sendMail([
'from_email' => $producerManager->getEmailOpendistrib($producer),
'from_name' => $producer->name,
'to_email' => $contactProducer->email,
'to_name' => $contactProducer->name,
'subject' => '[' . $producer->name . '] Erreur de paiement',
'content_view_text' => '@common/mail/paymentErrorProducer-text.php',
'content_view_html' => '@common/mail/paymentErrorProducer-html.php',
'content_params' => [
\Yii::$app->mailerService->sendFromSite(
'Erreur de paiement',
'paymentErrorProducer',
[
'amount' => $amount,
'user' => $user,
'producer' => $producer,
'order' => $order,
'distribution' => $distribution
]
]);
],
$contactProducer->email,
);
}

break;

+ 23
- 21
producer/controllers/OrderController.php Ver arquivo

@@ -462,30 +462,30 @@ class OrderController extends ProducerBaseController
}
}

$paramsEmail = [
'from_email' => $producerManager->getEmailOpendistrib($producer),
'from_name' => $producer->name,
'to_email' => $user->email,
'to_name' => $userManager->getUsername($user),
'subject' => '[' . $producer->name . '] Confirmation de commande',
'content_view_text' => '@common/mail/orderConfirm-text.php',
'content_view_html' => '@common/mail/orderConfirm-html.php',
'content_params' => [
/*
* Envoi email de confirmation
*/
if ($isNewOrder) {

$emailSubject = 'Confirmation de commande';
$emailContentParams = [
'order' => $order,
'pointSale' => $pointSale,
'distribution' => $distribution,
'user' => $user,
'producer' => $producer
]
];
];

/*
* Envoi email de confirmation
*/
if ($isNewOrder) {
// au client
if ($producerManager->getConfig('option_email_confirm')) {
Mailjet::sendMail($paramsEmail);
\Yii::$app->mailerService->sendFromProducer(
$emailSubject,
'orderConfirm',
$emailContentParams,
$user->email,
$producer
);

}

// au producteur
@@ -493,11 +493,13 @@ class OrderController extends ProducerBaseController
if ($producerManager->getConfig('option_email_confirm_producer') && $contactProducer && strlen(
$contactProducer->email
)) {
$paramsEmail['to_email'] = $contactProducer->email;
$paramsEmail['to_name'] = $contactProducer->name;
$paramsEmail['content_view_text'] = '@common/mail/orderConfirmProducer-text.php';
$paramsEmail['content_view_html'] = '@common/mail/orderConfirmProducer-html.php';
Mailjet::sendMail($paramsEmail);

\Yii::$app->mailerService->sendFromSite(
$emailSubject,
'orderConfirmProducer',
$emailContentParams,
$contactProducer->email
);
}
}


+ 3
- 2
producer/views/order/order.php Ver arquivo

@@ -340,7 +340,8 @@ $this->setTitle('Commander');
{{ product.description }}
</div>
<div class="description-long" v-if="product.recipe.length">
<a href="javascript:void(0);" class="show-more-link">En savoir plus</a>
<a href="javascript:void(0);" class="show-more-link">En savoir
plus</a>
<div class="content">
{{ product.recipe }}
</div>
@@ -454,7 +455,7 @@ $this->setTitle('Commander');
</div>

<template
v-if="producer.credit == 1 && pointSaleActive.credit == 1 && pointSaleActive.credit_functioning == 'mandatory' && !checkCreditLimit(order) ">
v-if="producer.credit == 1 && pointSaleActive.credit == 1 && (pointSaleActive.credit_functioning == 'mandatory' || (pointSaleActive.credit_functioning == 'user' && user.credit_active)) && !checkCreditLimit(order) ">
<div class="alert alert-danger">
Vous devez
<template v-if="producer.online_payment == 1"><a

Carregando…
Cancelar
Salvar