Browse Source

[Global] Prix dégressifs : affichage dynamique du prix en fonction du volume (formulaire ajout / modification commande) #250

refactoring
Guillaume 2 years ago
parent
commit
e32660f591
5 changed files with 104 additions and 26 deletions
  1. +35
    -7
      backend/controllers/DistributionController.php
  2. +4
    -3
      backend/views/product/update/prices/_form.php
  3. +1
    -1
      backend/views/product/update/prices/list.php
  4. +36
    -5
      backend/web/js/vuejs/distribution-index.js
  5. +28
    -10
      common/models/Product.php

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

]; ];
} }


public function actionAjaxUpdateProductOrder($idDistribution, $idUser = false, $idPointSale = false, $idOrder = false)
{
public function actionAjaxUpdateProductOrder(
$idDistribution,
$idUser = false,
$idPointSale = false,
$idOrder = false
) {
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;


$distribution = Distribution::findOne($idDistribution); $distribution = Distribution::findOne($idDistribution);


$productOrderArray = []; $productOrderArray = [];
foreach ($productsArray as $product) { foreach ($productsArray as $product) {
$priceArray = [];

// specific prices
$specificPriceArray = $product->getSpecificPricesFilterByPriorityMatch(
$product->productPrice,
$user,
$pointSale
);

foreach ($specificPriceArray as $specificPrice) {
$priceArray[] = [
'from_quantity' => $specificPrice->from_quantity ? $specificPrice->from_quantity : 0,
'price_with_tax' => $product->getPriceWithTax([
'user' => $user,
'user_producer' => $userProducer,
'point_sale' => $pointSale,
'quantity' => $specificPrice->from_quantity
]),
];
}

// base price
$priceArray[] = [
'from_quantity' => 0,
'price_with_tax' => $product->getPriceWithTax(),
];

$productOrderArray[$product['id']] = [ $productOrderArray[$product['id']] = [
'quantity' => 0, 'quantity' => 0,
'unit' => $product->unit, 'unit' => $product->unit,
'price' => $product->getPriceWithTax([
'user' => $user,
'user_producer' => $userProducer,
'point_sale' => $pointSale,
]),
'unit_coefficient' => Product::$unitsArray[$product->unit]['coefficient'],
'prices' => $priceArray,
'active' => $product->productDistribution[0]->active 'active' => $product->productDistribution[0]->active
&& (!$pointSale || $product->isAvailableOnPointSale($pointSale)) && (!$pointSale || $product->isAvailableOnPointSale($pointSale))
]; ];

+ 4
- 3
backend/views/product/update/prices/_form.php View File

<?= $form->field($model, 'id_user')->dropDownList(User::populateDropdownList()); ?> <?= $form->field($model, 'id_user')->dropDownList(User::populateDropdownList()); ?>
<?= $form->field($model, 'id_user_group')->dropDownList(UserGroup::populateDropdownList()); ?> <?= $form->field($model, 'id_user_group')->dropDownList(UserGroup::populateDropdownList()); ?>
<?= $form->field($model, 'id_point_sale')->dropDownList(PointSale::populateDropdownList()); ?> <?= $form->field($model, 'id_point_sale')->dropDownList(PointSale::populateDropdownList()); ?>
<?= $form->field($model, 'from_quantity')->label('À partir de la quantité ('.Product::strUnit($modelProduct->unit, 'wording').')'); ?>
<?= $form->field($model, 'from_quantity')->label('À partir de la quantité ('.Product::strUnit(Product::getRefUnit($modelProduct->unit), 'wording').')'); ?>


<?php <?php
$producer = GlobalParam::getCurrentProducer(); $producer = GlobalParam::getCurrentProducer();
$taxRateValue = $modelProduct->taxRate->value ; $taxRateValue = $modelProduct->taxRate->value ;
} }
?> ?>

<?= $form->field($model, 'price', [ <?= $form->field($model, 'price', [
'template' => ' 'template' => '
<div class="row"> <div class="row">
<div class="col-xs-6"> <div class="col-xs-6">
<label for="product-price" class="control-label without-tax">Prix ('.Product::strUnit($modelProduct->unit, 'wording_unit').') HT</label>
<label for="product-price" class="control-label without-tax">Prix ('.Product::strUnit(Product::getRefUnit($modelProduct->unit), 'wording_unit').') HT</label>
<div class="input-group"> <div class="input-group">
{input} <span class="input-group-addon"><span class="glyphicon glyphicon-euro"></span></span> {input} <span class="input-group-addon"><span class="glyphicon glyphicon-euro"></span></span>
</div> </div>
</div> </div>
<div class="col-xs-6"> <div class="col-xs-6">
<label for="productprice-price-with-tax" class="control-label with-tax">Prix ('.Product::strUnit($modelProduct->unit, 'wording_unit').') TTC</label>
<label for="productprice-price-with-tax" class="control-label with-tax">Prix ('.Product::strUnit(Product::getRefUnit($modelProduct->unit), 'wording_unit').') TTC</label>
<div class="input-group"> <div class="input-group">
<input type="text" id="productprice-price-with-tax" class="form-control" name="" value="" data-tax-rate-value="'.$taxRateValue.'"> <input type="text" id="productprice-price-with-tax" class="form-control" name="" value="" data-tax-rate-value="'.$taxRateValue.'">
<span class="input-group-addon"><span class="glyphicon glyphicon-euro"></span></span> <span class="input-group-addon"><span class="glyphicon glyphicon-euro"></span></span>

+ 1
- 1
backend/views/product/update/prices/list.php View File

'attribute' => 'from_quantity', 'attribute' => 'from_quantity',
'value' => function ($productPrice) { 'value' => function ($productPrice) {
if($productPrice->from_quantity) { if($productPrice->from_quantity) {
return $productPrice->from_quantity.' '.$productPrice->product->wording_unit;
return $productPrice->from_quantity.' '.Product::strUnit(Product::getRefUnit($productPrice->product->unit), 'wording');
} }


return '' ; return '' ;

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

if (response.data) { if (response.data) {
for (idProduct in response.data) { for (idProduct in response.data) {
if (app.showModalFormOrderCreate) { if (app.showModalFormOrderCreate) {
Vue.set(app.orderCreate.productOrder[idProduct], 'price', response.data[idProduct].price);
Vue.set(app.orderCreate.productOrder[idProduct], 'prices', response.data[idProduct].prices);
Vue.set(app.orderCreate.productOrder[idProduct], 'active', response.data[idProduct].active); Vue.set(app.orderCreate.productOrder[idProduct], 'active', response.data[idProduct].active);
Vue.set(app.orderCreate.productOrder[idProduct], 'unit_coefficient', response.data[idProduct].unit_coefficient);
} }


if (app.showModalFormOrderUpdate && app.idOrderUpdate) { if (app.showModalFormOrderUpdate && app.idOrderUpdate) {
for (keyOrderUpdate in app.ordersUpdate) { for (keyOrderUpdate in app.ordersUpdate) {
if (order.id == app.idOrderUpdate) { if (order.id == app.idOrderUpdate) {
Vue.set(app.ordersUpdate[keyOrderUpdate].productOrder[idProduct], 'price', response.data[idProduct].price);
Vue.set(app.ordersUpdate[keyOrderUpdate].productOrder[idProduct], 'prices', response.data[idProduct].prices);
Vue.set(app.ordersUpdate[keyOrderUpdate].productOrder[idProduct], 'active', response.data[idProduct].active); Vue.set(app.ordersUpdate[keyOrderUpdate].productOrder[idProduct], 'active', response.data[idProduct].active);
Vue.set(app.ordersUpdate[keyOrderUpdate].productOrder[idProduct], 'unit_coefficient', response.data[idProduct].unit_coefficient);
} }
} }
} }
this.order.productOrder[id_product].quantity = 0 ; this.order.productOrder[id_product].quantity = 0 ;
} }
if(parseFloat(this.order.productOrder[id_product].quantity) + quantity >= 0) { if(parseFloat(this.order.productOrder[id_product].quantity) + quantity >= 0) {
var theQuantity = parseFloat(this.order.productOrder[id_product].quantity) + parseFloat(quantity) ;
var theQuantity = (parseFloat(this.order.productOrder[id_product].quantity) + parseFloat(quantity)).toFixed(2);
var theQuantityDecimal = theQuantity % 1;
if(theQuantityDecimal == 0) {
theQuantity = parseInt(theQuantity);
}


Vue.set(this.order.productOrder, id_product, { Vue.set(this.order.productOrder, id_product, {
quantity: theQuantity.toFixed(2),
quantity: theQuantity,
unit: this.order.productOrder[id_product].unit, unit: this.order.productOrder[id_product].unit,
price: this.order.productOrder[id_product].price,
unit_coefficient: this.order.productOrder[id_product].unit_coefficient,
prices: this.order.productOrder[id_product].prices,
price: this.getBestProductPrice(id_product, theQuantity),
active: this.order.productOrder[id_product].active active: this.order.productOrder[id_product].active
}); });
} }
}, },
getBestProductPrice: function(id_product, theQuantity) {
var thePriceWithTax = 9999;
var pricesArray = this.order.productOrder[id_product].prices;
var unitCoefficient = this.order.productOrder[id_product].unit_coefficient;
if(theQuantity) {
theQuantity = theQuantity / unitCoefficient;
}

for(var i = 0; i < pricesArray.length ; i++) {
var priceWithTax = pricesArray[i].price_with_tax;
var fromQuantity = pricesArray[i].from_quantity;

if(priceWithTax < thePriceWithTax && fromQuantity <= theQuantity) {
thePriceWithTax = priceWithTax;
}
}
if(thePriceWithTax == 9999) {
return 0;
}
else {
return thePriceWithTax;
}
},
productPriceChange: function(event) { productPriceChange: function(event) {
var idProduct = event.currentTarget.getAttribute('data-id-product') ; var idProduct = event.currentTarget.getAttribute('data-id-product') ;
var price = parseFloat(event.currentTarget.value) ; var price = parseFloat(event.currentTarget.value) ;

+ 28
- 10
common/models/Product.php View File

'coefficient' => 1 'coefficient' => 1
], ],
'g' => [ 'g' => [
'ref_unit' => 'kg',
'unit' => 'g', 'unit' => 'g',
'wording_unit' => 'le g', 'wording_unit' => 'le g',
'wording' => 'g', 'wording' => 'g',
'coefficient' => 1 'coefficient' => 1
], ],
'mL' => [ 'mL' => [
'ref_unit' => 'L',
'unit' => 'mL', 'unit' => 'mL',
'wording_unit' => 'le mL', 'wording_unit' => 'le mL',
'wording' => 'mL', 'wording' => 'mL',
return $productGift; return $productGift;
} }


public function getRefUnit($unit)
{
if(isset(self::$unitsArray[$unit]) && isset(self::$unitsArray[$unit]['ref_unit'])) {
return self::$unitsArray[$unit]['ref_unit'];
}

return $unit;
}

/** /**
* Retourne le libellé d'une unité. * Retourne le libellé d'une unité.
* *
return $strUnit; return $strUnit;
} }


public function getSpecificPricesFilterByPriorityMatch($specificPrices, $user, $pointSale)
{
$priorityMatchSpecificPrice = ProductPrice::getPriorityMatchOfSpecificPriceArray($specificPrices, $user, $pointSale);

if($priorityMatchSpecificPrice) {
foreach($specificPrices as $keySpecificPrice => $specificPrice) {
if(!$specificPrice->$priorityMatchSpecificPrice($user, $pointSale)) {
unset($specificPrices[$keySpecificPrice]);
}
}
}

return $specificPrices;
}

public function getPrice($params = []) public function getPrice($params = [])
{ {
$specificPrices = $this->productPrice ; $specificPrices = $this->productPrice ;
$user = isset($params['user']) ? $params['user'] : false ; $user = isset($params['user']) ? $params['user'] : false ;
$userProducer = isset($params['user_producer']) ? $params['user_producer'] : false ; $userProducer = isset($params['user_producer']) ? $params['user_producer'] : false ;
$pointSale = isset($params['point_sale']) ? $params['point_sale'] : false ; $pointSale = isset($params['point_sale']) ? $params['point_sale'] : false ;
$quantity = isset($params['quantity']) ? $params['quantity'] : 1 ;
$quantity = (isset($params['quantity']) && $params['quantity']) ? $params['quantity'] : 1 ;


if($specificPrices && ($user || $pointSale)) { if($specificPrices && ($user || $pointSale)) {

$priorityMatchSpecificPrice = ProductPrice::getPriorityMatchOfSpecificPriceArray($specificPrices, $user, $pointSale);

foreach($specificPrices as $keySpecificPrice => $specificPrice) {
if(!$specificPrice->$priorityMatchSpecificPrice($user, $pointSale)) {
unset($specificPrices[$keySpecificPrice]);
}
}

$specificPrices = $this->getSpecificPricesFilterByPriorityMatch($specificPrices, $user, $pointSale);
$bestPrice = 9999; $bestPrice = 9999;
foreach($specificPrices as $specificPrice) { foreach($specificPrices as $specificPrice) {
$fromQuantity = $specificPrice->from_quantity; $fromQuantity = $specificPrice->from_quantity;

Loading…
Cancel
Save