Browse Source

[Boutique] Gestion des accessoires

feature/rotating_product
Guillaume Bourgeois 6 months ago
parent
commit
b13a9c4909
5 changed files with 240 additions and 204 deletions
  1. +19
    -4
      domain/Order/Order/OrderBuilder.php
  2. +23
    -10
      domain/Order/Order/OrderResolver.php
  3. +25
    -27
      producer/controllers/OrderController.php
  4. +2
    -2
      producer/views/order/order.php
  5. +171
    -161
      producer/web/js/vuejs/order-order.js

+ 19
- 4
domain/Order/Order/OrderBuilder.php View File

@@ -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\Product;
use domain\Product\Product\ProductRepository;
use domain\Product\Product\ProductSolver;
use domain\Subscription\Subscription\Subscription;
@@ -147,22 +148,36 @@ class OrderBuilder extends AbstractBuilder
return $order;
}

public function addOrUpdateOrderFromArray(Order $orderOverride, array $ordersArray): array
public function addOrUpdateOrIgnoreOrderFromArray(Order $orderOverride, array $ordersArray, bool $ignoreOrderCurrent = false): array
{
$override = false;
foreach($ordersArray as $key => $order) {
if($order->id == $orderOverride->id) {
$ordersArray[$key] = $orderOverride;
$override = true;
if($ignoreOrderCurrent) {
unset($ordersArray[$key]);
}
else {
$ordersArray[$key] = $orderOverride;
$override = true;
}
}
}
if(!$override) {
if(!$override && !$ignoreOrderCurrent) {
$ordersArray[] = $orderOverride;
}

return $ordersArray;
}

public function deleteProductOrderQuantity(Order $order, Product $product, float $quantity)
{
foreach($order->productOrder as $productOrder) {
if($productOrder->id_product == $product->id) {
$productOrder->quantity -= $quantity;
}
}
}

public function initDateUpdate(Order $order)
{
$order->date_update = date('Y-m-d H:i:s');;

+ 23
- 10
domain/Order/Order/OrderResolver.php View File

@@ -37,15 +37,16 @@ class OrderResolver extends AbstractResolver
Product $product,
Distribution $distribution,
bool $inNumberOfPieces = false,
Order $orderOverride = null
Order $orderCurrent = null,
bool $ignoreOrderCurrent = false
): float
{
if(!isset($this->ordersArrayCachedByDistribution[$distribution->id])) {
$this->ordersArrayCachedByDistribution[$distribution->id] = $this->orderRepository->findOrdersByDistribution($distribution);
}
$ordersArray = $this->ordersArrayCachedByDistribution[$distribution->id];
if($orderOverride) {
$ordersArray = $this->orderBuilder->addOrUpdateOrderFromArray($orderOverride, $ordersArray);
if($orderCurrent) {
$ordersArray = $this->orderBuilder->addOrUpdateOrIgnoreOrderFromArray($orderCurrent, $ordersArray, $ignoreOrderCurrent);
}

$productQuantity = $this->orderSolver->getProductQuantity($product, $ordersArray);
@@ -90,10 +91,16 @@ class OrderResolver extends AbstractResolver
return $quantityMax;
}

public function getProductQuantityMaxOrderable(Product $product, Distribution $distribution, Order $orderCurrent = null): ?float
{
return $this->getProductQuantityRemaining($product, $distribution, $orderCurrent, true);
}

public function getQuantityOfAccessoryAvailableInDistribution(
Accessory $accessory,
Distribution $distribution,
Order $orderOverride = null
Order $orderCurrent = null,
bool $ignoreOrderCurrent = false
): int
{
$quantityOfAccessoryUsed = 0;
@@ -103,7 +110,8 @@ class OrderResolver extends AbstractResolver
$productAccessory->getProduct(),
$distribution,
true,
$orderOverride
$orderCurrent,
$ignoreOrderCurrent
);
}

@@ -113,7 +121,8 @@ class OrderResolver extends AbstractResolver
public function getSmallestQuantityAccessoryAvailable(
Product $product,
Distribution $distribution,
Order $orderOverride = null
Order $orderCurrent = null,
bool $ignoreOrderCurrent = false
): ?int
{
$smallestQuantity = null;
@@ -123,7 +132,8 @@ class OrderResolver extends AbstractResolver
$quantityAccessoryAvailableInDistribution = $this->getQuantityOfAccessoryAvailableInDistribution(
$productAccessory->getAccessory(),
$distribution,
$orderOverride
$orderCurrent,
$ignoreOrderCurrent
);
$smallestQuantity = is_null($smallestQuantity) ? $quantityAccessoryAvailableInDistribution
: min($smallestQuantity, $quantityAccessoryAvailableInDistribution);
@@ -136,7 +146,8 @@ class OrderResolver extends AbstractResolver
public function getProductQuantityRemaining(
Product $product,
Distribution $distribution,
Order $orderOverride = null
Order $orderCurrent = null,
bool $ignoreOrderCurrent = false
): ?float
{
$productDistribution = $this->productDistributionRepository->findOneProductDistribution($distribution, $product);
@@ -148,7 +159,8 @@ class OrderResolver extends AbstractResolver
$product,
$distribution,
false,
$orderOverride
$orderCurrent,
$ignoreOrderCurrent
);
$quantityRemaining = is_null($productDistribution->quantity_max) ? null
: ($productDistribution->quantity_max - $quantityOrder);
@@ -158,7 +170,8 @@ class OrderResolver extends AbstractResolver
$smallestQuantityAccessoryAvailable = $this->getSmallestQuantityAccessoryAvailable(
$product,
$distribution,
$orderOverride
$orderCurrent,
$ignoreOrderCurrent
);
if (!is_null($smallestQuantityAccessoryAvailable)) {
$smallestQuantityAccessoryAvailable = $this->productSolver->getWeightOrNumberOfPieces($smallestQuantityAccessoryAvailable, $product);

+ 25
- 27
producer/controllers/OrderController.php View File

@@ -964,6 +964,20 @@ class OrderController extends ProducerBaseController

$productsArrayFilter = $productModule->filterProductsByPointSale($productsArray, $pointSale);

$orderCurrent = $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)
];
}
}
$orderCurrent = $orderModule->getBuilder()->instanciateOrderFromProductOrdersArray($productOrdersArray, $orderCurrent);
}

