Browse Source

Merge branch 'develop'

master
Guillaume Bourgeois 1 year ago
parent
commit
827824a964
51 changed files with 509 additions and 223 deletions
  1. +7
    -6
      backend/controllers/DistributionController.php
  2. +3
    -2
      backend/controllers/DocumentController.php
  3. +22
    -49
      backend/controllers/ProducerController.php
  4. +48
    -34
      backend/controllers/ProductController.php
  5. +4
    -2
      backend/controllers/SubscriptionController.php
  6. +5
    -2
      backend/controllers/UserController.php
  7. +1
    -1
      backend/models/CreditForm.php
  8. +2
    -0
      backend/models/MailForm.php
  9. +10
    -10
      backend/views/distribution/index.php
  10. +2
    -2
      backend/views/document/_form.php
  11. +2
    -2
      backend/views/producer/update.php
  12. +2
    -2
      backend/views/product/_form.php
  13. +3
    -2
      backend/views/product/index.php
  14. +7
    -0
      backend/views/user/credit.php
  15. +5
    -3
      backend/web/css/screen.css
  16. +2
    -9
      backend/web/js/backend.js
  17. +19
    -5
      backend/web/js/vuejs/distribution-index.js
  18. +4
    -2
      backend/web/sass/_responsive.scss
  19. +1
    -1
      common/config/params.php
  20. +8
    -2
      common/forms/SubscriptionForm.php
  21. +1
    -1
      common/helpers/Opendistrib.php
  22. +4
    -2
      common/helpers/Upload.php
  23. +23
    -1
      common/logic/AbstractBuilder.php
  24. +12
    -2
      common/logic/AbstractRepository.php
  25. +23
    -0
      common/logic/AbstractRepositoryQuery.php
  26. +12
    -9
      common/logic/Distribution/Distribution/Service/DistributionBuilder.php
  27. +15
    -0
      common/logic/Distribution/ProductDistribution/Service/ProductDistributionBuilder.php
  28. +2
    -1
      common/logic/Document/Invoice/Service/InvoiceSolver.php
  29. +6
    -3
      common/logic/Order/Order/Repository/OrderRepository.php
  30. +1
    -0
      common/logic/Order/Order/Service/OrderBuilder.php
  31. +14
    -1
      common/logic/Payment/Model/Payment.php
  32. +6
    -6
      common/logic/Payment/Service/PaymentBuilder.php
  33. +22
    -16
      common/logic/Payment/Service/PaymentNotifier.php
  34. +14
    -7
      common/logic/Payment/Service/PaymentUtils.php
  35. +2
    -1
      common/logic/PointSale/PointSale/Repository/PointSaleRepositoryQuery.php
  36. +13
    -2
      common/logic/Producer/Producer/Model/Producer.php
  37. +52
    -0
      common/logic/Producer/Producer/Service/ProducerBuilder.php
  38. +13
    -8
      common/logic/Product/Product/Model/Product.php
  39. +6
    -6
      common/logic/Product/Product/Model/ProductSearch.php
  40. +8
    -8
      common/logic/Product/Product/Repository/ProductRepository.php
  41. +1
    -6
      common/logic/Product/Product/Repository/ProductRepositoryQuery.php
  42. +1
    -1
      common/logic/Product/Product/Service/ProductBuilder.php
  43. +8
    -3
      common/logic/Product/Product/Service/ProductSolver.php
  44. +10
    -0
      common/logic/StatusInterface.php
  45. +1
    -0
      common/logic/Subscription/Subscription/Service/SubscriptionBuilder.php
  46. +27
    -0
      common/versions/23.10.A.php
  47. +26
    -0
      console/migrations/m230929_065700_rename_column_product_active_status.php
  48. +26
    -0
      console/migrations/m231002_142915_add_column_payment_summary.php
  49. +1
    -1
      producer/controllers/OrderController.php
  50. +1
    -1
      producer/controllers/SiteController.php
  51. +1
    -1
      producer/web/js/vuejs/subscription-form.js

+ 7
- 6
backend/controllers/DistributionController.php View File

$orderManager = $this->getOrderManager(); $orderManager = $this->getOrderManager();
$productManager = $this->getProductManager(); $productManager = $this->getProductManager();
$userManager = $this->getUserManager(); $userManager = $this->getUserManager();
$pointSaleManager = $this->getPointSaleManager();


$producer = $this->getProducerCurrent(); $producer = $this->getProducerCurrent();
$format = 'Y-m-d'; $format = 'Y-m-d';
$distribution = $distributionManager->createDistributionIfNotExist($date); $distribution = $distributionManager->createDistributionIfNotExist($date);
$ordersArray = $orderManager->findOrdersByDistribution($distribution); $ordersArray = $orderManager->findOrdersByDistribution($distribution);
$ordersArrayObject = $ordersArray; $ordersArrayObject = $ordersArray;
$productsArray = $productManager->findProductsByDistribution($distribution);
$productsArray = $productManager->findProductsByDistribution($distribution, false);


$json['products'] = $this->buildAjaxInfosResponseProducts($distribution, $productsArray, $ordersArray); $json['products'] = $this->buildAjaxInfosResponseProducts($distribution, $productsArray, $ordersArray);
$json['distribution'] = $this->buildAjaxInfosResponseDistribution($distribution, $ordersArrayObject, $productsArray); $json['distribution'] = $this->buildAjaxInfosResponseDistribution($distribution, $ordersArrayObject, $productsArray);


if (!isset($product->productDistribution[0])) { if (!isset($product->productDistribution[0])) {
$productDistributionAdd = $distributionManager->addProduct($distribution, $product); $productDistributionAdd = $distributionManager->addProduct($distribution, $product);
$jsonProduct['productDistribution'][0] = $productDistributionAdd->getAttributes();
$product->populateRelation('productDistribution', [$productDistributionAdd]);
if($productDistributionAdd) {
$jsonProduct['productDistribution'][0] = $productDistributionAdd->getAttributes();
$product->populateRelation('productDistribution', [$productDistributionAdd]);
}
} }
else { else {
foreach($product->productDistribution as $key => $productDistribution) { foreach($product->productDistribution as $key => $productDistribution) {
} }
} }


