Browse Source

Produits tournants

feature/rotating_product
Guillaume Bourgeois 3 months ago
parent
commit
f6fad5c0e7
11 changed files with 166 additions and 91 deletions
  1. +2
    -3
      backend/views/rotating/index.php
  2. +2
    -22
      backend/views/subscription/index.php
  3. +0
    -41
      domain/Order/Order/OrderBuilder.php
  4. +51
    -1
      domain/Order/Order/OrderManager.php
  5. +10
    -0
      domain/Product/Rotating/Rotating.php
  6. +7
    -3
      domain/Subscription/Subscription/Subscription.php
  7. +24
    -1
      domain/Subscription/Subscription/SubscriptionSolver.php
  8. +20
    -13
      producer/controllers/SubscriptionController.php
  9. +28
    -4
      producer/views/subscription/_form.php
  10. +1
    -1
      producer/views/subscription/index.php
  11. +21
    -2
      producer/web/js/vuejs/subscription-form.js

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



use common\components\View; use common\components\View;
use domain\Product\Rotating\Rotating; use domain\Product\Rotating\Rotating;
use domain\Product\RotatingProduct\RotatingProduct;
use yii\helpers\Html; use yii\helpers\Html;
use yii\grid\GridView; use yii\grid\GridView;


'label' => 'Produits', 'label' => 'Produits',
'format' => 'raw', 'format' => 'raw',
'value' => function(Rotating $rotating) { 'value' => function(Rotating $rotating) {
return implode(' ', array_map(function($rotatingProduct) {
return '<span class="label label-default">'.$rotatingProduct->getProduct()->name.'</span>';
}, $rotating->getRotatingProducts()));
return $rotating->getRotatingProductsListAsString(true);
} }
], ],
[ [

+ 2
- 22
backend/views/subscription/index.php View File

'headerOptions' => ['class' => 'column-hide-on-mobile'], 'headerOptions' => ['class' => 'column-hide-on-mobile'],
'filterOptions' => ['class' => 'column-hide-on-mobile'], 'filterOptions' => ['class' => 'column-hide-on-mobile'],
'contentOptions' => ['class' => 'column-hide-on-mobile'], 'contentOptions' => ['class' => 'column-hide-on-mobile'],
'value' => function($model) {
$productModule = ProductModule::getInstance();
$html = '' ;
foreach($model->productSubscription as $productSubscription)
{
if($productSubscription->getProduct()) {
$html .= Html::encode($productSubscription->getProduct()->name).' ('.($productSubscription->getQuantity() * Product::$unitsArray[$productSubscription->getProduct()->unit]['coefficient']).'&nbsp;'. $productModule->getSolver()->strUnit($productSubscription->getProduct(), 'wording_short').')<br />' ;
}
elseif($productSubscription->getRotating()) {
$html .= Html::encode($productSubscription->getRotating()->getName()).' ('.($productSubscription->getQuantity()).'&nbsp;p.)<br />' ;
}
else {
$html .= 'Produit non défini<br />' ;
}
}
// aucun produit
if(!count($model->productSubscription))
{
$html .= '<span class="glyphicon glyphicon-warning-sign"></span> Aucun produit<br />' ;
}
'value' => function($model) use ($subscriptionModule) {


return $html ;
return $subscriptionModule->getSolver()->getProductsListAsHtml($model);
} }
], ],
[ [

+ 0
- 41
domain/Order/Order/OrderBuilder.php View File

$order->date_update = date('Y-m-d H:i:s');; $order->date_update = date('Y-m-d H:i:s');;
} }


public function addProductOrdersFromSubscription(Order $order, Subscription $subscription): bool
{
$productsAdd = false;
$user = $subscription->user ?? null;
foreach ($subscription->productSubscription as $productSubscription) {

if($productSubscription->getProduct()) {
$product = $productSubscription->getProduct();
}
elseif($productSubscription->getRotating()) {
$product = RotatingResolver::getInstance()->getProductOfRotatingInDistribution(
$productSubscription->getRotating(),
$order->distribution
);
}

$this->productOrderBuilder->createProductOrder(
$order,
$product,
$productSubscription->getQuantity(),
(float) $this->productSolver->getPrice($product, [
'user' => $user,
'point_sale' => $subscription->pointSale,
'quantity' => $productSubscription->getQuantity()
])
);
$productsAdd = true;
}

return $productsAdd;
}