$indexProduct = 0;
foreach ($productsArrayFilter as $key => &$product) {
$productObject = $product;
@@ -978,8 +992,6 @@ class OrderController extends ProducerBaseController
]
);

$coefficient_unit = Product::$unitsArray[$product['unit']]['coefficient'];

if (is_null($product['photo']) || strlen($product['photo']) == 0) {
$product['photo'] = '';
}
@@ -988,32 +1000,22 @@ class OrderController extends ProducerBaseController
$product['photo'] = Image::getThumbnailSmall($product['photo']);
}

$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);
}

$quantityOrder = $orderModule->getResolver()->getProductQuantityByDistribution($productObject, $distribution, false, $orderOverride);
$product['quantity_ordered'] = $quantityOrder;
$product['quantity_max'] = $orderModule->getResolver()->getProductQuantityMax($productObject, $distribution);
$product['quantity_remaining'] = $orderModule->getResolver()->getProductQuantityRemaining($productObject, $distribution);
$coefficientUnit = Product::$unitsArray[$product['unit']]['coefficient'];
$product['coefficient_unit'] = $coefficientUnit;
$product['quantity_max'] = $orderModule->getResolver()->getProductQuantityMaxOrderable($productObject, $distribution, $orderCurrent);
$product['quantity_remaining'] = $orderModule->getResolver()->getProductQuantityRemaining($productObject, $distribution, $orderCurrent);
$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);
$quantityOrderUser = $orderModule->getSolver()->getProductQuantity($productObject, $orderOverride ? [$orderOverride] : [], true);
$product['quantity_form'] = $quantityOrderUser * $coefficient_unit;
$quantityOrderUser = $orderModule->getSolver()->getProductQuantity($productObject, $orderCurrent ? [$orderCurrent] : [], true);
$product['quantity_form'] = $quantityOrderUser * $coefficientUnit;
if($product['quantity_remaining'] < 0 && $product['quantity_form']) {
$product['quantity_form'] = $product['quantity_form'] + ($product['quantity_remaining'] * $coefficientUnit);
$orderModule->getBuilder()->deleteProductOrderQuantity($orderCurrent, $productObject, abs($product['quantity_remaining']));
$product['quantity_remaining'] = $orderModule->getResolver()->getProductQuantityRemaining($productObject, $distribution, $orderCurrent);
}
$product['wording_unit'] = $unitModule->getSolver()->strUnit($product['unit'], 'wording_unit', true);