if (!is_numeric($product->productDistribution[0]->quantity_max)) {
if (!isset($product->productDistribution[0]) || !is_numeric($product->productDistribution[0]->quantity_max)) {
$jsonProduct['quantity_remaining'] = null; $jsonProduct['quantity_remaining'] = null;
} else { } else {
$jsonProduct['quantity_remaining'] = $product->productDistribution[0]->quantity_max - $quantityOrder; $jsonProduct['quantity_remaining'] = $product->productDistribution[0]->quantity_max - $quantityOrder;
$oneProductUnactivated = false; $oneProductUnactivated = false;
foreach ($order->productOrder as $productOrder) { foreach ($order->productOrder as $productOrder) {
foreach ($productsArray as $product) { foreach ($productsArray as $product) {
if ($productOrder->id_product == $product['id'] && !$product['productDistribution'][0]['active']) {
if ($productOrder->id_product == $product['id'] && isset($product['productDistribution'][0]) && !$product['productDistribution'][0]['active']) {
$oneProductUnactivated = true; $oneProductUnactivated = true;
} }
} }

+ 3
- 2
backend/controllers/DocumentController.php View File

if($documentManager->isDocumentInvoice($document) && $documentManager->isStatusValid($document)) { if($documentManager->isDocumentInvoice($document) && $documentManager->isStatusValid($document)) {
$payment = $paymentManager->instanciatePayment( $payment = $paymentManager->instanciatePayment(
Payment::TYPE_PAYMENT, Payment::TYPE_PAYMENT,
number_format($documentManager->getAmountWithTax($document), 3),
number_format($documentManager->getAmountWithTax($document, Order::INVOICE_AMOUNT_TOTAL), 2),
$this->getProducerCurrent(), $this->getProducerCurrent(),
null, null,
null, null,
MeanPayment::TRANSFER, MeanPayment::TRANSFER,
null, null,
null,
$document $document
); );
$payment->amount = number_format($payment->amount, 2); $payment->amount = number_format($payment->amount, 2);


if ($document) { if ($document) {
$ordersArray = []; $ordersArray = [];
$productsArray = $productManager->findProducts();
$productsArray = $productManager->findProducts(false);


foreach ($document->orders as $order) { foreach ($document->orders as $order) {
$orderManager->initOrder($order); $orderManager->initOrder($order);

+ 22
- 49
backend/controllers/ProducerController.php View File

use yii\filters\VerbFilter; use yii\filters\VerbFilter;
use yii\filters\AccessControl; use yii\filters\AccessControl;
use common\helpers\Upload; use common\helpers\Upload;
use yii\web\UploadedFile;


/** /**
* UserController implements the CRUD actions for User model. * UserController implements the CRUD actions for User model.
*/ */
public function actionUpdate() public function actionUpdate()
{ {
$producerManager = $this->getProducerManager();
$producerContainer = $this->getProducerContainer();
$producerBuilder = $producerContainer->getBuilder();
$request = Yii::$app->request; $request = Yii::$app->request;
$model = $this->findModel(GlobalParam::getCurrentProducerId()); $model = $this->findModel(GlobalParam::getCurrentProducerId());

$logoFilenameOld = $model->logo; $logoFilenameOld = $model->logo;
$photoFilenameOld = $model->photo; $photoFilenameOld = $model->photo;
if (strlen($model->option_dashboard_date_start)) {
$model->option_dashboard_date_start = date('d/m/Y', strtotime($model->option_dashboard_date_start));
}
if (strlen($model->option_dashboard_date_end)) {
$model->option_dashboard_date_end = date('d/m/Y', strtotime($model->option_dashboard_date_end));
}
$producerBuilder->initOptionDashboardDatesDisplay($model);


if ($model->load(\Yii::$app->request->post()) && $model->save()) {
if ($model->load(\Yii::$app->request->post())) {


if (strlen($model->option_dashboard_date_start)) {
$model->option_dashboard_date_start = date(
'Y-m-d',
strtotime(str_replace('/', '-', $model->option_dashboard_date_start)
));
$model->save();
}

if (strlen($model->option_dashboard_date_end)) {
$model->option_dashboard_date_end = date(
'Y-m-d',
strtotime(str_replace('/', '-', $model->option_dashboard_date_end))
);
$model->save();
}
$model->logoFile = UploadedFile::getInstance($model, 'logoFile');
$model->photoFile = UploadedFile::getInstance($model, 'photoFile');


Upload::uploadFile($model, 'logo', $logoFilenameOld);
Upload::uploadFile($model, 'photo', $photoFilenameOld);
if($model->validate()) {


$deleteLogo = $request->post('delete_logo', 0);
if ($deleteLogo) {
$model->logo = '';
$producerBuilder->processUploadImage($model, 'logo', $logoFilenameOld, $request->post('delete_logo', 0));
$producerBuilder->processUploadImage($model, 'photo', $photoFilenameOld, $request->post('delete_photo', 0));
$producerBuilder->initOptionDashboardDatesBeforeSave($model);
$producerBuilder->savePrivateKeysStripe($model);
$model->save(); $model->save();
}


$deletePhoto = $request->post('delete_photo', 0);
if ($deletePhoto) {
$model->photo = '';
$model->save();
$this->setFlash('success', 'Paramètres mis à jour.');
return $this->redirect(['update', 'id' => $model->id, 'edit_ok' => true]);
} }
}


$producerManager->savePrivateKeyApiStripe($model);
$producerManager->savePrivateKeyEndpointStripe($model);

$model->option_stripe_private_key = '';
$model->option_stripe_endpoint_secret = '';
$model->save();

$this->setFlash('success', 'Paramètres mis à jour.');
return $this->redirect(['update', 'id' => $model->id, 'edit_ok' => true]);
} else {
if ($model->load(\Yii::$app->request->post())) {
$this->setFlash('error', 'Le formulaire comporte des erreurs.');
}
return $this->render('update', [
'model' => $model,
]);
if ($model->load(\Yii::$app->request->post())) {
$this->setFlash('error', 'Le formulaire comporte des erreurs.');
} }

return $this->render('update', [
'model' => $model,
]);
} }


/** /**

+ 48
- 34
backend/controllers/ProductController.php View File



$model = $productManager->instanciateProduct(); $model = $productManager->instanciateProduct();


$model->active = 1;
$model->status = Product::STATUS_ONLINE;
$model->id_producer = GlobalParam::getCurrentProducerId(); $model->id_producer = GlobalParam::getCurrentProducerId();
$model->monday = 1; $model->monday = 1;
$model->tuesday = 1; $model->tuesday = 1;
$model->sunday = 1; $model->sunday = 1;
$model->available_on_points_sale = 1; $model->available_on_points_sale = 1;


if ($model->load(\Yii::$app->request->post()) && $productManager->saveCreate($model)) {
if ($model->load(\Yii::$app->request->post())) {


$lastProductOrder = Product::find()->where('id_producer = :id_producer')->params([':id_producer' => GlobalParam::getCurrentProducerId()])->orderBy('order DESC')->one();
if ($lastProductOrder) {
$model->order = ++$lastProductOrder->order;
}
$model->photoFile = UploadedFile::getInstance($model, 'photoFile');
if($model->validate()) {


Upload::uploadFile($model, 'photo');
$productManager->saveUpdate($model);
$lastProductOrder = Product::find()->where('id_producer = :id_producer')->params([':id_producer' => GlobalParam::getCurrentProducerId()])->orderBy('order DESC')->one();
if ($lastProductOrder) {
$model->order = ++$lastProductOrder->order;
}
$productManager->create($model);


$this->processAvailabilityPointsSale($model);
$distributionManager->addProductIncomingDistributions($model);
if($model->photoFile) {
Upload::uploadFile($model, 'photoFile', 'photo');
}


$this->setFlash('success', 'Produit <strong>' . Html::encode($model->name) . '</strong> ajouté');
$this->processAvailabilityPointsSale($model);
$distributionManager->addProductIncomingDistributions($model);


return $this->redirect(['index']);
} else {
return $this->render('create', [
'model' => $model,
]);
$this->setFlash('success', 'Produit <strong>' . Html::encode($model->name) . '</strong> ajouté');

return $this->redirect(['index']);
}
} }

return $this->render('create', [
'model' => $model,
]);
} }


/** /**


$photoFilenameOld = $model->photo; $photoFilenameOld = $model->photo;


if ($model->load(\Yii::$app->request->post()) && $productManager->saveUpdate($model)) {
if (Yii::$app->request->isPost && $model->load(\Yii::$app->request->post())) {


Upload::uploadFile($model, 'photo', $photoFilenameOld);
$model->photoFile = UploadedFile::getInstance($model, 'photoFile');


$deletePhoto = $request->post('delete_photo', 0);
if ($deletePhoto) {
$model->photo = '';
$model->save();
}
if($model->validate()) {
if($model->photoFile) {
Upload::uploadFile($model, 'photoFile', 'photo', $photoFilenameOld);
}


$this->processAvailabilityPointsSale($model);
$deletePhoto = $request->post('delete_photo', 0);
if ($deletePhoto) {
$model->photo = '';
$model->save();
}


if ($model->apply_distributions) {
$distributionManager->addProductIncomingDistributions($model);
}
$this->processAvailabilityPointsSale($model);
if ($model->apply_distributions) {
$distributionManager->addProductIncomingDistributions($model);
}
$productManager->update($model);


$this->setFlash('success', 'Produit <strong>' . Html::encode($model->name) . '</strong> modifié');
return $this->redirect(['index']);
$this->setFlash('success', 'Produit <strong>' . Html::encode($model->name) . '</strong> modifié');
return $this->redirect(['index']);
}
} }


return $this->render('update/update', [ return $this->render('update/update', [
*/ */
public function actionDelete(int $id, bool $confirm = false) public function actionDelete(int $id, bool $confirm = false)
{ {
$productContainer = $this->getProductContainer();
$productDistributionContainer = $this->getProductDistributionContainer();
$product = $this->findModel($id); $product = $this->findModel($id);


if ($confirm) { if ($confirm) {
$product->delete();
ProductDistribution::deleteAll(['id_product' => $id]);
$productContainer->getBuilder()->updateStatusDeleted($product);
$productDistributionContainer->getBuilder()->disableProductDistributionsIncomingByProduct($product);


$this->setFlash('success', 'Produit <strong>' . Html::encode($product->name) . '</strong> supprimé'); $this->setFlash('success', 'Produit <strong>' . Html::encode($product->name) . '</strong> supprimé');
} else { } else {
} }
} }


public function actionAjaxToggleActive($id, $active)
public function actionAjaxToggleStatus($id, $status)
{ {
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;


$distributionManager = $this->getDistributionManager(); $distributionManager = $this->getDistributionManager();


$product = $this->findModel($id); $product = $this->findModel($id);
$product->active = (int) $active;
$product->status = (int) $status;
$product->save(); $product->save();


$distributionManager->addProductIncomingDistributions($product); $distributionManager->addProductIncomingDistributions($product);


return ['success', 'id' => $id, 'active' => $active];
return ['success', 'id' => $id, 'status' => $status];
} }


/** /**

+ 4
- 2
backend/controllers/SubscriptionController.php View File

$subscriptionManager = $this->getSubscriptionManager(); $subscriptionManager = $this->getSubscriptionManager();
$productSubscriptionManager = $this->getProductSubscriptionManager(); $productSubscriptionManager = $this->getProductSubscriptionManager();
$productManager = $this->getProductManager(); $productManager = $this->getProductManager();
$orderManager = $this->getOrderManager();
$distributionManager = $this->getDistributionManager(); $distributionManager = $this->getDistributionManager();
$orderManager = $this->getOrderManager();


$model = new SubscriptionForm; $model = new SubscriptionForm;
$model->isAdmin = true; $model->isAdmin = true;
$productManager = $this->getProductManager(); $productManager = $this->getProductManager();


$productsQuery = Product::find() $productsQuery = Product::find()
->where(['id_producer' => GlobalParam::getCurrentProducerId(),]);
->where(['id_producer' => GlobalParam::getCurrentProducerId()])
->andWhere('status >= :status')
->addParams(['status' => Product::STATUS_OFFLINE]);


if ($idSubscription) { if ($idSubscription) {
$productsQuery->joinWith(['productSubscription' => function ($query) use ($idSubscription) { $productsQuery->joinWith(['productSubscription' => function ($query) use ($idSubscription) {

+ 5
- 2
backend/controllers/UserController.php View File

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


$paymentContainer->getUtils() $paymentContainer->getUtils()
->creditOrDebitUser($creditForm->type, $user, $creditForm->amount, $creditForm->mean_payment, $user);
->creditOrDebitUser($creditForm->type, $user, $creditForm->amount, $creditForm->mean_payment, $this->getUserCurrent(), $creditForm->comment);


if($creditForm->send_mail) { if($creditForm->send_mail) {
$paymentContainer->getNotifier() $paymentContainer->getNotifier()
->notifyUserCreditMovement($user, $creditForm->type, $creditForm->amount); ->notifyUserCreditMovement($user, $creditForm->type, $creditForm->amount);
if(!$user->email) {
$this->addFlash('error', "L'utilisateur n'a pas pu être prévenu car son adresse email n'est pas définie.");
}
} }


$this->setFlash('success', 'Crédit mis à jour.');
$this->addFlash('success', 'Crédit mis à jour.');


return $this->refresh(); return $this->refresh();
} }

+ 1
- 1
backend/models/CreditForm.php View File



if ($this->validate()) { if ($this->validate()) {
$user = $userManager->findOneUserById($this->id_user); $user = $userManager->findOneUserById($this->id_user);
$paymentManager->creditOrDebitUser($this->type, $user, $this->amount, $this->mean_payment, $userManager->getCurrent());
$paymentManager->creditOrDebitUser($this->type, $user, $this->amount, $this->mean_payment, $userManager->getCurrent(), $this->comment);
// on prévient l'utilisateur que son compte vient d'être crédité // on prévient l'utilisateur que son compte vient d'être crédité
if($this->send_mail) { if($this->send_mail) {

+ 2
- 0
backend/models/MailForm.php View File

->where([ ->where([
'id_producer' => GlobalParam::getCurrentProducerId(), 'id_producer' => GlobalParam::getCurrentProducerId(),
]) ])
->andWhere('status >= :status')
->addParams(['status' => Product::STATUS_OFFLINE])
->innerJoinWith(['productDistribution' => function($query) use($distribution) { ->innerJoinWith(['productDistribution' => function($query) use($distribution) {
$query->andOnCondition([ $query->andOnCondition([
'product_distribution.id_distribution' => $distribution->id, 'product_distribution.id_distribution' => $distribution->id,

+ 10
- 10
backend/views/distribution/index.php View File

</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-for="product in products">
<tr v-for="product in products" v-if="getProductDistribution(product)">
<td> <td>
<button class="btn btn-success" v-if="product.productDistribution[0].active == 1"><span class="glyphicon glyphicon-ok"></span></button>
<button class="btn btn-success" v-if="getProductDistribution(product).active == 1"><span class="glyphicon glyphicon-ok"></span></button>
<button class="btn btn-default" v-else data-active-product="1" :data-id-product="product.id" @click="productActiveClick"><span class="glyphicon glyphicon-ok"></span></button> <button class="btn btn-default" v-else data-active-product="1" :data-id-product="product.id" @click="productActiveClick"><span class="glyphicon glyphicon-ok"></span></button>
<button class="btn btn-danger" v-if="product.productDistribution[0].active == 0"><span class="glyphicon glyphicon-remove"></span></button>
<button class="btn btn-danger" v-if="getProductDistribution(product).active == 0"><span class="glyphicon glyphicon-remove"></span></button>
<button class="btn btn-default" v-else data-active-product="0" :data-id-product="product.id" @click="productActiveClick"><span class="glyphicon glyphicon-remove"></span></button> <button class="btn btn-default" v-else data-active-product="0" :data-id-product="product.id" @click="productActiveClick"><span class="glyphicon glyphicon-remove"></span></button>
</td> </td>
<td>{{ product.name }}</td> <td>{{ product.name }}</td>
</td> </td>
<td class="quantity-max"> <td class="quantity-max">
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control quantity-max" placeholder="&infin;" :data-id-product="product.id" v-model="product.productDistribution[0].quantity_max" @keyup="productQuantityMaxChange" />
<input type="text" class="form-control quantity-max" placeholder="&infin;" :data-id-product="product.id" v-model="getProductDistribution(product).quantity_max" @keyup="productQuantityMaxChange" />
<span class="input-group-addon">{{ (product.unit == 'piece') ? 'p.' : ' '+((product.unit == 'g' || product.unit == 'kg') ? 'kg' : 'litre(s)') }}</span> <span class="input-group-addon">{{ (product.unit == 'piece') ? 'p.' : ' '+((product.unit == 'g' || product.unit == 'kg') ? 'kg' : 'litre(s)') }}</span>
</div> </div>
</td> </td>
<a href="javascript:void(0);" @click="orderPaymentModalClick" :data-id-order="order.id"> <a href="javascript:void(0);" @click="orderPaymentModalClick" :data-id-order="order.id">
<order-state-payment :order="order" :producer="producer"></order-state-payment> <order-state-payment :order="order" :producer="producer"></order-state-payment>
</a> </a>
<span class="glyphicon glyphicon-time" title="Débit automatique du crédit la veille de la distribution" v-if="order.auto_payment && (order.amount_paid == 0 || order.amount_paid < order.amount)"></span>
<span class="glyphicon glyphicon-time" title="Débit automatique du crédit la veille de la distribution" v-if="order.amount != 0 && order.auto_payment && (order.amount_paid == 0 || order.amount_paid < order.amount)"></span>
</td> </td>
<td class="column-credit" v-if="!idActivePointSale || (pointSaleActive && pointSaleActive.credit == 1)"> <td class="column-credit" v-if="!idActivePointSale || (pointSaleActive && pointSaleActive.credit == 1)">
<template v-if="order.isCreditContext"> <template v-if="order.isCreditContext">
<td colspan="6"> <td colspan="6">
<strong><span class="glyphicon glyphicon-menu-right"></span> Produits</strong> <strong><span class="glyphicon glyphicon-menu-right"></span> Produits</strong>
<ul> <ul>
<li v-for="product in products" v-if="order.productOrder[product.id].quantity > 0">
{{ product.name }} : {{ order.productOrder[product.id].quantity }} {{ order.productOrder[product.id].unit == 'piece' ? ' pièce(s)' : ' '+order.productOrder[product.id].unit }} <span v-if="product.productDistribution[0].active == 0" class="glyphicon glyphicon-warning-sign" title="Ce produit n'est pas activé"></span>
<li v-for="product in products" v-if="getProductDistribution(product) && order.productOrder[product.id].quantity > 0">
{{ product.name }} : {{ order.productOrder[product.id].quantity }} {{ order.productOrder[product.id].unit == 'piece' ? ' pièce(s)' : ' '+order.productOrder[product.id].unit }} <span v-if="getProductDistribution(product).active == 0" class="glyphicon glyphicon-warning-sign" title="Ce produit n'est pas activé"></span>
</li> </li>
</ul> </ul>
<div v-if="order.comment && order.comment.length > 0" class="comment"> <div v-if="order.comment && order.comment.length > 0" class="comment">
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-for="product in products" :class="(order.productOrder[product.id].quantity > 0) ? 'product-ordered' : ''">
<tr v-for="product in products" v-if="product.status >= 0 || order.productOrder[product.id].quantity > 0" :class="(order.productOrder[product.id].quantity > 0) ? 'product-ordered' : ''">
<td> <td>
<span class="label label-success" v-if="loadingUpdateProductOrder || order.productOrder[product.id].active">Actif</span> <span class="label label-success" v-if="loadingUpdateProductOrder || order.productOrder[product.id].active">Actif</span>
<span class="label label-danger" v-else>Inactif</span> <span class="label label-danger" v-else>Inactif</span>
</div> </div>
<div slot="footer"> <div slot="footer">
<div class="actions-form"> <div class="actions-form">
<button class="modal-default-button btn btn-danger" @click="$emit('close')">Fermer</button>

<button class="modal-default-button btn btn-primary" @click="submitFormUpdate" v-if="order.id">Modifier</button> <button class="modal-default-button btn btn-primary" @click="submitFormUpdate" v-if="order.id">Modifier</button>
<button class="modal-default-button btn btn-primary" @click="submitFormCreate" v-if="!order.id">Créer</button> <button class="modal-default-button btn btn-primary" @click="submitFormCreate" v-if="!order.id">Créer</button>


<button class="modal-default-button btn btn-danger" @click="$emit('close')">Fermer</button>

<div class="right"> <div class="right">
<button class="modal-default-button btn btn-info btn-update-prices" @click="updateProductOrderPrices(true)">Recharger les prix</button> <button class="modal-default-button btn btn-info btn-update-prices" @click="updateProductOrderPrices(true)">Recharger les prix</button>
<button v-if="order.id" class="modal-default-button btn btn-info btn-update-prices" @click="updateInvoicePrices(true)"> <button v-if="order.id" class="modal-default-button btn btn-info btn-update-prices" @click="updateInvoicePrices(true)">

+ 2
- 2
backend/views/document/_form.php View File



<?php if ($action == 'update' && $documentClass == 'Invoice'): ?> <?php if ($action == 'update' && $documentClass == 'Invoice'): ?>


<?= $this->render('form/_payment', ['model' => $model]); ?>
<?= $this->render('form/_payment', ['model' => $model, 'payment' => $payment]); ?>


<div v-if="(deliveryNoteUpdateArray && deliveryNoteUpdateArray.length > 0) || (deliveryNoteCreateArray && deliveryNoteCreateArray.length > 0)"> <div v-if="(deliveryNoteUpdateArray && deliveryNoteUpdateArray.length > 0) || (deliveryNoteCreateArray && deliveryNoteCreateArray.length > 0)">
<div class="panel panel-default"> <div class="panel panel-default">
<select class="form-control" v-model="productAddId" <select class="form-control" v-model="productAddId"
@change="changeProductAdd"> @change="changeProductAdd">
<option value="0" selected="selected">--</option> <option value="0" selected="selected">--</option>
<option v-for="product in productsArray" :value="product.id">
<option v-for="product in productsArray" v-if="product.status >= 0" :value="product.id">
{{ product.name }} {{ product.name }}
</option> </option>
</select> </select>

+ 2
- 2
backend/views/producer/update.php View File



<h4>Apparence</h4> <h4>Apparence</h4>
<?= $form->field($model, 'background_color_logo') ?> <?= $form->field($model, 'background_color_logo') ?>
<?= $form->field($model, 'logo')->fileInput() ?>
<?= $form->field($model, 'logoFile')->fileInput() ?>
<?php <?php
if (strlen($model->logo)) { if (strlen($model->logo)) {
echo '<img src="' . Yii::$app->urlManagerProducer->getHostInfo() . '/' . Yii::$app->urlManagerProducer->baseUrl . '/uploads/' . $model->logo . '" width="200px" /><br />'; echo '<img src="' . Yii::$app->urlManagerProducer->getHostInfo() . '/' . Yii::$app->urlManagerProducer->baseUrl . '/uploads/' . $model->logo . '" width="200px" /><br />';
echo '<input type="checkbox" name="delete_logo" id="delete_logo" /> <label for="delete_logo">Supprimer le logo</label><br /><br />'; echo '<input type="checkbox" name="delete_logo" id="delete_logo" /> <label for="delete_logo">Supprimer le logo</label><br /><br />';
} }
?> ?>
<?= $form->field($model, 'photo')->fileInput()->hint('Format idéal : 900 x 150 px') ?>
<?= $form->field($model, 'photoFile')->fileInput()->hint('Format idéal : 900 x 150 px') ?>
<?php <?php
if (strlen($model->photo)) { if (strlen($model->photo)) {
echo '<img src="' . Yii::$app->urlManagerProducer->getHostInfo() . '/' . Yii::$app->urlManagerProducer->baseUrl . '/uploads/' . $model->photo . '" width="400px" /><br />'; echo '<img src="' . Yii::$app->urlManagerProducer->getHostInfo() . '/' . Yii::$app->urlManagerProducer->baseUrl . '/uploads/' . $model->photo . '" width="400px" /><br />';

+ 2
- 2
backend/views/product/_form.php View File



<div> <div>
<div class="col-md-8"> <div class="col-md-8">
<?= $form->field($model, 'active')->radioList([1 => 'Oui', 0 => 'Non']) ?>
<?= $form->field($model, 'status')->radioList([1 => 'Oui', 0 => 'Non']) ?>
<?= $form->field($model, 'name')->textInput(['maxlength' => 255]) ?> <?= $form->field($model, 'name')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'reference')->textInput(['maxlength' => 255]) ?> <?= $form->field($model, 'reference')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'id_product_category')->dropDownList($productCategoryManager->populateProductCategoriesDropdownList()); ?> <?= $form->field($model, 'id_product_category')->dropDownList($productCategoryManager->populateProductCategoriesDropdownList()); ?>
?> ?>
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
<?= $form->field($model, 'photo')->fileInput() ?>
<?= $form->field($model, 'photoFile')->fileInput() ?>
<?php <?php
if (strlen($model->photo)) { if (strlen($model->photo)) {
echo '<img class="photo-product" src="' . Image::getThumbnailSmall($model->photo, true). '" width="200px" /><br />'; echo '<img class="photo-product" src="' . Image::getThumbnailSmall($model->photo, true). '" width="200px" /><br />';

+ 3
- 2
backend/views/product/index.php View File

} }
], ],
[ [
'attribute' => 'active',
'attribute' => 'status',
'label' => 'Actif',
'headerOptions' => ['class' => 'active column-hide-on-mobile'], 'headerOptions' => ['class' => 'active column-hide-on-mobile'],
'filterOptions' => ['class' => 'column-hide-on-mobile'], 'filterOptions' => ['class' => 'column-hide-on-mobile'],
'contentOptions' => ['class' => 'center column-hide-on-mobile'], 'contentOptions' => ['class' => 'center column-hide-on-mobile'],
return Toggle::widget( return Toggle::widget(
[ [
'name' => 'active', 'name' => 'active',
'checked' => $model->active,
'checked' => $model->status,
'options' => [ 'options' => [
'data-id' => $model->id, 'data-id' => $model->id,
'data-on' => 'Oui', 'data-on' => 'Oui',

+ 7
- 0
backend/views/user/credit.php View File

return ''; return '';
} }
], ],
[
'label' => 'Commentaire',
'format' => 'raw',
'value' => function ($model) {
return nl2br($model->comment);
}
],
], ],
]); ?> ]); ?>
</div> </div>

+ 5
- 3
backend/web/css/screen.css View File

/* line 148, ../sass/_responsive.scss */ /* line 148, ../sass/_responsive.scss */
.distribution-index #orders table button.dropdown-toggle, .distribution-index #orders table button.dropdown-toggle,
.distribution-index #orders table button.btn-moins, .distribution-index #orders table button.btn-moins,
.distribution-index #orders table button.btn-plus {
padding: 15px;
.distribution-index #orders table button.btn-plus,
.distribution-index #orders table .btn {
padding: 10px;
} }
/* line 155, ../sass/_responsive.scss */
/* line 156, ../sass/_responsive.scss */
.distribution-index #orders table .column-origin, .distribution-index #orders table .column-origin,
.distribution-index #orders table .column-point-sale, .distribution-index #orders table .column-point-sale,
.distribution-index #orders table .column-state-payment, .distribution-index #orders table .column-state-payment,
.distribution-index #orders table .column-payment, .distribution-index #orders table .column-payment,
.distribution-index #orders table .column-credit,
.distribution-index #orders table .column-tiller, .distribution-index #orders table .column-tiller,
.distribution-index #orders table .column-delivery-note { .distribution-index #orders table .column-delivery-note {
display: none; display: none;

+ 2
- 9
backend/web/js/backend.js View File

$('body.product-index .toggle input').change(function() { $('body.product-index .toggle input').change(function() {
var id = $(this).data('id'); var id = $(this).data('id');
var checked = $(this).prop('checked'); var checked = $(this).prop('checked');

var active = 0;
if(checked) {
active = 1;
}

$.get(UrlManager.getBaseUrl() + 'product/ajax-toggle-active', {
$.get(UrlManager.getBaseUrl() + 'product/ajax-toggle-status', {
id: id, id: id,
active: active
status: checked ? 1 : 0
}); });

}) })
} }



+ 19
- 5
backend/web/js/vuejs/distribution-index.js View File

initCountActiveProducts: function () { initCountActiveProducts: function () {
this.countActiveProducts = 0; this.countActiveProducts = 0;
for (var i = 0; i < this.products.length; i++) { for (var i = 0; i < this.products.length; i++) {
if (this.products[i].productDistribution[0].active == 1) {
if (this.products[i].productDistribution && this.products[i].productDistribution[0].active == 1) {
this.countActiveProducts++; this.countActiveProducts++;
} }
} }
}); });


for (i = 0; i < this.products.length; i++) { for (i = 0; i < this.products.length; i++) {
if (this.products[i].id == idProduct) {
if (this.products[i].productDistribution && this.products[i].id == idProduct) {
this.products[i].productDistribution[0].active = activeProduct; this.products[i].productDistribution[0].active = activeProduct;
} }
} }
return false; return false;
}, },
isProductMaximumQuantityExceeded: function (product) { isProductMaximumQuantityExceeded: function (product) {
return product.productDistribution[0].quantity_max
return
this.getProductDistribution(product)
&& this.getProductDistribution(product).quantity_max
&& product.quantity_ordered && product.quantity_ordered
&& product.quantity_ordered > product.productDistribution[0].quantity_max;
&& product.quantity_ordered > this.getProductDistribution(product).quantity_max;
}, },
pointSaleActiveClick: function (event) { pointSaleActiveClick: function (event) {
var idPointSale = event.currentTarget.getAttribute('data-id-point-sale'); var idPointSale = event.currentTarget.getAttribute('data-id-point-sale');
}, },
getUnitCoefficient: function(unit) { getUnitCoefficient: function(unit) {
return this.units[unit].coefficient; return this.units[unit].coefficient;
},
getProductDistribution: function(product) {
if(typeof product.productDistribution !== 'undefined' && product.productDistribution[0]) {
return product.productDistribution[0];
}

return null;
} }
}, },
}); });
productQuantityOrder += this.getProductQuantityProductOrder(this.order, product); productQuantityOrder += this.getProductQuantityProductOrder(this.order, product);
} }