public function updateOrderFromSubscription(Order $order, Subscription $subscription): void
{
$this->initOrderBaseFromSubscription($order, $subscription);
$this->initOrderAutoPaymentFromSubscription($order, $subscription);
$this->addProductOrdersFromSubscription($order, $subscription);

$this->update($order);
}

public function initOrderBaseFromSubscription(Order $order, Subscription $subscription): void public function initOrderBaseFromSubscription(Order $order, Subscription $subscription): void
{ {
$order->origin = Order::ORIGIN_AUTO; $order->origin = Order::ORIGIN_AUTO;

+ 51
- 1
domain/Order/Order/OrderManager.php View File

use domain\Order\OrderStatus\OrderStatus; use domain\Order\OrderStatus\OrderStatus;
use domain\Order\OrderStatus\OrderStatusRepository; use domain\Order\OrderStatus\OrderStatusRepository;
use domain\Order\OrderStatusHistory\OrderStatusHistoryManager; use domain\Order\OrderStatusHistory\OrderStatusHistoryManager;
use domain\Order\ProductOrder\ProductOrderBuilder;
use domain\Producer\Producer\Producer; use domain\Producer\Producer\Producer;
use domain\Producer\Producer\ProducerSolver; use domain\Producer\Producer\ProducerSolver;
use domain\Product\Product\ProductSolver;
use domain\Product\Rotating\RotatingResolver;
use domain\Subscription\Subscription\Subscription; use domain\Subscription\Subscription\Subscription;
use domain\Subscription\Subscription\SubscriptionRepository; use domain\Subscription\Subscription\SubscriptionRepository;
use domain\Subscription\Subscription\SubscriptionSolver; use domain\Subscription\Subscription\SubscriptionSolver;
protected OrderSolver $orderSolver; protected OrderSolver $orderSolver;
protected SubscriptionSolver $subscriptionSolver; protected SubscriptionSolver $subscriptionSolver;
protected SubscriptionRepository $subscriptionRepository; protected SubscriptionRepository $subscriptionRepository;
protected ProductOrderBuilder $productOrderBuilder;
protected ProductSolver $productSolver;
protected RotatingResolver $rotatingResolver;


public function loadDependencies(): void public function loadDependencies(): void
{ {
$this->orderSolver = $this->loadService(OrderSolver::class); $this->orderSolver = $this->loadService(OrderSolver::class);
$this->subscriptionSolver = $this->loadService(SubscriptionSolver::class); $this->subscriptionSolver = $this->loadService(SubscriptionSolver::class);
$this->subscriptionRepository = $this->loadService(SubscriptionRepository::class); $this->subscriptionRepository = $this->loadService(SubscriptionRepository::class);
$this->productOrderBuilder = $this->loadService(ProductOrderBuilder::class);
$this->productSolver = $this->loadService(ProductSolver::class);
$this->rotatingResolver = $this->loadService(RotatingResolver::class);
} }


public function changeOrderStatus(Order $order, string $orderStatusAlias, User $user, \DateTime $date = null) public function changeOrderStatus(Order $order, string $orderStatusAlias, User $user, \DateTime $date = null)
return $return; return $return;
} }


public function addProductOrdersFromSubscription(Order $order, Subscription $subscription): bool
{
$productsAdd = false;
$user = $subscription->user ?? null;
foreach ($subscription->productSubscription as $productSubscription) {

if($productSubscription->getProduct()) {
$product = $productSubscription->getProduct();
}
elseif($productSubscription->getRotating()) {
$product = $this->rotatingResolver->getProductOfRotatingInDistribution(
$productSubscription->getRotating(),
$order->distribution
);
}

$this->productOrderBuilder->createProductOrder(
$order,
$product,
$productSubscription->getQuantity(),
(float) $this->productSolver->getPrice($product, [
'user' => $user,
'point_sale' => $subscription->pointSale,
'quantity' => $productSubscription->getQuantity()
])
);
$productsAdd = true;
}

return $productsAdd;
}

public function updateOrderFromSubscription(Order $order, Subscription $subscription): void
{
$this->orderBuilder->initOrderBaseFromSubscription($order, $subscription);
$this->orderBuilder->initOrderAutoPaymentFromSubscription($order, $subscription);
$this->addProductOrdersFromSubscription($order, $subscription);

$this->orderBuilder->update($order);
}