if ($order) {
$product['quantity_remaining'] = $orderModule->getResolver()->getProductQuantityRemaining($productObject, $distribution, $orderOverride);
foreach ($order->productOrder as $productOrder) {
if ($productOrder->id_product == $product['id']) {
$product['wording_unit'] = $productModule->getSolver()->strUnit($productOrder->product, 'wording_unit', true);
@@ -1021,11 +1023,7 @@ class OrderController extends ProducerBaseController
}
}
}
$product['coefficient_unit'] = $coefficient_unit;

if ($product['quantity_remaining'] < 0) {
$product['quantity_remaining'] = 0;
}
$product['index'] = $indexProduct++;
}


+ 2
- 2
producer/views/order/order.php View File

@@ -354,7 +354,7 @@ $this->setMeta('description', $producerModule->getSeoGenerator()->generateMetaDe
<span v-if="product.weight">({{ product.weight }}&nbsp;g)</span>
</span>
<div>
<span v-if="product.quantity_max > 0 && (product.quantity_remaining == 0 || product.quantity_remaining * product.coefficient_unit < 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">
@@ -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_remaining == 0 || loadingProducts">
:disabled="product.quantity_remaining <= 0 || product.quantity_form >= product.quantity_max || loadingProducts">
<i class="bi bi-plus-lg"></i></button>
</span>
</div>

+ 171
- 161
producer/web/js/vuejs/order-order.js View File

@@ -8,6 +8,7 @@ var app = new Vue({
loading: false,
loadingProducts: false,
loadingInit: true,
cancelTokenSource: null,
step: null,
producer: null,
user: null,
@@ -131,7 +132,9 @@ var app = new Vue({
var app = this ;

if(loadingProducts) {
this.loadingProducts = true ;
if(app.cancelTokenSource !== null) {
app.cancelTokenSource.cancel();
}
}
else {
this.loading = true ;
@@ -142,201 +145,207 @@ var app = new Vue({
app.products = [] ;
}

axios.get("ajax-infos",{params: {
date : this.getDate(),
pointSaleId: this.pointSaleActiveId ? this.pointSaleActiveId : (this.pointSaleActive ? this.pointSaleActive.id : 0),
productsJson: this.getProductsArray(),
loadingProducts: loadingProducts
app.cancelTokenSource = axios.CancelToken.source();
axios.get("ajax-infos",{
cancelToken: app.cancelTokenSource.token,
params: {
date : this.getDate(),
pointSaleId: this.pointSaleActiveId ? this.pointSaleActiveId : (this.pointSaleActive ? this.pointSaleActive.id : 0),
productsJson: this.getProductsArray(),
loadingProducts: loadingProducts
}})
.catch(function (thrown) {
if (axios.isCancel(thrown)) {
//console.log('Request canceled', thrown.message);
//return Promise.reject(thrown);
}
})
.then(function(response) {
app.calendar.attrs = [];
app.calendar.availableDates = [];

var distributions = response.data.distributions;
app.distributions = distributions;
if (distributions.length) {
var arrayDate;
var highlightStyle = {
style: {
background: 'white',
border: 'solid 2px #198754'
},
contentStyle: {
color: '#198754'
}
};
for (var i = 0; i < distributions.length; i++) {
app.calendar.attrs.push({
highlight: highlightStyle,
dates: distributions[i].date
});
if(response) {
app.calendar.attrs = [];
app.calendar.availableDates = [];

var distributions = response.data.distributions;
app.distributions = distributions;
if (distributions.length) {
var arrayDate;
var highlightStyle = {
style: {
background: 'white',
border: 'solid 2px #198754'
},
contentStyle: {
color: '#198754'
}
};
for (var i = 0; i < distributions.length; i++) {
app.calendar.attrs.push({
highlight: highlightStyle,
dates: distributions[i].date
});

arrayDate = distributions[i].date.split('-');
app.calendar.availableDates.push({
highlight: highlightStyle,
start: new Date(arrayDate[0], arrayDate[1] - 1, arrayDate[2]),
end: new Date(arrayDate[0], arrayDate[1] - 1, arrayDate[2])
});
arrayDate = distributions[i].date.split('-');
app.calendar.availableDates.push({
highlight: highlightStyle,
start: new Date(arrayDate[0], arrayDate[1] - 1, arrayDate[2]),
end: new Date(arrayDate[0], arrayDate[1] - 1, arrayDate[2])
});
}
}
}

if(response.data.leave_period) {
leavePeriodStartDateArray = response.data.leave_period.start.split('-');
leavePeriodEndDateArray = response.data.leave_period.end.split('-');
if (response.data.leave_period) {
leavePeriodStartDateArray = response.data.leave_period.start.split('-');
leavePeriodEndDateArray = response.data.leave_period.end.split('-');

app.calendar.attrs.push({
highlight: {
style: {
//background: '#E09F3E'
background: 'gray'
app.calendar.attrs.push({
highlight: {
style: {
//background: '#E09F3E'
background: 'gray'
},
contentStyle: {
color: 'white'
}
},
contentStyle: {
color: 'white'
}
},
dates: {
start: new Date(leavePeriodStartDateArray[0], leavePeriodStartDateArray[1] - 1, leavePeriodStartDateArray[2]),
end: new Date(leavePeriodEndDateArray[0], leavePeriodEndDateArray[1] - 1, leavePeriodEndDateArray[2])
},
popover: {
label: 'En congé',
hideIndicator: true,
isInteractive: true
},
});
}
dates: {
start: new Date(leavePeriodStartDateArray[0], leavePeriodStartDateArray[1] - 1, leavePeriodStartDateArray[2]),
end: new Date(leavePeriodEndDateArray[0], leavePeriodEndDateArray[1] - 1, leavePeriodEndDateArray[2])
},
popover: {
label: 'En congé',
hideIndicator: true,
isInteractive: true
},
});
}

if (response.data.distribution) {
app.distribution = response.data.distribution;
}
if (response.data.distribution) {
app.distribution = response.data.distribution;
}

var orders = [];
if (response.data.orders) {
orders = response.data.orders;
}
var orders = [];
if (response.data.orders) {
orders = response.data.orders;
}

if (orders.length) {
for (var i = 0; i < orders.length; i++) {
arrayDate = orders[i].date_distribution.split('-');
var dateOrder = new Date(arrayDate[0], arrayDate[1] - 1, arrayDate[2]);
if (app.isAvailableDate(dateOrder)) {
app.calendar.attrs.push({
highlight: {
style: {
background: '#198754'
if (orders.length) {
for (var i = 0; i < orders.length; i++) {
arrayDate = orders[i].date_distribution.split('-');
var dateOrder = new Date(arrayDate[0], arrayDate[1] - 1, arrayDate[2]);
if (app.isAvailableDate(dateOrder)) {
app.calendar.attrs.push({
highlight: {
style: {
background: '#198754'
},
contentStyle: {
color: 'white'
}
},
contentStyle: {
color: 'white'
}
},
popover: {
label: orders[i].pointSale.name + ' (' + app.formatPrice(orders[i].amount_total)+')',
hideIndicator: true,
isInteractive: true
},
dates: orders[i].date_distribution
});
popover: {
label: orders[i].pointSale.name + ' (' + app.formatPrice(orders[i].amount_total) + ')',
hideIndicator: true,
isInteractive: true
},
dates: orders[i].date_distribution
});
}
}
}
}

app.producer = response.data.producer;
app.user = response.data.user;
app.useCredit = response.data.producer.use_credit_checked_default;
app.producer = response.data.producer;
app.user = response.data.user;
app.useCredit = response.data.producer.use_credit_checked_default;


if (response.data.points_sale) {
app.pointsSale = [];
var orderPointSale = 0;
for (var key in response.data.points_sale) {
response.data.points_sale[key].order = orderPointSale++;
app.pointsSale[response.data.points_sale[key].id] = response.data.points_sale[key];
if (response.data.points_sale) {
app.pointsSale = [];
var orderPointSale = 0;
for (var key in response.data.points_sale) {
response.data.points_sale[key].order = orderPointSale++;
app.pointsSale[response.data.points_sale[key].id] = response.data.points_sale[key];

if(!app.pointsSaleCodes[response.data.points_sale[key].id]) {
app.pointsSaleCodes[response.data.points_sale[key].id] = '';
Vue.set(app.pointsSaleCodes, response.data.points_sale[key].id, '');
if (!app.pointsSaleCodes[response.data.points_sale[key].id]) {
app.pointsSaleCodes[response.data.points_sale[key].id] = '';
Vue.set(app.pointsSaleCodes, response.data.points_sale[key].id, '');
}
}
}
}

if(app.pointSaleActiveId) {
app.pointSaleActive = app.getPointSale(app.pointSaleActiveId);
}

if(app.pointSaleActive) {
if(app.producer.credit
&& app.pointSaleActive.payment_method_credit
&& (app.pointSaleActive.credit_functioning == 'mandatory'
|| (app.pointSaleActive.credit_functioning == 'user' && app.user.credit_active)
|| (app.pointSaleActive.credit_functioning == 'optional' && response.data.producer.use_credit_checked_default))) {
app.paymentMethod = 'credit';
if (app.pointSaleActiveId) {
app.pointSaleActive = app.getPointSale(app.pointSaleActiveId);
}
else if(app.pointSaleActive.payment_method_onsite) {
app.paymentMethod = 'onsite';

if (app.pointSaleActive) {
if (app.producer.credit
&& app.pointSaleActive.payment_method_credit
&& (app.pointSaleActive.credit_functioning == 'mandatory'
|| (app.pointSaleActive.credit_functioning == 'user' && app.user.credit_active)
|| (app.pointSaleActive.credit_functioning == 'optional' && response.data.producer.use_credit_checked_default))) {
app.paymentMethod = 'credit';
} else if (app.pointSaleActive.payment_method_onsite) {
app.paymentMethod = 'onsite';
} else if (app.pointSaleActive.payment_method_online) {
app.paymentMethod = 'online';
}
}
else if(app.pointSaleActive.payment_method_online) {
app.paymentMethod = 'online';

if (app.isChangeState('point-sale', 'point-sale', 'date')) {
app.date = null;
app.dateFormat = null;
}
}

if(app.isChangeState('point-sale', 'point-sale', 'date')) {
app.date = null ;
app.dateFormat = null ;
}
// update order
var updateOrder = false;
if (app.isChangeState('date', 'point-sale', 'products')
|| app.isChangeState('date', 'date', 'point-sale')
|| app.isChangeState('point-sale', 'date', 'products')
|| app.isChangeState('point-sale', 'point-sale', 'date')) {

// update order
var updateOrder = false ;
if(app.isChangeState('date', 'point-sale', 'products')
|| app.isChangeState('date', 'date', 'point-sale')
|| app.isChangeState('point-sale', 'date', 'products')
|| app.isChangeState('point-sale', 'point-sale', 'date')) {
updateOrder = true;
}

updateOrder = true ;
}
if (updateOrder) {
app.updateOrder(response);
}

if(updateOrder) {
app.updateOrder(response);
}
if (type == 'first') {
if (app.getDate() && app.pointSaleActive) {
app.step = 'products';
if (response.data.products) {
app.products = response.data.products;
}

if(type == 'first') {
if(app.getDate() && app.pointSaleActive) {
app.step = 'products' ;
if(response.data.products) {
app.products = response.data.products;
app.updateOrder(response);
} else if (app.producer.option_order_entry_point == 'point-sale') {
app.step = 'point-sale';
} else if (app.getDate() && app.producer && app.producer.option_order_entry_point == 'date') {
app.step = 'point-sale';
} else {
app.step = 'date';
}

app.updateOrder(response);
}
else if(app.producer.option_order_entry_point == 'point-sale') {
app.step = 'point-sale' ;
}
else if(app.getDate() && app.producer && app.producer.option_order_entry_point == 'date') {
app.step = 'point-sale' ;
}
else {
app.step = 'date' ;
}
}

if(response.data.categories) {
app.categories = response.data.categories ;
for(keyCategory in response.data.categories) {
var category = response.data.categories[keyCategory];
if(category.id && app.countProductsByCategory(category)) {
app.setCategoryCurrent(category, true) ;
break;
if (response.data.categories) {
app.categories = response.data.categories;
for (keyCategory in response.data.categories) {
var category = response.data.categories[keyCategory];
if (category.id && app.countProductsByCategory(category)) {
app.setCategoryCurrent(category, true);
break;
}
}
}
}

setTimeout(function() {
app.responsive();
opendistrib_products();
}, 500);
setTimeout(function () {
app.responsive();
opendistrib_products();
}, 500);

app.loading = false ;
app.loadingProducts = false ;
app.loadingInit = false ;
app.loading = false;
app.loadingProducts = false;
app.loadingInit = false;
}
});
},
updateOrder: function(response) {
@@ -498,6 +507,7 @@ var app = new Vue({
},
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_max * this.products[product.index].coefficient_unit
&& (quantity <= (this.products[product.index].quantity_remaining * this.products[product.index].coefficient_unit)
|| this.products[product.index].quantity_remaining == null)
) {

Loading…
Cancel
Save