quantityRemaining = product.productDistribution[0].quantity_max - productQuantityOrder;
quantityRemaining = this.getProductDistribution(product).quantity_max - productQuantityOrder;
if(unit != 'piece') { if(unit != 'piece') {
quantityRemaining = quantityRemaining.toFixed(2); quantityRemaining = quantityRemaining.toFixed(2);
} }
}, },
getUnitCoefficient: function(unit) { getUnitCoefficient: function(unit) {
return this.units[unit].coefficient; return this.units[unit].coefficient;
},
getProductDistribution: function(product) {
if(typeof product.productDistribution !== 'undefined' && product.productDistribution[0]) {
return product.productDistribution[0];
}
} }
} }
}); });

+ 4
- 2
backend/web/sass/_responsive.scss View File



button.dropdown-toggle, button.dropdown-toggle,
button.btn-moins, button.btn-moins,
button.btn-plus {
padding: 15px;
button.btn-plus,
.btn {
padding: 10px;
} }


//.column-checkbox, //.column-checkbox,
//.column-amount, //.column-amount,
.column-state-payment, .column-state-payment,
.column-payment, .column-payment,
.column-credit,
.column-tiller, .column-tiller,
//.column-actions, //.column-actions,
.column-delivery-note { .column-delivery-note {

+ 1
- 1
common/config/params.php View File

*/ */


return [ return [
'version' => '23.9.E',
'version' => '23.10.A',
'siteName' => 'Opendistrib', 'siteName' => 'Opendistrib',
'adminEmail' => 'contact@opendistrib.net', 'adminEmail' => 'contact@opendistrib.net',
'supportEmail' => 'contact@opendistrib.net', 'supportEmail' => 'contact@opendistrib.net',

+ 8
- 2
common/forms/SubscriptionForm.php View File

use common\logic\Product\Product\Model\Product; use common\logic\Product\Product\Model\Product;
use common\logic\Subscription\ProductSubscription\Model\ProductSubscription; use common\logic\Subscription\ProductSubscription\Model\ProductSubscription;
use common\logic\Subscription\Subscription\Model\Subscription; use common\logic\Subscription\Subscription\Model\Subscription;
use common\logic\Subscription\Subscription\Wrapper\SubscriptionManager;
use Yii; use Yii;
use yii\base\Model; use yii\base\Model;


*/ */
public function save() public function save()
{ {
$subscriptionManager = SubscriptionManager::getInstance();

if ($this->id) { if ($this->id) {
$subscription = Subscription::searchOne(['id' => $this->id]) ; $subscription = Subscription::searchOne(['id' => $this->id]) ;
} }
else { else {
$subscription = new Subscription ;
$subscription = $subscriptionManager->instanciateSubscription() ;
} }


if ($subscription) { if ($subscription) {
$subscription->saturday = $this->saturday; $subscription->saturday = $this->saturday;
$subscription->sunday = $this->sunday; $subscription->sunday = $this->sunday;
$subscription->week_frequency = $this->week_frequency; $subscription->week_frequency = $this->week_frequency;
$subscription->auto_payment = Subscription::AUTO_PAYMENT_DEDUCTED;
$subscription->auto_payment = $this->auto_payment;
if(is_null($subscription->auto_payment)) {
$subscription->auto_payment = Subscription::AUTO_PAYMENT_DEDUCTED;
}
$subscription->comment = $this->comment; $subscription->comment = $this->comment;


$subscription->save(); $subscription->save();

+ 1
- 1
common/helpers/Opendistrib.php View File

} }
} }


rsort($versionsArray);
rsort($versionsArray, SORT_NATURAL);


return $versionsArray; return $versionsArray;
} }

+ 4
- 2
common/helpers/Upload.php View File



class Upload class Upload
{ {
public static function uploadFile($model, $champs, $filename_old = '')
public static function uploadFile($model, $champsFile, $champs, $filename_old = '')
{ {
$file = UploadedFile::getInstance($model, $champs);
$file = $model->$champsFile;
if ($file) { if ($file) {
$file_name = $file->baseName . '-' . uniqid(); $file_name = $file->baseName . '-' . uniqid();
$file_name_extension = $file_name . '.' . $file->extension; $file_name_extension = $file_name . '.' . $file->extension;
$model->$champs = $filename_old; $model->$champs = $filename_old;
} }


$model->$champsFile = null;

$model->save(); $model->save();
} }
} }

+ 23
- 1
common/logic/AbstractBuilder.php View File

{ {
return $model->save(); return $model->save();
} }
}

/**
* Status
*/

public function updateStatusOnline(Model $model)
{
$model->status = StatusInterface::STATUS_ONLINE;
$this->update($model);
}

public function updateStatusOffline(Model $model)
{
$model->status = StatusInterface::STATUS_OFFLINE;
$this->update($model);
}

public function updateStatusDeleted(Model $model)
{
$model->status = StatusInterface::STATUS_DELETED;
$this->update($model);
}
}