public function updateOrdersIncomingDistributionsFromSubscription(Subscription $subscription, User $userAction, $update = false): array public function updateOrdersIncomingDistributionsFromSubscription(Subscription $subscription, User $userAction, $update = false): array
{ {
$orderArray = []; $orderArray = [];
&& $subscription->pointSale) { && $subscription->pointSale) {


$order = $this->orderBuilder->createOrder($distribution); $order = $this->orderBuilder->createOrder($distribution);
$this->orderBuilder->updateOrderFromSubscription($order, $subscription);
$this->updateOrderFromSubscription($order, $subscription);
$this->changeOrderStatus($order, OrderStatus::ALIAS_ORDERED, $userAction); $this->changeOrderStatus($order, OrderStatus::ALIAS_ORDERED, $userAction);


return $order; return $order;

+ 10
- 0
domain/Product/Rotating/Rotating.php View File

use domain\Producer\Producer\Producer; use domain\Producer\Producer\Producer;
use domain\Product\RotatingProduct\RotatingProduct; use domain\Product\RotatingProduct\RotatingProduct;
use yii\db\ActiveQuery; use yii\db\ActiveQuery;
use yii\helpers\Html;


class Rotating extends ActiveRecordCommon class Rotating extends ActiveRecordCommon
{ {
} }
} }


/* Méthodes */

public function getRotatingProductsListAsString(bool $withHtmlLabel = true): string
{
return implode($withHtmlLabel ? ' ' : ', ', array_map(function(RotatingProduct $rotatingProduct) use ($withHtmlLabel) {
return ($withHtmlLabel ? '<span class="label label-default">' : '') . Html::encode($rotatingProduct->getProduct()->name) . ($withHtmlLabel ? '</span>' : '');
}, $this->getRotatingProducts()));
}

/* Getters / Setters */ /* Getters / Setters */


public function getId(): ?int public function getId(): ?int

+ 7
- 3
domain/Subscription/Subscription/Subscription.php View File

use common\components\ActiveRecordCommon; use common\components\ActiveRecordCommon;
use domain\PointSale\PointSale\PointSale; use domain\PointSale\PointSale\PointSale;
use domain\Producer\Producer\Producer; use domain\Producer\Producer\Producer;
use domain\Product\Product\Product;
use domain\Product\Rotating\Rotating;
use domain\Subscription\ProductSubscription\ProductSubscription; use domain\Subscription\ProductSubscription\ProductSubscription;
use domain\User\User\User; use domain\User\User\User;


]; ];
} }


/*
* Relations
*/
/* Méthodes */

/* Getters / Setters */

/* Relations */


public function getUser() public function getUser()
{ {

+ 24
- 1
domain/Subscription/Subscription/SubscriptionSolver.php View File



use domain\Product\Product\Product; use domain\Product\Product\Product;
use domain\Product\Product\ProductSolver; use domain\Product\Product\ProductSolver;
use domain\Product\Rotating\Rotating;
use domain\User\User\UserSolver; use domain\User\User\UserSolver;
use domain\_\AbstractService; use domain\_\AbstractService;
use domain\_\SolverInterface; use domain\_\SolverInterface;
foreach($subscription->productSubscription as $productSubscription) foreach($subscription->productSubscription as $productSubscription)
{ {
if($productSubscription->getProduct()) { if($productSubscription->getProduct()) {
$html .= '<strong>'.($productSubscription->getQuantity() * Product::$unitsArray[$productSubscription->getProduct()->unit]['coefficient']) . '&nbsp'. $this->productSolver->strUnit($productSubscription->getProduct(), 'wording_short') . '</strong> ' . Html::encode($productSubscription->getProduct()->name). '<br />' ;
$html .= '<strong>'.($productSubscription->getQuantity() * Product::$unitsArray[$productSubscription->getProduct()->unit]['coefficient']) . '&nbsp;'. $this->productSolver->strUnit($productSubscription->getProduct(), 'wording_short') . '</strong> ' . Html::encode($productSubscription->getProduct()->name). '<br />' ;
}
elseif($productSubscription->getRotating()) {
$html .= '<strong>'.$productSubscription->getQuantity() . '&nbsp;p.</strong> ' . Html::encode($productSubscription->getRotating()->getName()). '<br />' ;
} }
else { else {
$html .= 'Produit non défini<br />' ; $html .= 'Produit non défini<br />' ;
}, $subscriptionsArray) }, $subscriptionsArray)
); );
} }

public function getProductOrRotatingQuantity(Subscription $subscription, Product $product = null, Rotating $rotating = null): float
{
$quantity = 0;

if ($subscription->productSubscription && count($subscription->productSubscription)) {
foreach($subscription->productSubscription as $productSubscription) {
if ($product && $product->id == $productSubscription->id_product) {
$coefficientUnit = $this->productSolver->getUnitCoefficient($productSubscription->getProduct());
$quantity = $productSubscription->getQuantity() * $coefficientUnit;
}
if($rotating && $rotating->id == $productSubscription->id_rotating) {
$quantity = $productSubscription->getQuantity();
}
}
}

return $quantity;
}
} }

