@@ -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)); |
@@ -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(); | |||
} | |||
} | |||
@@ -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 |
@@ -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>.'); | |||
@@ -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 | |||
); | |||
} | |||
} | |||
} |
@@ -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> |
@@ -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> | |||
@@ -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): ?> |
@@ -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> | |||
@@ -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> |
@@ -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> |
@@ -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; | |||
} |
@@ -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,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; | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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'), |
@@ -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 [ | |||
] | |||
] | |||
]; |
@@ -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'); | |||
} |
@@ -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'); | |||
} | |||
/** |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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,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 | |||
{ |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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(); | |||
} | |||
@@ -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; | |||
} | |||
/** |
@@ -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', |
@@ -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'; |
@@ -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(); | |||
} |
@@ -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), | |||
]; | |||
} | |||
@@ -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; | |||
} | |||
} |
@@ -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() |
@@ -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(); |
@@ -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, | |||
] | |||
]); | |||
); | |||
} | |||
} |
@@ -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> |
@@ -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') ?> |
@@ -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" | |||
] | |||
] | |||
); | |||
@@ -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)" | |||
] | |||
] | |||
); | |||
@@ -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" | |||
], | |||
[] | |||
] | |||
); | |||
?> |
@@ -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)" | |||
], | |||
[] | |||
] | |||
); | |||
?> |
@@ -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" | |||
] | |||
] | |||
); | |||
@@ -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" | |||
], | |||
[] | |||
] | |||
); | |||
?> |
@@ -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" | |||
] | |||
] | |||
); | |||
@@ -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" | |||
], | |||
] | |||
); | |||
?> |
@@ -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" | |||
] | |||
] | |||
); | |||
@@ -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' | |||
] | |||
] | |||
); | |||
@@ -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' | |||
], | |||
[] | |||
] | |||
); | |||
?> |
@@ -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" | |||
] | |||
); | |||
?> |
@@ -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" | |||
] | |||
], | |||
); | |||
?> |
@@ -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; |
@@ -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); | |||
})(); |
@@ -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": "*", |
@@ -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", |
@@ -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'); | |||
} | |||
} |
@@ -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 { |
@@ -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): ?> |
@@ -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> |
@@ -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; |
@@ -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 | |||
); | |||
} | |||
} | |||
@@ -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 |