+ 12
- 2
common/logic/AbstractRepository.php View File

return $this->query; return $this->query;
} }


public function createDefaultQuery(): RepositoryQueryInterface
public function createDefaultQuery(bool $filterStatus = true): RepositoryQueryInterface
{ {
$this->createQuery(); $this->createQuery();

if($filterStatus) {
$this->defaultStatus();
}
$this->defaultWith(); $this->defaultWith();
$this->defaultJoinWith(); $this->defaultJoinWith();
$this->defaultFilterProducerContext(); $this->defaultFilterProducerContext();
return $this->query; return $this->query;
} }


public function defaultStatus(): void
{
$class = new \ReflectionClass($this->query->getDefinition()->getEntityFqcn());
if($class->implementsInterface('common\logic\StatusInterface')) {
$this->query->filterIsStatusOnlineAndOffline();
}
}

public function defaultWith(): void public function defaultWith(): void
{ {
$defaultOptions = $this->getDefaultOptionsSearch(); $defaultOptions = $this->getDefaultOptionsSearch();

+ 23
- 0
common/logic/AbstractRepositoryQuery.php View File

$this->definition = $this->loadService($serviceClass); $this->definition = $this->loadService($serviceClass);
} }


public function getDefinition()
{
return $this->definition;
}

public function baseQuery(): ActiveQuery public function baseQuery(): ActiveQuery
{ {
$class = $this->definition->getEntityFqcn(); $class = $this->definition->getEntityFqcn();
return $this; return $this;
} }


