@@ -182,19 +182,25 @@ class DistributionController extends BackendController | |||
$json['distribution']['weight'] = number_format($weight, 2); | |||
// products | |||
$productsArray = Product::find() | |||
->orWhere(['id_producer' => GlobalParam::getCurrentProducerId(),]) | |||
->joinWith([ | |||
'taxRate', | |||
'productDistribution' => function ($query) use ($distribution) { | |||
$query->andOnCondition( | |||
'product_distribution.id_distribution = ' . $distribution->id | |||
); | |||
} | |||
]) | |||
->orderBy('product_distribution.active DESC, order ASC') | |||
->asArray() | |||
->all(); | |||
$productsQuery = Product::find() | |||
->orWhere(['id_producer' => GlobalParam::getCurrentProducerId(),]) | |||
->joinWith([ | |||
'taxRate', | |||
'productDistribution' => function ($query) use ($distribution) { | |||
$query->andOnCondition( | |||
'product_distribution.id_distribution = ' . $distribution->id | |||
); | |||
} | |||
]) | |||
->orderBy('product_distribution.active DESC, order ASC'); | |||
/*$productsObjectsArray = $productsQuery->all(); | |||
foreach($productsObjectsArray as $product) { | |||
$productsObjectsArray[$product->id] = $product; | |||
}*/ | |||
$productsArray = $productsQuery->asArray()->all(); | |||
$potentialRevenues = 0; | |||
$potentialWeight = 0; | |||
@@ -235,21 +241,30 @@ class DistributionController extends BackendController | |||
$ordersArrayObject = $ordersArray; | |||
if ($ordersArray) { | |||
foreach ($ordersArray as &$order) { | |||
$user = $order->user ? : null; | |||
$pointSale = $order->pointSale ? : null; | |||
$productOrderArray = []; | |||
foreach ($order->productOrder as $productOrder) { | |||
//$product = isset($productsObjectsArray[$productOrder->id_product]) ? $productsObjectsArray[$productOrder->id_product] : null; | |||
$productOrderArray[$productOrder->id_product] = [ | |||
'quantity' => $productOrder->quantity * Product::$unitsArray[$productOrder->unit]['coefficient'], | |||
'unit' => $productOrder->unit, | |||
'price' => Price::getPriceWithTax($productOrder->price, $productOrder->taxRate->value) | |||
'price' => $productOrder->price, | |||
'price_with_tax' => Price::getPriceWithTax($productOrder->price, $productOrder->taxRate->value), | |||
//'prices' => $product ? $product->getPriceArray($user, $pointSale) : [] | |||
]; | |||
} | |||
foreach ($productsArray as $product) { | |||
//$productObject = isset($productsObjectsArray[$productOrder->id_product]) ? $productsObjectsArray[$productOrder->id_product] : null; | |||
if (!isset($productOrderArray[$product['id']])) { | |||
$productOrderArray[$product['id']] = [ | |||
'quantity' => 0, | |||
'unit' => $product['unit'], | |||
'price' => Price::getPriceWithTax($product['price'], $product['taxRate']['value']), | |||
'price' => $product['price'], | |||
'price_with_tax' => Price::getPriceWithTax($product['price'], $product['taxRate']['value']), | |||
//'prices' => $productObject ? $productObject->getPriceArray($user, $pointSale) : [] | |||
]; | |||
} | |||
} | |||
@@ -453,7 +468,6 @@ class DistributionController extends BackendController | |||
$productsArray = Product::find() | |||
->where([ | |||
'id_producer' => GlobalParam::getCurrentProducerId(), | |||
'product.active' => 1, | |||
])->joinWith([ | |||
'productPrice', | |||
'productDistribution' => function ($q) use ($distribution) { |
@@ -633,7 +633,7 @@ $this->setPageTitle('Distributions') ; | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr v-for="product in products" :class="(order.productOrder[product.id] > 0) ? 'product-ordered' : ''"> | |||
<tr v-for="product in products" :class="(order.productOrder[product.id].quantity > 0) ? 'product-ordered' : ''"> | |||
<td> | |||
<span class="label label-success" v-if="loadingUpdateProductOrder || order.productOrder[product.id].active">Actif</span> | |||
<span class="label label-danger" v-else>Inactif</span> | |||
@@ -641,7 +641,11 @@ $this->setPageTitle('Distributions') ; | |||
<td>{{ product.name }}</td> | |||
<td class="price"> | |||
<div class="input-group"> | |||
<input type="text" v-model="order.productOrder[product.id].price" class="form-control" @change="productPriceChange" :data-id-product="product.id" /> | |||
<input type="text" v-model="order.productOrder[product.id].price" class="form-control input-sm" @change="productPriceChange" :data-with-tax="false" :data-id-product="product.id" /> | |||
<span class="input-group-addon" id="basic-addon2">€ HT </span> | |||
</div> | |||
<div class="input-group"> | |||
<input type="text" v-model="order.productOrder[product.id].price_with_tax" class="form-control input-sm" @change="productPriceChange" :data-with-tax="true" :data-id-product="product.id" /> | |||
<span class="input-group-addon" id="basic-addon2">€ TTC</span> | |||
</div> | |||
</td> | |||
@@ -650,7 +654,7 @@ $this->setPageTitle('Distributions') ; | |||
<span class="input-group-btn"> | |||
<button class="btn btn-default btn-moins" type="button" @click="productQuantityClick(product.id, order.productOrder[product.id].unit == 'piece' ? -1 : -parseFloat(product.step))"><span class="glyphicon glyphicon-minus"></span></button> | |||
</span> | |||
<input type="text" v-model="order.productOrder[product.id].quantity" class="form-control" /> | |||
<input type="text" v-model="order.productOrder[product.id].quantity" class="form-control input-quantity" /> | |||
<span class="input-group-addon">{{ order.productOrder[product.id].unit == 'piece' ? 'p.' : order.productOrder[product.id].unit }}</span> | |||
<span class="input-group-btn"> | |||
<button class="btn btn-default btn-plus" type="button" @click="productQuantityClick(product.id, order.productOrder[product.id].unit == 'piece' ? 1 : parseFloat(product.step))"><span class="glyphicon glyphicon-plus"></span></button> | |||
@@ -673,6 +677,7 @@ $this->setPageTitle('Distributions') ; | |||
<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-else>Créer</button> | |||
<button class="modal-default-button btn btn-default" @click="updateProductOrderPrices(true)">Recharger les prix</button> | |||
<button class="modal-default-button btn btn-default" @click="$emit('close')">Annuler</button> | |||
</div> | |||
</div> |
@@ -1720,22 +1720,23 @@ body.login-page .login-box .login-box-body a:hover { | |||
right: 15px; | |||
width: 300px; | |||
height: auto; | |||
z-index: 9999; | |||
} | |||
/* line 9, ../sass/_alerts.scss */ | |||
/* line 10, ../sass/_alerts.scss */ | |||
#app-alerts .slide-fade-enter-active { | |||
-moz-transition: all 0.3s ease; | |||
-o-transition: all 0.3s ease; | |||
-webkit-transition: all 0.3s ease; | |||
transition: all 0.3s ease; | |||
} | |||
/* line 12, ../sass/_alerts.scss */ | |||
/* line 13, ../sass/_alerts.scss */ | |||
#app-alerts .slide-fade-leave-active { | |||
-moz-transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1); | |||
-o-transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1); | |||
-webkit-transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1); | |||
transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1); | |||
} | |||
/* line 15, ../sass/_alerts.scss */ | |||
/* line 16, ../sass/_alerts.scss */ | |||
#app-alerts .slide-fade-enter, #app-alerts .slide-fade-leave-to { | |||
-moz-transform: translateX(10px); | |||
-ms-transform: translateX(10px); | |||
@@ -2190,7 +2191,7 @@ termes. | |||
background-color: #e9e9e9; | |||
} | |||
/* line 370, ../sass/distribution/_index.scss */ | |||
.distribution-index .modal-form-order table.table-products .product-ordered input { | |||
.distribution-index .modal-form-order table.table-products .product-ordered input.input-quantity { | |||
font-size: 16px; | |||
font-weight: bold; | |||
} |
@@ -139,7 +139,7 @@ function opendistrib_products_event_price_with_tax() { | |||
taxRateSelected = 0; | |||
} | |||
var price = $('#product-price').val(); | |||
var price = $('#product-price').val().replace(',', '.'); | |||
if (price) { | |||
$('#product-price-with-tax').val(getPriceWithTax(price, taxRateSelected)); | |||
// formattage | |||
@@ -211,7 +211,7 @@ function opendistrib_product_prices() { | |||
function opendistrib_product_prices_event_price_with_tax() { | |||
var taxRateValue = $('#productprice-price-with-tax').data('tax-rate-value'); | |||
var price = $('#productprice-price').val(); | |||
var price = $('#productprice-price').val().replace(',', '.'); | |||
if (price) { | |||
$('#productprice-price-with-tax').val(getPriceWithTax(price, taxRateValue)); | |||
// formattage | |||
@@ -221,7 +221,7 @@ function opendistrib_product_prices_event_price_with_tax() { | |||
function opendistrib_product_prices_event_price() { | |||
var taxRateValue = $('#productprice-price-with-tax').data('tax-rate-value'); | |||
var priceWithTax = $('#productprice-price-with-tax').val(); | |||
var priceWithTax = $('#productprice-price-with-tax').val().replace(',', '.'); | |||
if (priceWithTax) { | |||
$('#productprice-price').val(getPrice(priceWithTax, taxRateValue)); | |||
// formattage |
@@ -619,11 +619,13 @@ var app = new Vue({ | |||
.then(function (response) { | |||
if (response.data) { | |||
for (idProduct in response.data) { | |||
if (app.showModalFormOrderCreate) { | |||
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], 'unit_coefficient', response.data[idProduct].unit_coefficient); | |||
Vue.set(app.orderCreate.productOrder[idProduct], 'price', app.getBestProductPrice(app.orderCreate, idProduct, app.orderCreate.productOrder[idProduct].quantity)); | |||
Vue.set(app.orderCreate.productOrder[idProduct], 'price', app.getBestProductPrice(app.orderCreate, idProduct, app.orderCreate.productOrder[idProduct].quantity, false)); | |||
Vue.set(app.orderCreate.productOrder[idProduct], 'price_with_tax', app.getBestProductPrice(app.orderCreate, idProduct, app.orderCreate.productOrder[idProduct].quantity, true)); | |||
} | |||
if (app.showModalFormOrderUpdate && app.idOrderUpdate) { | |||
@@ -632,46 +634,79 @@ var app = new Vue({ | |||
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], 'unit_coefficient', response.data[idProduct].unit_coefficient); | |||
Vue.set(app.ordersUpdate[keyOrderUpdate].productOrder[idProduct], 'prices', response.data[idProduct].prices); | |||
if(updatePricesOnUpdateOrder) { | |||
Vue.set( | |||
app.ordersUpdate[keyOrderUpdate].productOrder[idProduct], | |||
'price', | |||
app.getBestProductPrice(app.ordersUpdate[keyOrderUpdate], idProduct, app.ordersUpdate[keyOrderUpdate].productOrder[idProduct].quantity)); | |||
app.getBestProductPrice(app.ordersUpdate[keyOrderUpdate], idProduct, app.ordersUpdate[keyOrderUpdate].productOrder[idProduct].quantity, false)); | |||
Vue.set( | |||
app.ordersUpdate[keyOrderUpdate].productOrder[idProduct], | |||
'price_with_tax', | |||
app.getBestProductPrice(app.ordersUpdate[keyOrderUpdate], idProduct, app.ordersUpdate[keyOrderUpdate].productOrder[idProduct].quantity, true)); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
if(updatePricesOnUpdateOrder) { | |||
appAlerts.alert('info','Prix rechargés') ; | |||
} | |||
} | |||
app.loadingUpdateProductOrder = false; | |||
}); | |||
} | |||
}, | |||
getBestProductPrice: function(order, idProduct, theQuantity) { | |||
var thePriceWithTax = 9999; | |||
getBestProductPrice: function(order, idProduct, theQuantity, withTax) { | |||
var thePrice = 9999; | |||
var pricesArray = order.productOrder[idProduct].prices; | |||
var unitCoefficient = order.productOrder[idProduct].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(pricesArray) { | |||
for(var i = 0; i < pricesArray.length ; i++) { | |||
var price = pricesArray[i].price; | |||
if(withTax) { | |||
price = pricesArray[i].price_with_tax | |||
} | |||
var fromQuantity = pricesArray[i].from_quantity; | |||
if(priceWithTax < thePriceWithTax && fromQuantity <= theQuantity) { | |||
thePriceWithTax = priceWithTax; | |||
if(price < thePrice && fromQuantity <= theQuantity) { | |||
thePrice = price; | |||
} | |||
} | |||
} | |||
else { | |||
var product = this.getProduct(idProduct); | |||
if(withTax) { | |||
thePrice = getPriceWithTax(product.price, product.taxRate.value); | |||
} | |||
else { | |||
thePrice = product.price; | |||
} | |||
} | |||
if(thePriceWithTax == 9999) { | |||
if(thePrice == 9999) { | |||
return 0; | |||
} | |||
else { | |||
return thePriceWithTax; | |||
return thePrice; | |||
} | |||
}, | |||
getProduct: function(idProduct) { | |||
for(var i= 0; i < this.products.length; i++) { | |||
if(this.products[i].id == idProduct) { | |||
return this.products[i]; | |||
} | |||
} | |||
return false; | |||
}, | |||
}, | |||
}); | |||
@@ -691,6 +726,7 @@ Vue.component('order-form',{ | |||
username : '', | |||
comment: '', | |||
baseUrl: $('meta[name=baseurl]').attr('content'), | |||
vatMode: 'with_tax' | |||
} ; | |||
}, | |||
template: '#order-form-template', | |||
@@ -791,21 +827,55 @@ Vue.component('order-form',{ | |||
} | |||
Vue.set(this.order.productOrder[id_product], 'quantity', theQuantity); | |||
Vue.set(this.order.productOrder[id_product], 'price', app.getBestProductPrice(this.order, id_product, theQuantity)); | |||
Vue.set(this.order.productOrder[id_product], 'price', app.getBestProductPrice(this.order, id_product, theQuantity, false)); | |||
Vue.set(this.order.productOrder[id_product], 'price_with_tax', app.getBestProductPrice(this.order, id_product, theQuantity, true)); | |||
} | |||
}, | |||
productPriceChange: function(event) { | |||
var idProduct = event.currentTarget.getAttribute('data-id-product') ; | |||
var price = parseFloat(event.currentTarget.value) ; | |||
if(isNaN(price)) { | |||
price = 0 ; | |||
getProduct: function(idProduct) { | |||
for(var i= 0; i < this.products.length; i++) { | |||
if(this.products[i].id == idProduct) { | |||
return this.products[i]; | |||
} | |||
} | |||
Vue.set(this.order.productOrder, idProduct, { | |||
quantity: this.order.productOrder[idProduct].quantity, | |||
unit: this.order.productOrder[idProduct].unit, | |||
price: price | |||
}); | |||
return false; | |||
}, | |||
productPriceChange: function(event) { | |||
var idProduct = event.currentTarget.getAttribute('data-id-product'); | |||
var product = this.getProduct(idProduct); | |||
if(product) { | |||
var taxRateValue = parseFloat(product.taxRate.value); | |||
var withTax = event.currentTarget.getAttribute('data-with-tax'); | |||
var price = 0; | |||
var priceWithTax = 0; | |||
var priceValue = parseFloat(event.currentTarget.value.replace(',', '.')); | |||
if(withTax) { | |||
priceWithTax = priceValue.toFixed(2); | |||
price = getPrice(priceWithTax, taxRateValue); | |||
} | |||
else { | |||
price = priceValue.toFixed(3); | |||
priceWithTax = getPriceWithTax(price, taxRateValue); | |||
} | |||
if(isNaN(price)) { | |||
price = 0 ; | |||
} | |||
if(isNaN(priceWithTax)) { | |||
priceWithTax = 0 ; | |||
} | |||
Vue.set(this.order.productOrder, idProduct, { | |||
active: this.order.productOrder[idProduct].active, | |||
quantity: this.order.productOrder[idProduct].quantity, | |||
unit: this.order.productOrder[idProduct].unit, | |||
price: price, | |||
price_with_tax: priceWithTax | |||
}); | |||
} | |||
}, | |||
userChange: function(event) { | |||
var app = this ; |
@@ -5,6 +5,7 @@ | |||
right: 15px ; | |||
width: 300px ; | |||
height: auto ; | |||
z-index: 9999; | |||
.slide-fade-enter-active { | |||
@include transition(all .3s ease); |
@@ -367,7 +367,7 @@ termes. | |||
background-color: #e9e9e9; | |||
} | |||
input { | |||
input.input-quantity { | |||
font-size: 16px; | |||
font-weight: bold; | |||
} |