+ 20
- 13
producer/controllers/SubscriptionController.php View File



$posts = \Yii::$app->request->post(); $posts = \Yii::$app->request->post();


$idSubscription = (int)$posts['idSubscription'];
$idSubscription = (int) $posts['idSubscription'];
$isUpdate = false; $isUpdate = false;
if ($idSubscription) { if ($idSubscription) {
$subscription = $subscriptionModule->findOneSubscriptionById($idSubscription); $subscription = $subscriptionModule->findOneSubscriptionById($idSubscription);
$this->setFlash('error', 'Abonnement introuvable'); $this->setFlash('error', 'Abonnement introuvable');
} }



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


$user = $this->getUserCurrent(); $user = $this->getUserCurrent();
$userProducer = $this->getUserProducerModule()->findOneUserProducer($this->getUserCurrent()); $userProducer = $this->getUserProducerModule()->findOneUserProducer($this->getUserCurrent());
$pointSale = null; $pointSale = null;
$subscription = null;


if ($idSubscription > 0) { if ($idSubscription > 0) {
$arrayProductsSubscription = ProductSubscription::searchAll([ $arrayProductsSubscription = ProductSubscription::searchAll([
$productsArray = $productModule->findProducts(); $productsArray = $productModule->findProducts();
$indexProduct = 0; $indexProduct = 0;
foreach ($productsArray as &$product) { foreach ($productsArray as &$product) {
$quantity = 0;
$coefficientUnit = $productModule->getSolver()->getUnitCoefficient($product); $coefficientUnit = $productModule->getSolver()->getUnitCoefficient($product);
if (isset($arrayProductsSubscription) && count($arrayProductsSubscription)) {
foreach ($arrayProductsSubscription as $productSubscription) {
if ($product->id == $productSubscription->id_product) {
$coefficientUnit = $productModule->getSolver()->getUnitCoefficient($productSubscription->getProduct());
$quantity = $productSubscription->getQuantity() * $coefficientUnit;
}
}
}

$quantity = $subscription ? $subscriptionModule->getSolver()->getProductOrRotatingQuantity($subscription, $product) : 0;
$productPointSaleArray = []; $productPointSaleArray = [];
foreach($product->productPointSale as $productPointSale) { foreach($product->productPointSale as $productPointSale) {
$productPointSaleArray[] = $productPointSale->id_point_sale; $productPointSaleArray[] = $productPointSale->id_point_sale;
} }


$params['products'] = $productsArray; $params['products'] = $productsArray;

// Produits tournants
$rotatingsArray = $this->getRotatingModule()->getRepository()->findRotatings();
$rotatingsArrayReturn = [];
$indexRotating = 0;
foreach($rotatingsArray as $rotating) {
$indexRotating ++;
$quantity = $subscription ? $subscriptionModule->getSolver()->getProductOrRotatingQuantity($subscription, null, $rotating) : 0;
$rotatingsArrayReturn[$indexRotating] = array_merge($rotating->getAttributes(), [
'index' => $indexRotating,
'quantity_form' => $quantity,
'product_list_as_html' => $rotating->getRotatingProductsListAsString(false)
]);
}
$params['rotatings'] = $rotatingsArrayReturn;

// Points de vente
$pointsSaleArray = $this->getPointSaleModule()->findPointSalesByUserAccess($user); $pointsSaleArray = $this->getPointSaleModule()->findPointSalesByUserAccess($user);
foreach ($pointsSaleArray as &$pointSale) { foreach ($pointsSaleArray as &$pointSale) {
$pointSale = array_merge($pointSale->getAttributes(), [ $pointSale = array_merge($pointSale->getAttributes(), [

+ 28
- 4
producer/views/subscription/_form.php View File

<th>Nom</th> <th>Nom</th>
<th>Prix unitaire</th> <th>Prix unitaire</th>
<th>Quantité</th> <th>Quantité</th>
<th>Total</th>
<!--<th>Total</th>-->
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
</span> </span>
</div> </div>
</td> </td>
<td class="price-total">
<!--<td class="price-total">
<template v-if="product.quantity_form">{{ formatPrice(product.price_with_tax * (product.quantity_form / product.coefficient_unit )) }}</template> <template v-if="product.quantity_form">{{ formatPrice(product.price_with_tax * (product.quantity_form / product.coefficient_unit )) }}</template>
</td>-->
</tr>
<tr v-for="rotating in rotatings">
<td>
<div class="name">{{ rotating.name }} (produit tournant)</div>
<div class="description" v-html="rotating.product_list_as_html"></div>
</td>
<td class="price-unit"></td>
<td class="quantity">
<div class="input-group">
<span class="input-group-btn">
<button class="btn btn-secondary" type="button" @click="rotatingQuantityClick(rotating, -1)">
<span class="bi bi-dash-lg"></span>
</button>
</span>
<input type="text" v-model="rotating.quantity_form"
:class="'form-control '+((rotating.quantity_form > 0) ? 'has-quantity' : '')">
<span class="input-group-text">p.</span>
<span class="input-group-btn">
<button class="btn btn-secondary" type="button" @click="rotatingQuantityClick(rotating, 1)">
<span class="bi bi-plus-lg"></span>
</button>
</span>
</div>
</td> </td>
</tr> </tr>
<tr class="total">
<!--<tr class="total">
<td colspan="3"></td> <td colspan="3"></td>
<td class="price-total"> <td class="price-total">
<span>{{ priceTotal(true) }}</span> <span>{{ priceTotal(true) }}</span>
</td> </td>
</tr>
</tr>-->
</tbody> </tbody>
</table> </table>
<div v-if="!checkOneProductAvailable()" class="alert alert-warning"> <div v-if="!checkOneProductAvailable()" class="alert alert-warning">

+ 1
- 1
producer/views/subscription/index.php View File

'label' => 'Produits', 'label' => 'Produits',
'format' => 'raw', 'format' => 'raw',
'value' => function ($subscription) use ($subscriptionModule) { 'value' => function ($subscription) use ($subscriptionModule) {
return $subscriptionModule->getProductsListAsHtml($subscription);
return $subscriptionModule->getSolver()->getProductsListAsHtml($subscription);
} }
], ],
[ [

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

saturday: false, saturday: false,
sunday: false, sunday: false,
products: [], products: [],
rotatings: [],
errors: [], errors: [],
disableSubmitButton: false, disableSubmitButton: false,
lastCountDays: 0, lastCountDays: 0,
this.idSubscription = $('#subscription-id').val(); this.idSubscription = $('#subscription-id').val();
} }


//this.dateBegin = new Date();

axios.get("ajax-infos", {params: {idSubscription: this.idSubscription}}) axios.get("ajax-infos", {params: {idSubscription: this.idSubscription}})
.then(function (response) { .then(function (response) {


app.products = response.data.products; app.products = response.data.products;
app.rotatings = response.data.rotatings;
app.pointsSale = response.data.points_sale; app.pointsSale = response.data.points_sale;


if (app.idSubscription > 0) { if (app.idSubscription > 0) {
this.products[product.index].quantity_form += quantity; this.products[product.index].quantity_form += quantity;
} }
}, },
rotatingQuantityClick: function (rotating, quantity) {
if (this.rotatings[rotating.index].quantity_form + quantity >= 0) {
this.rotatings[rotating.index].quantity_form += quantity;
}
},
oneProductOrdered: function () { oneProductOrdered: function () {
for (var key in this.products) { for (var key in this.products) {
if (this.products[key].quantity_form > 0) { if (this.products[key].quantity_form > 0) {
return true; return true;
} }
} }
for (var keyRotating in this.rotatings) {
if (this.rotatings[keyRotating].quantity_form > 0) {
return true;
}
}
return false; return false;
}, },
formatPrice: formatPrice, formatPrice: formatPrice,
} }
} }


var rotatingsArray = {};
for (var keyRotating in this.rotatings) {
if (this.rotatings[keyRotating].quantity_form != null &&
this.rotatings[keyRotating].quantity_form > 0) {
rotatingsArray['rotating_' + this.rotatings[keyRotating].id] = this.rotatings[keyRotating].quantity_form;
}
}

axios.post('ajax-process', { axios.post('ajax-process', {
idSubscription: this.idSubscription, idSubscription: this.idSubscription,
SubscriptionForm: { SubscriptionForm: {
saturday: this.saturday == true ? 1 : 0, saturday: this.saturday == true ? 1 : 0,
sunday: this.sunday == true ? 1 : 0, sunday: this.sunday == true ? 1 : 0,
products: productsArray, products: productsArray,
rotatings: rotatingsArray,
comment: this.comment comment: this.comment
} }
}).then(function (response) { }).then(function (response) {

Loading…
Cancel
Save