public function filterIsStatusOnline()
{
$this->andWhere(['status' => StatusInterface::STATUS_ONLINE]);
return $this;
}

public function filterIsStatusOnlineAndOffline()
{
$this->andWhere('status >= :status')->addParams(['status' => StatusInterface::STATUS_OFFLINE]);
return $this;
}

public function filterIsStatusDeleted()
{
$this->andWhere(['status' => StatusInterface::STATUS_DELETED]);
return $this;
}

public function getDataProvider(int $pageSize): ActiveDataProvider public function getDataProvider(int $pageSize): ActiveDataProvider
{ {
return new ActiveDataProvider([ return new ActiveDataProvider([

+ 12
- 9
common/logic/Distribution/Distribution/Service/DistributionBuilder.php View File

use common\logic\PointSale\PointSale\Model\PointSale; use common\logic\PointSale\PointSale\Model\PointSale;
use common\logic\Product\Product\Model\Product; use common\logic\Product\Product\Model\Product;
use common\logic\Product\Product\Repository\ProductRepository; use common\logic\Product\Product\Repository\ProductRepository;
use common\logic\Product\Product\Service\ProductSolver;
use common\logic\User\UserProducer\Repository\UserProducerRepository; use common\logic\User\UserProducer\Repository\UserProducerRepository;


class DistributionBuilder extends AbstractBuilder class DistributionBuilder extends AbstractBuilder
protected OrderRepository $orderRepository; protected OrderRepository $orderRepository;
protected UserProducerRepository $userProducerRepository; protected UserProducerRepository $userProducerRepository;
protected ProductOrderBuilder $productOrderBuilder; protected ProductOrderBuilder $productOrderBuilder;
protected ProductSolver $productSolver;


public function loadDependencies(): void public function loadDependencies(): void
{ {
$this->orderRepository = $this->loadService(OrderRepository::class); $this->orderRepository = $this->loadService(OrderRepository::class);
$this->userProducerRepository = $this->loadService(UserProducerRepository::class); $this->userProducerRepository = $this->loadService(UserProducerRepository::class);
$this->productOrderBuilder = $this->loadService(ProductOrderBuilder::class); $this->productOrderBuilder = $this->loadService(ProductOrderBuilder::class);
$this->productSolver = $this->loadService(ProductSolver::class);
} }


public function instanciateDistribution(string $date, bool $delivery = true): Distribution public function instanciateDistribution(string $date, bool $delivery = true): Distribution
return $distribution; return $distribution;
} }


// initDistribution
public function createDistribution(string $date, bool $delivery = true): Distribution public function createDistribution(string $date, bool $delivery = true): Distribution
{ {
$distribution = $this->instanciateDistribution($date, $delivery); $distribution = $this->instanciateDistribution($date, $delivery);

$this->saveCreate($distribution);

$this->create($distribution);
$this->createPointSaleDistributions($distribution); $this->createPointSaleDistributions($distribution);
$this->createProductDistributions($distribution); $this->createProductDistributions($distribution);


/** /**
* Ajoute un produit à une distribution. * Ajoute un produit à une distribution.
*/ */
public function addProduct(Distribution $distribution, Product $product): ProductDistribution
public function addProduct(Distribution $distribution, Product $product): ?ProductDistribution
{ {
$productDistribution = $this->productDistributionBuilder->createProductDistributionIfNotExist($distribution, $product);
$this->productDistributionBuilder->updateProductDistribution($productDistribution);
$this->updateOrderProductPrices($distribution, $product);
if($this->productSolver->isStatusOnlineOrOffline($product)) {
$productDistribution = $this->productDistributionBuilder->createProductDistributionIfNotExist($distribution, $product);
$this->productDistributionBuilder->updateProductDistribution($productDistribution);
$this->updateOrderProductPrices($distribution, $product);
return $productDistribution;
}


return $productDistribution;
return null;
} }


/** /**

+ 15
- 0
common/logic/Distribution/ProductDistribution/Service/ProductDistributionBuilder.php View File



use common\logic\AbstractBuilder; use common\logic\AbstractBuilder;
use common\logic\Distribution\Distribution\Model\Distribution; use common\logic\Distribution\Distribution\Model\Distribution;
use common\logic\Distribution\Distribution\Repository\DistributionRepository;
use common\logic\Distribution\Distribution\Service\DistributionSolver; use common\logic\Distribution\Distribution\Service\DistributionSolver;
use common\logic\Distribution\ProductDistribution\Model\ProductDistribution; use common\logic\Distribution\ProductDistribution\Model\ProductDistribution;
use common\logic\Distribution\ProductDistribution\Repository\ProductDistributionRepository; use common\logic\Distribution\ProductDistribution\Repository\ProductDistributionRepository;
protected ProductDistributionRepository $productDistributionRepository; protected ProductDistributionRepository $productDistributionRepository;
protected DistributionSolver $distributionSolver; protected DistributionSolver $distributionSolver;
protected ProductSolver $productSolver; protected ProductSolver $productSolver;
protected DistributionRepository $distributionRepository;


public function loadDependencies(): void public function loadDependencies(): void
{ {
$this->productDistributionRepository = $this->loadService(ProductDistributionRepository::class); $this->productDistributionRepository = $this->loadService(ProductDistributionRepository::class);
$this->distributionSolver = $this->loadService(DistributionSolver::class); $this->distributionSolver = $this->loadService(DistributionSolver::class);
$this->productSolver = $this->loadService(ProductSolver::class); $this->productSolver = $this->loadService(ProductSolver::class);
$this->distributionRepository = $this->loadService(DistributionRepository::class);
} }


public function instanciateProductDistribution(Distribution $distribution, Product $product): ProductDistribution public function instanciateProductDistribution(Distribution $distribution, Product $product): ProductDistribution
$productDistribution->active = $active; $productDistribution->active = $active;
$this->update($productDistribution); $this->update($productDistribution);
} }

public function disableProductDistributionsIncomingByProduct(Product $product)
{
$distributionsIncomingArray = $this->distributionRepository->findDistributionsIncoming(true);
foreach($distributionsIncomingArray as $distribution) {
ProductDistribution::updateAll([
'id_product' => $product->id,
'id_distribution' => $distribution->id,
'active' => false
]);
}
}
} }

+ 2
- 1
common/logic/Document/Invoice/Service/InvoiceSolver.php View File

use common\helpers\Price; use common\helpers\Price;
use common\logic\Document\Document\Service\DocumentSolver; use common\logic\Document\Document\Service\DocumentSolver;
use common\logic\Document\Invoice\Model\Invoice; use common\logic\Document\Invoice\Model\Invoice;
use common\logic\Order\Order\Model\Order;


class InvoiceSolver extends DocumentSolver class InvoiceSolver extends DocumentSolver
{ {


public function isInvoicePaid(Invoice $invoice): bool public function isInvoicePaid(Invoice $invoice): bool
{ {
return $this->getInvoiceAmountPaid($invoice) >= Price::numberTwoDecimals($this->getAmountWithTax($invoice));
return $this->getInvoiceAmountPaid($invoice) >= Price::numberTwoDecimals($this->getAmountWithTax($invoice, Order::INVOICE_AMOUNT_TOTAL));
} }
} }

+ 6
- 3
common/logic/Order/Order/Repository/OrderRepository.php View File

$titleLabel = ''; $titleLabel = '';


if(!$amountPaid) { if(!$amountPaid) {
if($isOrderPaid) {
if($isOrderPaid && $amountTotal != 0) {
$label = 'Facture payée'; $label = 'Facture payée';
} }
elseif($this->isCreditAutoPayment($order)) {
elseif($this->isCreditAutoPayment($order) && $amountTotal != 0) {
if($order->subscription && $order->subscription->auto_payment == 0) { if($order->subscription && $order->subscription->auto_payment == 0) {
$label = 'Crédit désactivé'; $label = 'Crédit désactivé';
} }
$label = 'Crédit non débité'; $label = 'Crédit non débité';
} }
} }
elseif($amountTotal == 0) {
$label = 'Gratuit';
}
else { else {
$label = 'Non réglé'; $label = 'Non réglé';
} }
$classLabel = 'warning'; $classLabel = 'warning';
$titleLabel = 'Paiement en surplus'; $titleLabel = 'Paiement en surplus';
} }
elseif($isOrderPaid) {
elseif(($isOrderPaid && $amountTotal != 0) || $amountTotal == 0) {
$classLabel = 'success'; $classLabel = 'success';
} }
elseif($orderPaymentStatus == Order::PAYMENT_UNPAID) { elseif($orderPaymentStatus == Order::PAYMENT_UNPAID) {

+ 1
- 0
common/logic/Order/Order/Service/OrderBuilder.php View File

$order->user, $order->user,
$this->userSolver->getCurrent(), $this->userSolver->getCurrent(),
MeanPayment::CREDIT, MeanPayment::CREDIT,
null,
$order $order
); );
} }

+ 14
- 1
common/logic/Payment/Model/Payment.php View File

[['amount'], 'double'], [['amount'], 'double'],
[['date_transaction'], 'date', 'format' => 'php:Y-m-d'], [['date_transaction'], 'date', 'format' => 'php:Y-m-d'],
[['type', 'mean_payment'], 'string', 'max' => 255], [['type', 'mean_payment'], 'string', 'max' => 255],
[['comment'], 'string', 'max' => 2048],
[['comment', 'summary'], 'string', 'max' => 2048],
]; ];
} }


'id_producer' => 'Producteur', 'id_producer' => 'Producteur',
'mean_payment' => 'Moyen de paiement', 'mean_payment' => 'Moyen de paiement',
'comment' => 'Commentaire', 'comment' => 'Commentaire',
'summary' => 'Résumé',
'date_transaction' => 'Date transaction' 'date_transaction' => 'Date transaction'
]; ];
} }


return $this; return $this;
} }

public function getSummary(): ?string
{
return $this->summary;
}

public function setSummary(?string $summary): self
{
$this->summary = $summary;

return $this;
}
} }

+ 6
- 6
common/logic/Payment/Service/PaymentBuilder.php View File

User $user = null, User $user = null,
User $userAction = null, User $userAction = null,
string $meanPayment = null, string $meanPayment = null,
string $comment = null,
Order $order = null, Order $order = null,
Invoice $invoice = null Invoice $invoice = null
): Payment ): Payment
$payment->type = $type; $payment->type = $type;
$payment->amount = round($amount, 2); $payment->amount = round($amount, 2);
$payment->populateProducer($producer); $payment->populateProducer($producer);
$payment->setMeanPayment($meanPayment);
$payment->setComment($comment);


if($user) { if($user) {
$payment->populateUser($user); $payment->populateUser($user);
$payment->populateInvoice($invoice); $payment->populateInvoice($invoice);
} }


if($meanPayment) {
$payment->mean_payment = $meanPayment;
}

return $payment; return $payment;
} }


User $user = null, User $user = null,
User $userAction = null, User $userAction = null,
string $meanPayment = null, string $meanPayment = null,
string $comment = null,
Order $order = null, Order $order = null,
Invoice $invoice = null Invoice $invoice = null
): ?Payment ): ?Payment
return null; return null;
} }


$payment = $this->instanciatePayment($type, $amount, $producer, $user, $userAction, $meanPayment, $order, $invoice);
$payment->setComment($payment->getComment() . $this->orderSolver->getPaymentComment($payment));
$payment = $this->instanciatePayment($type, $amount, $producer, $user, $userAction, $meanPayment, $comment, $order, $invoice);
$payment->setSummary($this->orderSolver->getPaymentComment($payment));
$this->create($payment); $this->create($payment);


return $payment; return $payment;

+ 22
- 16
common/logic/Payment/Service/PaymentNotifier.php View File



public function notifyUserCreditMovement(User $user, string $type, float $amount) public function notifyUserCreditMovement(User $user, string $type, float $amount)
{ {
$producer = $this->getProducerContext();
$credit = $this->userRepository->getCredit($user, true);

$this->mailer->sendFromProducer(
'Mouvement de crédit',
'creditUser',
[
'user' => $user,
'producer' => $producer,
'credit' => $credit,
'type' => $type,
'amount' => $amount
],
$user->email,
$producer
);
if($user->email) {
$producer = $this->getProducerContext();
$credit = $this->userRepository->getCredit($user, true);

$this->mailer->sendFromProducer(
'Mouvement de crédit',
'creditUser',
[
'user' => $user,
'producer' => $producer,
'credit' => $credit,
'type' => $type,
'amount' => $amount
],
$user->email,
$producer
);

return true;
}

return false;
} }
} }

+ 14
- 7
common/logic/Payment/Service/PaymentUtils.php View File

$this->producerSolver = $this->loadService(ProducerSolver::class); $this->producerSolver = $this->loadService(ProducerSolver::class);
} }


public function creditUser(User $user, float $amount, string $meanPayment, User $userAction): void
public function creditUser(User $user, float $amount, string $meanPayment, User $userAction, string $comment = null): void
{ {
$this->paymentBuilder->createPayment( $this->paymentBuilder->createPayment(
Payment::TYPE_CREDIT, Payment::TYPE_CREDIT,
$this->getProducerContext(), $this->getProducerContext(),
$user, $user,
$userAction, $userAction,
$meanPayment
$meanPayment,
$comment
); );
} }


public function debitUser(User $user, float $amount, string $meanPayment, User $userAction): void
public function debitUser(User $user, float $amount, string $meanPayment, User $userAction, string $comment = null): void
{ {
$this->paymentBuilder->createPayment( $this->paymentBuilder->createPayment(
Payment::TYPE_DEBIT, Payment::TYPE_DEBIT,
$this->getProducerContext(), $this->getProducerContext(),
$user, $user,
$userAction, $userAction,
$meanPayment
$meanPayment,
$comment
); );
} }


public function creditOrDebitUser(string $type, User $user, float $amount, string $meanPayment, User $userAction): void
public function creditOrDebitUser(string $type, User $user, float $amount, string $meanPayment, User $userAction, string $comment): void
{ {
if($type == Payment::TYPE_CREDIT) { if($type == Payment::TYPE_CREDIT) {
$this->creditUser($user, $amount, $meanPayment, $userAction);
$this->creditUser($user, $amount, $meanPayment, $userAction, $comment);
} }
elseif($type == Payment::TYPE_DEBIT) { elseif($type == Payment::TYPE_DEBIT) {
$this->debitUser($user, $amount, $meanPayment, $userAction);
$this->debitUser($user, $amount, $meanPayment, $userAction, $comment);
} }
else { else {
throw new ErrorException('$type a une valeur incorrect'); throw new ErrorException('$type a une valeur incorrect');
$order->user, $order->user,
$userAction, $userAction,
$meanPayment, $meanPayment,
null,
$order $order
); );
} }
$order->user, $order->user,
$userAction, $userAction,
MeanPayment::CREDIT, MeanPayment::CREDIT,
null,
$order $order
); );
} }
$order->user, $order->user,
$userAction, $userAction,
$meanPayment, $meanPayment,
null,
$order $order
); );
} }
$order->user, $order->user,
$userAction, $userAction,
MeanPayment::CREDIT, MeanPayment::CREDIT,
null,
$order $order
); );
} }
$order->user, $order->user,
$userAction, $userAction,
MeanPayment::CREDIT, MeanPayment::CREDIT,
null,
$order $order
); );
} }

+ 2
- 1
common/logic/PointSale/PointSale/Repository/PointSaleRepositoryQuery.php View File

use common\logic\AbstractRepositoryQuery; use common\logic\AbstractRepositoryQuery;
use common\logic\PointSale\PointSale\Model\PointSale; use common\logic\PointSale\PointSale\Model\PointSale;
use common\logic\PointSale\PointSale\Service\PointSaleDefinition; use common\logic\PointSale\PointSale\Service\PointSaleDefinition;
use common\logic\StatusInterface;
use yii\db\ActiveQuery; use yii\db\ActiveQuery;


class PointSaleRepositoryQuery extends AbstractRepositoryQuery class PointSaleRepositoryQuery extends AbstractRepositoryQuery


public function filterIsOnline(): self public function filterIsOnline(): self
{ {
$this->andWhere(['status' => 1]);
$this->andWhere(['status' => StatusInterface::STATUS_ONLINE]);


return $this; return $this;
} }

+ 13
- 2
common/logic/Producer/Producer/Model/Producer.php View File

use common\logic\User\User\Model\User; use common\logic\User\User\Model\User;
use common\logic\User\UserProducer\Model\UserProducer; use common\logic\User\UserProducer\Model\UserProducer;
use common\components\ActiveRecordCommon; use common\components\ActiveRecordCommon;
use yii\web\UploadedFile;


/** /**
* This is the model class for table "producer". * This is the model class for table "producer".
self::BILLING_TYPE_FREE_PRICE => 'Prix libre', self::BILLING_TYPE_FREE_PRICE => 'Prix libre',
]; ];


var $secret_key_payplug;

const ONLINE_PAYMENT_MINIMUM_AMOUNT_DEFAULT = 25; const ONLINE_PAYMENT_MINIMUM_AMOUNT_DEFAULT = 25;


const ORDER_DEADLINE_DEFAULT = 20; const ORDER_DEADLINE_DEFAULT = 20;
const ORDER_DELAY_DEFAULT = 1; const ORDER_DELAY_DEFAULT = 1;


var $secret_key_payplug;

/**
* @var UploadedFile
*/
public $logoFile;
/**
* @var UploadedFile
*/
public $photoFile;

/** /**
* @inheritdoc * @inheritdoc
*/ */
return $model->tiller == true; return $model->tiller == true;
} }
], ],
[['logoFile', 'photoFile'], 'file', 'extensions' => 'png, jpg, jpeg', 'mimeTypes' => 'image/png, image/jpeg'],
[ [
[ [
'order_delay', 'order_delay',

+ 52
- 0
common/logic/Producer/Producer/Service/ProducerBuilder.php View File



use common\helpers\Opendistrib; use common\helpers\Opendistrib;
use common\helpers\Password; use common\helpers\Password;
use common\helpers\Upload;
use common\logic\AbstractBuilder; use common\logic\AbstractBuilder;
use common\logic\Producer\Producer\Model\Producer; use common\logic\Producer\Producer\Model\Producer;
use common\logic\Producer\Producer\Repository\ProducerRepository; use common\logic\Producer\Producer\Repository\ProducerRepository;
$producer->option_stripe_endpoint_secret $producer->option_stripe_endpoint_secret
); );
} }

public function savePrivateKeysStripe(Producer $producer)
{
$this->savePrivateKeyApiStripe($producer);
$this->savePrivateKeyEndpointStripe($producer);

$producer->option_stripe_private_key = '';
$producer->option_stripe_endpoint_secret = '';

$producer->save();
}

public function initOptionDashboardDatesBeforeSave(Producer $producer): void
{
$this->initOptionDashboardDateStartEndBeforeSave($producer, true);
$this->initOptionDashboardDateStartEndBeforeSave($producer, false);
}

private function initOptionDashboardDateStartEndBeforeSave(Producer $producer, bool $dateStart): void
{
$field = 'option_dashboard_date_'.($dateStart ? 'start' : 'end');
if ($producer->$field && strlen($producer->$field)) {
$producer->$field = date(
'Y-m-d',
strtotime(str_replace('/', '-', $producer->$field))
);
}
}

public function initOptionDashboardDatesDisplay(Producer $producer, bool $dateStart = true): void
{
$this->initOptionDashboardDateStartEndDisplay($producer, true);
$this->initOptionDashboardDateStartEndDisplay($producer, false);
}

private function initOptionDashboardDateStartEndDisplay(Producer $producer, bool $dateStart): void
{
$field = 'option_dashboard_date_'.($dateStart ? 'start' : 'end');
if (strlen($producer->$field)) {
$producer->$field = date('d/m/Y', strtotime($producer->$field));
}
}

public function processUploadImage(Producer $producer, string $name, string $filenameOld, bool $deleteImage)
{
Upload::uploadFile($producer, $name.'File', $name, $filenameOld);
if ($deleteImage) {
$producer->$name = '';
$producer->save();
}
}
} }

