@@ -601,31 +601,11 @@ class DistributionController extends BackendController | |||
'active' => $product->productDistribution[0]->active | |||
&& (!$pointSale || $productModule->isAvailableOnPointSale($product, $pointSale)), | |||
'invoice_price' => $invoicePrice, | |||
//'quantity_remaining' => $orderModule->getResolver()->getProductQuantityRemaining($product, $distribution, $order, $quantityForm), | |||
]; | |||
} | |||
// construction de $orderOverride | |||
$orderOverride = $order; | |||
if(!$orderOverride) { | |||
$orderOverride = new Order(); | |||
} | |||
$productOrderModule = $this->getProductOrderModule(); | |||
$productOrderObjectArray = []; | |||
foreach($productOrderArray as $idProduct => $productOrder) { | |||
if($productOrder['quantity']) { | |||
$product = $productModule->getRepository()->findOneProductById($idProduct); | |||
$productOrderObject = $productOrderModule->getBuilder()->instanciateProductOrder( | |||
$orderOverride, | |||
$product, | |||
$productOrder['quantity'], | |||
0 | |||
); | |||
$productOrderObjectArray[] = $productOrderObject; | |||
} | |||
} | |||
$orderOverride->populateRelation('productOrder', $productOrderObjectArray); | |||
$orderOverride = $orderModule->getBuilder()->instanciateOrderFromProductOrdersArray($productOrderArray, $order); | |||
foreach($productOrderArray as $idProduct => $productOrder) { | |||
$product = $productModule->getRepository()->findOneProductById($idProduct); | |||
$productOrderArray[$idProduct]['quantity_remaining'] = $orderModule->getResolver()->getProductQuantityRemaining($product, $distribution, $orderOverride); |
@@ -31,6 +31,7 @@ use domain\PointSale\UserPointSale\UserPointSaleRepository; | |||
use domain\Producer\Producer\Producer; | |||
use domain\Producer\Producer\ProducerRepository; | |||
use domain\Producer\Producer\ProducerSolver; | |||
use domain\Product\Product\ProductRepository; | |||
use domain\Product\Product\ProductSolver; | |||
use domain\Subscription\Subscription\Subscription; | |||
use domain\Subscription\Subscription\SubscriptionBuilder; | |||
@@ -67,6 +68,7 @@ class OrderBuilder extends AbstractBuilder | |||
protected DocumentSolver $documentSolver; | |||
protected ProducerSolver $producerSolver; | |||
protected OrderStatusRepository $orderStatusRepository; | |||
protected ProductRepository $productRepository; | |||
public function loadDependencies(): void | |||
{ | |||
@@ -93,6 +95,7 @@ class OrderBuilder extends AbstractBuilder | |||
$this->documentSolver = $this->loadService(DocumentSolver::class); | |||
$this->producerSolver = $this->loadService(ProducerSolver::class); | |||
$this->orderStatusRepository = $this->loadService(OrderStatusRepository::class); | |||
$this->productRepository = $this->loadService(ProductRepository::class); | |||
} | |||
public function instanciateOrder(Distribution $distribution): Order | |||
@@ -118,6 +121,48 @@ class OrderBuilder extends AbstractBuilder | |||
return $order; | |||
} | |||
public function instanciateOrderFromProductOrdersArray(array $productOrdersArray, Order $order = null): Order | |||
{ | |||
if(!$order) { | |||
$order = new Order(); | |||
$this->initOrderStatus($order); | |||
} | |||
$productOrderObjectArray = []; | |||
foreach($productOrdersArray as $idProduct => $productOrder) { | |||
if($productOrder['quantity']) { | |||
$product = $this->productRepository->findOneProductById($idProduct); | |||
$productOrderObject = $this->productOrderBuilder->instanciateProductOrder( | |||
$order, | |||
$product, | |||
$productOrder['quantity'], | |||
0 | |||
); | |||
$productOrderObjectArray[] = $productOrderObject; | |||
} | |||
} | |||
$order->populateRelation('productOrder', $productOrderObjectArray); | |||
return $order; | |||
} | |||
public function addOrUpdateOrderFromArray(Order $orderOverride, array $ordersArray): array | |||
{ | |||
$override = false; | |||
foreach($ordersArray as $key => $order) { | |||
if($order->id == $orderOverride->id) { | |||
$ordersArray[$key] = $orderOverride; | |||
$override = true; | |||
} | |||
} | |||
if(!$override) { | |||
$ordersArray[] = $orderOverride; | |||
} | |||
return $ordersArray; | |||
} | |||
public function initDateUpdate(Order $order) | |||
{ | |||
$order->date_update = date('Y-m-d H:i:s');; |
@@ -19,6 +19,7 @@ class OrderResolver extends AbstractResolver | |||
protected OrderRepository $orderRepository; | |||
protected ProductDistributionRepository $productDistributionRepository; | |||
protected FeatureChecker $featureChecker; | |||
protected OrderBuilder $orderBuilder; | |||
protected array $ordersArrayCachedByDistribution = []; | |||
@@ -29,6 +30,7 @@ class OrderResolver extends AbstractResolver | |||
$this->orderRepository = $this->loadService(OrderRepository::class); | |||
$this->productDistributionRepository = $this->loadService(ProductDistributionRepository::class); | |||
$this->featureChecker = $this->loadService(FeatureChecker::class); | |||
$this->orderBuilder = $this->loadService(OrderBuilder::class); | |||
} | |||
public function getProductQuantityByDistribution( | |||
@@ -42,24 +44,11 @@ class OrderResolver extends AbstractResolver | |||
$this->ordersArrayCachedByDistribution[$distribution->id] = $this->orderRepository->findOrdersByDistribution($distribution); | |||
} | |||
$ordersArray = $this->ordersArrayCachedByDistribution[$distribution->id]; | |||
// @TODO : sortir cette logique de la méthode (refactoring) | |||
if($orderOverride) { | |||
$override = false; | |||
foreach($ordersArray as $key => $order) { | |||
if($order->id == $orderOverride->id) { | |||
$ordersArray[$key] = $orderOverride; | |||
$override = true; | |||
} | |||
} | |||
if(!$override) { | |||
$ordersArray[] = $orderOverride; | |||
} | |||
$ordersArray = $this->orderBuilder->addOrUpdateOrderFromArray($orderOverride, $ordersArray); | |||
} | |||
$productQuantity = $this->orderSolver->getProductQuantity($product, $ordersArray); | |||
if($inNumberOfPieces) { | |||
$productQuantity = $this->productSolver->getNumberOfPieces($productQuantity, $product); | |||
} |
@@ -613,15 +613,16 @@ class OrderController extends ProducerBaseController | |||
return 0; | |||
} | |||
public function actionAjaxInfos(string $date = '', int $pointSaleId = 0) | |||
public function actionAjaxInfos(string $date = '', int $pointSaleId = 0, string $productsJson = null) | |||
{ | |||
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | |||
$productsArray = json_decode($productsJson, true); | |||
$user = GlobalParam::getCurrentUser(); | |||
$producer = $this->getProducerCurrent(); | |||
$pointSale = $this->getPointSaleModule()->findOnePointSaleById($pointSaleId); | |||
$order = $this->getOrderUser($date, $pointSale); | |||
return $this->buildJsonAjaxInfos($date, $producer, $pointSale, $user, $order); | |||
return $this->buildJsonAjaxInfos($date, $producer, $pointSale, $user, $order, $productsArray); | |||
} | |||
public function buildJsonAjaxInfos( | |||
@@ -629,7 +630,8 @@ class OrderController extends ProducerBaseController | |||
Producer $producer, | |||
PointSale $pointSale = null, | |||
User $user = null, | |||
Order $order = null | |||
Order $order = null, | |||
array $productsArray = null | |||
) | |||
{ | |||
$orderModule = $this->getOrderModule(); | |||
@@ -649,7 +651,7 @@ class OrderController extends ProducerBaseController | |||
$json['distribution'] = $distribution; | |||
$json['points_sale'] = $this->ajaxInfosPointsSale($producer, $distribution); | |||
$json['categories'] = $this->ajaxInfosProductCategories($producer); | |||
$json['products'] = $this->ajaxInfosProducts($producer, $distribution, $pointSale, $user, $order); | |||
$json['products'] = $this->ajaxInfosProducts($producer, $distribution, $pointSale, $user, $order, $productsArray); | |||
if ($order) { | |||
$json['order'] = array_merge($order->getAttributes(), [ | |||
@@ -931,7 +933,8 @@ class OrderController extends ProducerBaseController | |||
Distribution $distribution, | |||
PointSale $pointSale = null, | |||
User $user = null, | |||
Order $order = null | |||
Order $order = null, | |||
array $productsFormArray = null | |||
) | |||
{ | |||
$unitModule = $this->getUnitModule(); | |||
@@ -984,18 +987,32 @@ class OrderController extends ProducerBaseController | |||
$product['photo'] = Image::getThumbnailSmall($product['photo']); | |||
} | |||
//$product['quantity_max'] = (isset($product['productDistribution']) && isset($product['productDistribution'][0])) ? $product['productDistribution'][0]['quantity_max'] : null; | |||
$product['quantity_max'] = $orderModule->getResolver()->getProductQuantityMax($productObject, $distribution); | |||
$quantityOrder = $orderModule->getSolver()->getProductQuantity($productObject, $ordersArray); | |||
$quantityOrder = $orderModule->getResolver()->getProductQuantityByDistribution($productObject, $distribution); | |||
$product['quantity_ordered'] = $quantityOrder; | |||
$product['quantity_remaining'] = $product['quantity_max'] - $quantityOrder; | |||
$product['quantity_max'] = $orderModule->getResolver()->getProductQuantityMax($productObject, $distribution); | |||
$product['quantity_remaining'] = $orderModule->getResolver()->getProductQuantityRemaining($productObject, $distribution); | |||
$product['wording_unit'] = $unitModule->getSolver()->strUnit($product['unit'], UnitDefinition::WORDING_UNIT, true); | |||
$product['wording_unit_ref'] = $unitModule->getSolver()->strUnit($product['unit'], UnitDefinition::WORDING_SHORT, true); | |||
if ($order) { | |||
$quantityOrderUser = $orderModule->getSolver()->getProductQuantity($productObject, [$order], true); | |||
$orderOverride = $order; | |||
if(count($productsFormArray)) { | |||
$productOrdersArray = []; | |||
foreach($productsFormArray as $idProduct => $quantityProduct) { | |||
if($idProduct) { | |||
$productObject1 = $productModule->getRepository()->findOneProductById($idProduct); | |||
$productOrdersArray[$idProduct] = [ | |||
'quantity' => $quantityProduct / $productModule->getSolver()->getUnitCoefficient($productObject1) | |||
]; | |||
} | |||
} | |||
$orderOverride = $orderModule->getBuilder()->instanciateOrderFromProductOrdersArray($productOrdersArray, $orderOverride); | |||
} | |||
$quantityOrderUser = $orderModule->getSolver()->getProductQuantity($productObject, [$orderOverride], true); | |||
$product['quantity_ordered'] = $quantityOrder; | |||
$product['quantity_remaining'] = $product['quantity_max'] - $quantityOrder + $quantityOrderUser; | |||
$product['quantity_remaining'] = $orderModule->getResolver()->getProductQuantityRemaining($productObject, $distribution, $orderOverride); | |||
$product['quantity_form'] = $quantityOrderUser * $coefficient_unit; | |||
foreach ($order->productOrder as $productOrder) { | |||
if ($productOrder->id_product == $product['id']) { |
@@ -354,7 +354,7 @@ $this->setMeta('description', $producerModule->getSeoGenerator()->generateMetaDe | |||
<span v-if="product.weight">({{ product.weight }} g)</span> | |||
</span> | |||
<div> | |||
<span v-if="product.quantity_max > 0 && ((product.quantity_form / product.coefficient_unit == product.quantity_remaining) || ((product.quantity_remaining * product.coefficient_unit) - product.quantity_form) < product.step)" | |||
<span v-if="product.quantity_max > 0 && (product.quantity_remaining == 0 || product.quantity_remaining * product.coefficient_unit < product.step)" | |||
class="badge bg-danger">Épuisé</span> | |||
</div> | |||
<div class="description" v-if="product.description.length"> | |||
@@ -402,7 +402,7 @@ $this->setMeta('description', $producerModule->getSeoGenerator()->generateMetaDe | |||
<button class="btn btn-secondary btn-moins" | |||
type="button" | |||
@click="productQuantityClick(product, product.unit == 'piece' ? -1 : -parseFloat(product.step))" | |||
:disabled="product.quantity_form == 0"> | |||
:disabled="product.quantity_form == 0 || loadingProducts"> | |||
<i class="bi bi-dash-lg"></i></button> | |||
</span> | |||
<input type="text" v-model="product.quantity_form" | |||
@@ -412,7 +412,7 @@ $this->setMeta('description', $producerModule->getSeoGenerator()->generateMetaDe | |||
<button class="btn btn-secondary btn-plus" | |||
type="button" | |||
@click="productQuantityClick(product, product.unit == 'piece' ? 1 : parseFloat(product.step))" | |||
:disabled="(product.quantity_form / product.coefficient_unit) == product.quantity_remaining && product.quantity_max > 0"> | |||
:disabled="product.quantity_remaining == 0 || loadingProducts"> | |||
<i class="bi bi-plus-lg"></i></button> | |||
</span> | |||
</div> |
@@ -6,6 +6,7 @@ var app = new Vue({ | |||
return Object.assign({ | |||
order: null, | |||
loading: false, | |||
loadingProducts: false, | |||
loadingInit: true, | |||
step: null, | |||
producer: null, | |||
@@ -126,10 +127,15 @@ var app = new Vue({ | |||
} | |||
} | |||
}, | |||
init: function(type, oldStep, step) { | |||
init: function(type, loadingProducts) { | |||
var app = this ; | |||
this.loading = true ; | |||
if(loadingProducts) { | |||
this.loadingProducts = true ; | |||
} | |||
else { | |||
this.loading = true ; | |||
} | |||
if(app.isChangeState('date', 'date', 'point-sale')) { | |||
app.pointSaleActive = null ; | |||
@@ -138,7 +144,8 @@ var app = new Vue({ | |||
axios.get("ajax-infos",{params: { | |||
date : this.getDate(), | |||
pointSaleId: this.pointSaleActiveId ? this.pointSaleActiveId : (this.pointSaleActive ? this.pointSaleActive.id : 0) | |||
pointSaleId: this.pointSaleActiveId ? this.pointSaleActiveId : (this.pointSaleActive ? this.pointSaleActive.id : 0), | |||
productsJson: this.getProductsArray() | |||
}}) | |||
.then(function(response) { | |||
app.calendar.attrs = []; | |||
@@ -327,6 +334,7 @@ var app = new Vue({ | |||
}, 500); | |||
app.loading = false ; | |||
app.loadingProducts = false ; | |||
app.loadingInit = false ; | |||
}); | |||
}, | |||
@@ -412,7 +420,6 @@ var app = new Vue({ | |||
} | |||
}, | |||
changeStep: function(step) { | |||
this.errors = [] ; | |||
var oldStep = this.step ; | |||
@@ -489,12 +496,13 @@ var app = new Vue({ | |||
this.nextStep() ; | |||
}, | |||
productQuantityClick: function(product, quantity) { | |||
if( this.products[product.index].quantity_form + quantity >= 0 && | |||
(this.products[product.index].quantity_form + quantity <= (this.products[product.index].quantity_remaining * this.products[product.index].coefficient_unit) || | |||
!this.products[product.index].quantity_max) | |||
if(this.products[product.index].quantity_form + quantity >= 0 | |||
&& (quantity <= (this.products[product.index].quantity_remaining * this.products[product.index].coefficient_unit) | |||
|| this.products[product.index].quantity_remaining == null) | |||
) { | |||
var theQuantity = parseFloat(this.products[product.index].quantity_form) + parseFloat(quantity); | |||
this.products[product.index].quantity_form = parseFloat(theQuantity.toFixed(2)) ; | |||
this.init('first', true); | |||
} | |||
}, | |||
oneProductOrdered: function() { | |||
@@ -652,14 +660,7 @@ var app = new Vue({ | |||
} | |||
// products | |||
var productsArray = {} ; | |||
for(var key in this.products) { | |||
if( this.products[key].quantity_form != null && | |||
this.products[key].quantity_form > 0) { | |||
productsArray[this.products[key].id] = this.products[key].quantity_form ; | |||
} | |||
} | |||
var productsArray = this.getProductsArray(); | |||
app.disableConfirmButton = true ; | |||
axios.post('ajax-process', { | |||
@@ -691,6 +692,16 @@ var app = new Vue({ | |||
} | |||
}); | |||
}, | |||
getProductsArray: function() { | |||
var productsArray = {} ; | |||
for(var key in this.products) { | |||
if( this.products[key].quantity_form != null && | |||
this.products[key].quantity_form > 0) { | |||
productsArray[this.products[key].id] = this.products[key].quantity_form ; | |||
} | |||
} | |||
return productsArray; | |||
}, | |||
checkProducts: function() { | |||
if(!this.oneProductOrdered()) { | |||
this.errors.push('Veuillez sélectionner au moins un produit.') ; |