+ 13
- 8
common/logic/Product/Product/Model/Product.php View File

use common\logic\Product\ProductPointSale\Model\ProductPointSale; use common\logic\Product\ProductPointSale\Model\ProductPointSale;
use common\logic\Product\ProductPrice\Model\ProductPrice; use common\logic\Product\ProductPrice\Model\ProductPrice;
use common\components\ActiveRecordCommon; use common\components\ActiveRecordCommon;
use common\logic\StatusInterface;
use common\logic\Subscription\ProductSubscription\Model\ProductSubscription; use common\logic\Subscription\ProductSubscription\Model\ProductSubscription;
use yii\web\UploadedFile;


/** /**
* This is the model class for table "product". * This is the model class for table "product".
* *
*/ */
class Product extends ActiveRecordCommon
class Product extends ActiveRecordCommon implements StatusInterface
{ {
public $total = 0; public $total = 0;
public $apply_distributions = true; public $apply_distributions = true;

public $price_with_tax = 0; public $price_with_tax = 0;
public $wording_unit = ''; public $wording_unit = '';

public $pointsSale; public $pointsSale;


/**
* @var UploadedFile
*/
public $photoFile;

public static $unitsArray = [ public static $unitsArray = [
'piece' => [ 'piece' => [
'unit' => 'piece', 'unit' => 'piece',
{ {
return [ return [
[['name', 'id_producer'], 'required'], [['name', 'id_producer'], 'required'],
[['active', 'order', 'id_producer', 'id_tax_rate', 'id_product_category'], 'integer'],
[['order', 'id_producer', 'id_tax_rate', 'id_product_category', 'status'], 'integer'],
[['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'unavailable', 'apply_distributions', 'available_on_points_sale'], 'boolean'], [['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'unavailable', 'apply_distributions', 'available_on_points_sale'], 'boolean'],
[['price', 'weight', 'step', 'quantity_max', 'quantity_max_monday', 'quantity_max_tuesday', 'quantity_max_wednesday', 'quantity_max_thursday', 'quantity_max_friday', 'quantity_max_saturday', 'quantity_max_sunday'], 'number'], [['price', 'weight', 'step', 'quantity_max', 'quantity_max_monday', 'quantity_max_tuesday', 'quantity_max_wednesday', 'quantity_max_thursday', 'quantity_max_friday', 'quantity_max_saturday', 'quantity_max_sunday'], 'number'],
[['photo'], 'file'],
[['photoFile'], 'file', 'extensions' => 'png, jpg, jpeg', 'mimeTypes' => 'image/png, image/jpeg'],
[['name', 'reference', 'description', 'photo', 'unit'], 'string', 'max' => 255], [['name', 'reference', 'description', 'photo', 'unit'], 'string', 'max' => 255],
[['recipe'], 'string', 'max' => 1000], [['recipe'], 'string', 'max' => 1000],
['step', 'required', 'message' => 'Champs obligatoire', 'when' => function ($model) { ['step', 'required', 'message' => 'Champs obligatoire', 'when' => function ($model) {
'name' => 'Nom', 'name' => 'Nom',
'reference' => 'Référence', 'reference' => 'Référence',
'description' => 'Description', 'description' => 'Description',
'active' => 'Actif',
'photo' => 'Photo',
'photoFile' => 'Photo',
'price' => 'Prix (€) TTC', 'price' => 'Prix (€) TTC',
'weight' => 'Poids', 'weight' => 'Poids',
'recipe' => 'Recette', 'recipe' => 'Recette',
'step' => 'Pas', 'step' => 'Pas',
'id_tax_rate' => 'TVA', 'id_tax_rate' => 'TVA',
'id_product_category' => 'Catégorie', 'id_product_category' => 'Catégorie',
'available_on_points_sale' => 'Par défaut'
'available_on_points_sale' => 'Par défaut',
'status' => 'Actif',
]; ];
} }



+ 6
- 6
common/logic/Product/Product/Model/ProductSearch.php View File

public function rules() public function rules()
{ {
return [ return [
[['active', 'order', 'quantity_max', 'id_producer'], 'integer'],
[['order', 'quantity_max', 'id_producer', 'status'], 'integer'],
[['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'unavailable'], 'boolean'], [['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'unavailable'], 'boolean'],
[['price', 'weight'], 'number'], [['price', 'weight'], 'number'],
[[ 'photo'], 'file'], [[ 'photo'], 'file'],
->with($optionsSearch['with']) ->with($optionsSearch['with'])
->innerJoinWith($optionsSearch['join_with'], true) ->innerJoinWith($optionsSearch['join_with'], true)
->where(['product.id_producer' => GlobalParam::getCurrentProducerId()]) ->where(['product.id_producer' => GlobalParam::getCurrentProducerId()])
->orderBy('product.order ASC')
;
->andWhere('status >= :status')->addParams(['status' => Product::STATUS_OFFLINE])
->orderBy('product.order ASC');
$dataProvider = new ActiveDataProvider([ $dataProvider = new ActiveDataProvider([
'query' => $query, 'query' => $query,
'sort' => ['attributes' => ['order', 'photo', 'name', 'description','active']],
'sort' => ['attributes' => ['order', 'photo', 'name', 'description','status']],
'pagination' => [ 'pagination' => [
'pageSize' => 1000, 'pageSize' => 1000,
], ],
$query->andFilterWhere(['like', 'product.name', $this->name]) ; $query->andFilterWhere(['like', 'product.name', $this->name]) ;
$query->andFilterWhere(['like', 'product.description', $this->description]) ; $query->andFilterWhere(['like', 'product.description', $this->description]) ;
if(isset($this->active) && is_numeric($this->active)) {
if(isset($this->status) && is_numeric($this->status)) {
$query->andWhere([ $query->andWhere([
'product.active' => $this->active
'product.status' => $this->status
]) ; ]) ;
} }

+ 8
- 8
common/logic/Product/Product/Repository/ProductRepository.php View File

->findOne(); ->findOne();
} }


public function findProducts(): array
public function findProducts(bool $filterStatus = true): array
{ {
return $this->createDefaultQuery()->find();
return $this->createDefaultQuery($filterStatus)->find();
} }


/** /**
return $this->createDefaultQuery()->count(); return $this->createDefaultQuery()->count();
} }


public function queryProductsByDistribution(Distribution $distribution)
public function queryProductsByDistribution(Distribution $distribution, bool $filterStatus = true)
{ {
return $this->createDefaultQuery()
return $this->createDefaultQuery($filterStatus)
->joinWith([ ->joinWith([
'productDistribution' => function ($query) use ($distribution) { 'productDistribution' => function ($query) use ($distribution) {
$query->andOnCondition( $query->andOnCondition(
/** /**
* Retourne les produits d'une production donnée. * Retourne les produits d'une production donnée.
*/ */
public function findProductsByDistribution(Distribution $distribution)
public function findProductsByDistribution(Distribution $distribution, bool $filterStatus = true)
{ {
$productArray = $this->queryProductsByDistribution($distribution)->find();
$productArray = $this->queryProductsByDistribution($distribution, $filterStatus)->find();
return $this->buildProductsArrayById($productArray); return $this->buildProductsArrayById($productArray);
} }


public function queryProductsByProductCategory(ProductCategory $productCategory) public function queryProductsByProductCategory(ProductCategory $productCategory)
{ {
return $this->createDefaultQuery() return $this->createDefaultQuery()
->filterIsActive()
->filterIsStatusOnline()
->filterByProductCategory($productCategory); ->filterByProductCategory($productCategory);
} }


public function countProductsWithoutCategory(Producer $producer): int public function countProductsWithoutCategory(Producer $producer): int
{ {
return $this->createDefaultQuery() return $this->createDefaultQuery()
->filterIsActive()
->filterIsStatusOnline()
->filterByProductCategory(null) ->filterByProductCategory(null)
->count(); ->count();
} }

+ 1
- 6
common/logic/Product/Product/Repository/ProductRepositoryQuery.php View File

use common\logic\Distribution\Distribution\Model\Distribution; use common\logic\Distribution\Distribution\Model\Distribution;
use common\logic\Product\Product\Service\ProductDefinition; use common\logic\Product\Product\Service\ProductDefinition;
use common\logic\Product\ProductCategory\Model\ProductCategory; use common\logic\Product\ProductCategory\Model\ProductCategory;
use common\logic\StatusInterface;


class ProductRepositoryQuery extends AbstractRepositoryQuery class ProductRepositoryQuery extends AbstractRepositoryQuery
{ {
return $this; return $this;
} }


public function filterIsActive(): self
{
$this->andWhere(['product.active' => true]);
return $this;
}

public function filterByProductCategory(ProductCategory $productCategory = null) : self public function filterByProductCategory(ProductCategory $productCategory = null) : self
{ {
if($productCategory) { if($productCategory) {

+ 1
- 1
common/logic/Product/Product/Service/ProductBuilder.php View File

public function createProduct(): Product public function createProduct(): Product
{ {
$product = $this->instanciateProduct(); $product = $this->instanciateProduct();
$this->saveCreate($product);
$this->create($product);


return $product; return $product;
} }

+ 8
- 3
common/logic/Product/Product/Service/ProductSolver.php View File



public function isProductActiveByDay(Product $product, string $day): bool public function isProductActiveByDay(Product $product, string $day): bool
{ {
return $product->active && $product->$day;
return $product->status && $product->$day;
} }


public function getProductFieldNameQuantityMax(string $day): string public function getProductFieldNameQuantityMax(string $day): string
$potentialRevenues = 0; $potentialRevenues = 0;


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


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


return $potentialWeight; return $potentialWeight;
} }

public function isStatusOnlineOrOffline(Product $product): bool
{
return $product->status >= Product::STATUS_OFFLINE;
}
} }

+ 10
- 0
common/logic/StatusInterface.php View File

<?php

namespace common\logic;

interface StatusInterface
{
const STATUS_DELETED = -1;
const STATUS_OFFLINE = 0;
const STATUS_ONLINE = 1;
}

+ 1
- 0
common/logic/Subscription/Subscription/Service/SubscriptionBuilder.php View File

public function instanciateSubscription(): Subscription public function instanciateSubscription(): Subscription
{ {
$subscription = new Subscription(); $subscription = new Subscription();
$subscription->auto_payment = Subscription::AUTO_PAYMENT_DEDUCTED;


return $subscription; return $subscription;
} }

+ 27
- 0
common/versions/23.10.A.php View File

<?php

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

version(
'03/10/2023',
[
[

],
[
"[Administration] Distributions > commandes : accès boutons d'action en version mobile",
"[Administration] Utilisateurs > historique crédit : remise en place colonne commentaire",
"[Administration] Distributions > liste commandes : libellé 'Gratuit' si montant à 0€",
"[Administration] Abonnements : correctif champs débit automatique non mis à jour lors de la modification",
]
],
[
[],
[
"[Administration] Produits : gestion statut 'supprimé'",
"[Administration] Correctif problème upload images webp"
]
],
);

?>

+ 26
- 0
console/migrations/m230929_065700_rename_column_product_active_status.php View File

<?php

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

/**
* Class m230929_065700_rename_column_product_active_status
*/
class m230929_065700_rename_column_product_active_status extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->renameColumn('product', 'active', 'status');
}

/**
* {@inheritdoc}
*/
public function safeDown()
{
$this->renameColumn('product', 'status', 'active');
}
}

+ 26
- 0
console/migrations/m231002_142915_add_column_payment_summary.php View File

<?php

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

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

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

+ 1
- 1
producer/controllers/OrderController.php View File

$productsArray = Product::find() $productsArray = Product::find()
->where([ ->where([
'id_producer' => $producer->id, 'id_producer' => $producer->id,
'product.active' => 1,
'product.status' => 1,
]); ]);


$productsArray = $productsArray->joinWith([ $productsArray = $productsArray->joinWith([

+ 1
- 1
producer/controllers/SiteController.php View File

$queryProducts = Product::find() $queryProducts = Product::find()
->andWhere([ ->andWhere([
'id_producer' => $this->getProducerCurrent()->id, 'id_producer' => $this->getProducerCurrent()->id,
'active' => true,
'status' => Product::STATUS_ONLINE,
'id_product_category' => null, 'id_product_category' => null,
]) ])
->with('productPointSale') ->with('productPointSale')

+ 1
- 1
producer/web/js/vuejs/subscription-form.js View File

} }
}, },
checkProductAvailable: function (product) { checkProductAvailable: function (product) {
var available = product.active &&
var available = product.status &&
(!this.monday || (this.monday && product.monday)) && (!this.monday || (this.monday && product.monday)) &&
(!this.tuesday || (this.tuesday && product.tuesday)) && (!this.tuesday || (this.tuesday && product.tuesday)) &&
(!this.wednesday || (this.wednesday && product.wednesday)) && (!this.wednesday || (this.wednesday && product.wednesday)) &&

Loading…
Cancel
Save