@@ -591,6 +591,7 @@ class DocumentController extends BackendController | |||
foreach ($order->productOrder as $productOrder) { | |||
$productsOrderArray[$productOrder->id] = array_merge($productOrder->getAttributes(), [ | |||
'url_product' => $this->getUrlManagerBackend()->createUrl(['product/update', 'id' => $productOrder->id_product]), | |||
'url_order' => $this->getUrlManagerBackend()->createUrl(['distribution/index', 'idOrderUpdate' => $productOrder->id_order]) | |||
]); | |||
} | |||
@@ -701,12 +702,10 @@ class DocumentController extends BackendController | |||
public function actionAjaxDeleteProductOrder($idProductOrder) | |||
{ | |||
$productOrderModule = $this->getProductOrderModule(); | |||
$productOrder = $productOrderModule->findOneProductOrderById($idProductOrder); | |||
if ($productOrder) { | |||
$productOrderModule->delete($productOrder); | |||
return Ajax::responseSuccess('Produit supprimé'); | |||
} | |||
@@ -771,6 +770,20 @@ class DocumentController extends BackendController | |||
} | |||
} | |||
public function actionAjaxUpdateProductOrderInvoicePrice($idProductOrder, $invoicePrice) | |||
{ | |||
$productOrderModule = $this->getProductOrderModule(); | |||
$productOrder = $productOrderModule->getRepository()->findOneProductOrderById((int) $idProductOrder); | |||
if($productOrder) { | |||
$productOrderModule->getBuilder()->updateProductOrderInvoicePriceByValue($productOrder, (float) $invoicePrice); | |||
return Ajax::responseSuccess("Prix mis à jour", [ | |||
'invoice_price' => $productOrder->invoice_price | |||
]); | |||
} | |||
return Ajax::responseError("Une erreur est survenue."); | |||
} | |||
public function getClass() | |||
{ | |||
$class = get_class($this); |
@@ -212,12 +212,6 @@ $documentClass = $documentModule->getClass($model); | |||
class="btn btn-sm btn-default"><span class="glyphicon glyphicon-download-alt"></span> Télécharger | |||
(PDF)</a> | |||
<?php if ($documentModule->isStatusValid($model)): ?> | |||
<a href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/regenerate', 'id' => $model->id]) ?>" | |||
class="btn btn-sm btn-default"><span class="glyphicon glyphicon-repeat"></span> Regénérer | |||
(PDF)</a> | |||
<?php endif; ?> | |||
<?php if ($documentClass == 'Invoice' && $producerModule->getConfig('option_export_evoliz')): ?> | |||
<a href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/export-csv-evoliz', 'id' => $model->id]) ?>" | |||
class="btn btn-sm btn-default"><span class="glyphicon glyphicon-save-file"></span> Export Evoliz | |||
@@ -233,6 +227,12 @@ $documentClass = $documentModule->getClass($model); | |||
href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/validate', 'id' => $model->id, 'backUpdateForm' => 1]) ?>" | |||
class="btn btn-sm btn-default"><span class="glyphicon glyphicon-ok"></span> Valider le document</a> | |||
<?php if ($documentModule->isStatusValid($model)): ?> | |||
<a href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/regenerate', 'id' => $model->id]) ?>" | |||
class="btn btn-sm btn-default"><span class="glyphicon glyphicon-repeat"></span> Regénérer | |||
(PDF)</a> | |||
<?php endif; ?> | |||
<?php if (isset($model->user) && strlen($model->user->email) > 0): ?> | |||
<a v-if="!document.is_sent" | |||
href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/send', 'id' => $model->id, 'backUpdateForm' => 1]) ?>" | |||
@@ -378,22 +378,37 @@ $documentClass = $documentModule->getClass($model); | |||
<template v-for="order in ordersArray"> | |||
<tr v-for="productOrder in order.productOrder"> | |||
<td class="col-md-4"> | |||
<div class="product-name">{{ getProductById(productOrder.id_product).name }} | |||
<div class="product-name"> | |||
<a :href="productOrder.url_product" target="_blank"> | |||
{{ getProductById(productOrder.id_product).name }} | |||
</a> | |||
</div> | |||
<ul class="product-order-meta"> | |||
<li v-if="order.distribution_date">Commande : <a class="btn btn-sm btn-default" | |||
:href="productOrder.url_order">{{ | |||
<li v-if="order.distribution_date">Commande : <a :href="productOrder.url_order">{{ | |||
order.distribution_date }}</a></li> | |||
<li>Utilisateur : {{ order.username }}</li> | |||
<li v-if="order.point_sale_name">Point de vente : {{ order.point_sale_name }}</li> | |||
</ul> | |||
</td> | |||
<td class="col-md-2"> | |||
{{ formatPrice(getProductOrderPrice(productOrder)) }} | |||
<template v-if="document.status == 'draft'"> | |||
<div class="input-group input-group-edit-invoice-price"> | |||
<input type="text" class="form-control" :id="'input-product-order-invoice-price-'+productOrder.id" :value="getProductOrderPrice(productOrder)" :data-id-product-order="productOrder.id" @keyup="showProductOrderInvoicePriceButtonApply" /> | |||
<span class="input-group-addon">€</span> | |||
</div> | |||
<div class="product-order-invoice-price-button-apply" :id="'product-order-invoice-price-button-apply-'+productOrder.id"> | |||
<button class="btn btn-success" type="button" :data-id-product-order="productOrder.id" @click="updateProductOrderInvoicePrice"> | |||
<span class="glyphicon glyphicon-ok"></span> | |||
</button> | |||
</div> | |||
</template> | |||
<template v-else> | |||
{{ formatPrice(getProductOrderPrice(productOrder)) }} | |||
</template> | |||
<template | |||
v-if="document.status == 'draft' && getProductOrderPrice(productOrder) != getBestProductPrice(productOrder.id_product, productOrder.quantity)"> | |||
<i class="fa fa-exclamation-triangle" | |||
title="Prix différent de celui défini au niveau du produit"></i> | |||
<i class="different-price fa fa-exclamation-triangle" | |||
:title="'Prix différent de celui défini au niveau du produit ('+getBestProductPrice(productOrder.id_product, productOrder.quantity)+' €)'"></i> | |||
</template> | |||
</td> | |||
<td class="col-md-2">{{ productOrder.quantity }}</td> |
@@ -2827,37 +2827,51 @@ termes. | |||
.document-form .info-box .info-box-text { | |||
font-size: 13px; | |||
} | |||
/* line 7, ../sass/document/_form.scss */ | |||
/* line 8, ../sass/document/_form.scss */ | |||
.document-form .info-box .info-box-number { | |||
font-size: 15px; | |||
} | |||
/* line 12, ../sass/document/_form.scss */ | |||
/* line 14, ../sass/document/_form.scss */ | |||
.document-form #block-add-product .input-price { | |||
text-align: center; | |||
} | |||
/* line 16, ../sass/document/_form.scss */ | |||
/* line 19, ../sass/document/_form.scss */ | |||
.document-form #block-add-product .input-group-quantity .input-quantity { | |||
text-align: center; | |||
} | |||
/* line 22, ../sass/document/_form.scss */ | |||
/* line 25, ../sass/document/_form.scss */ | |||
.document-form #block-add-product .total .input-group { | |||
margin-bottom: 10px; | |||
} | |||
/* line 25, ../sass/document/_form.scss */ | |||
/* line 29, ../sass/document/_form.scss */ | |||
.document-form #block-add-product .total .btn { | |||
float: right; | |||
} | |||
/* line 32, ../sass/document/_form.scss */ | |||
/* line 36, ../sass/document/_form.scss */ | |||
.document-form #block-list-products ul.product-order-meta { | |||
padding: 0px; | |||
margin: 0px; | |||
padding-left: 20px; | |||
} | |||
/* line 37, ../sass/document/_form.scss */ | |||
/* line 41, ../sass/document/_form.scss */ | |||
.document-form #block-list-products ul.product-order-meta li { | |||
color: gray; | |||
font-size: 11px; | |||
} | |||
/* line 51, ../sass/document/_form.scss */ | |||
.document-form #block-list-products .product-order-invoice-price-button-apply { | |||
display: none; | |||
} | |||
/* line 54, ../sass/document/_form.scss */ | |||
.document-form #block-list-products .product-order-invoice-price-button-apply .btn { | |||
display: block; | |||
width: 100%; | |||
} | |||
/* line 60, ../sass/document/_form.scss */ | |||
.document-form #block-list-products .different-price { | |||
position: relative; | |||
top: 5px; | |||
} | |||
/* line 7, ../sass/document/_index.scss */ | |||
.quotation-index .content-wrapper .content table.table .column-actions, |
@@ -122,7 +122,7 @@ var app = new Vue({ | |||
var price = 0; | |||
if (documentClass == 'DeliveryNote' || documentClass == 'Invoice') { | |||
price = productOrder.invoice_price; | |||
if (!price) { | |||
if (isNaN(price) || price === null) { | |||
price = productOrder.price; | |||
} | |||
} else { | |||
@@ -327,6 +327,32 @@ var app = new Vue({ | |||
if (isNaN(this.productAddQuantity)) { | |||
this.productAddQuantity = 1; | |||
} | |||
}, | |||
showProductOrderInvoicePriceButtonApply: function(event) { | |||
if(event.key == 'Enter') { | |||
this.updateProductOrderInvoicePrice(event); | |||
} | |||
else { | |||
var idProductOrder = event.currentTarget.getAttribute('data-id-product-order'); | |||
$('#product-order-invoice-price-button-apply-'+idProductOrder).show(); | |||
} | |||
}, | |||
updateProductOrderInvoicePrice: function (event) { | |||
var idProductOrder = event.currentTarget.getAttribute('data-id-product-order'); | |||
var invoicePrice = $('#input-product-order-invoice-price-'+idProductOrder).val(); | |||
axios.get(UrlManager.getBaseUrlAbsolute() + "document/ajax-update-product-order-invoice-price", { | |||
params: { | |||
idProductOrder: idProductOrder, | |||
invoicePrice: invoicePrice | |||
} | |||
}) | |||
.then(function (response) { | |||
appAlerts.alertResponse(response); | |||
$('#input-product-order-invoice-price-'+idProductOrder).val(response.data.datas.invoice_price); | |||
$('#product-order-invoice-price-button-apply-'+idProductOrder).hide(); | |||
app.init(); | |||
}); | |||
} | |||
} | |||
}); |
@@ -1,43 +1,65 @@ | |||
.document-form { | |||
.info-box { | |||
.info-box-text { | |||
font-size: 13px ; | |||
} | |||
.info-box-number { | |||
font-size: 15px ; | |||
} | |||
} | |||
#block-add-product { | |||
.input-price { | |||
text-align: center ; | |||
} | |||
.input-group-quantity { | |||
.input-quantity { | |||
text-align: center ; | |||
} | |||
} | |||
.total { | |||
.input-group { | |||
margin-bottom: 10px ; | |||
} | |||
.btn { | |||
float: right ; | |||
} | |||
} | |||
} | |||
#block-list-products { | |||
ul.product-order-meta { | |||
padding: 0px ; | |||
margin: 0px ; | |||
padding-left: 20px ; | |||
li { | |||
color: gray ; | |||
font-size: 11px ; | |||
} | |||
} | |||
} | |||
.info-box { | |||
.info-box-text { | |||
font-size: 13px; | |||
} | |||
.info-box-number { | |||
font-size: 15px; | |||
} | |||
} | |||
#block-add-product { | |||
.input-price { | |||
text-align: center; | |||
} | |||
.input-group-quantity { | |||
.input-quantity { | |||
text-align: center; | |||
} | |||
} | |||
.total { | |||
.input-group { | |||
margin-bottom: 10px; | |||
} | |||
.btn { | |||
float: right; | |||
} | |||
} | |||
} | |||
#block-list-products { | |||
ul.product-order-meta { | |||
padding: 0px; | |||
margin: 0px; | |||
padding-left: 20px; | |||
li { | |||
color: gray; | |||
font-size: 11px; | |||
} | |||
} | |||
.input-group-edit-invoice-price { | |||
} | |||
.product-order-invoice-price-button-apply { | |||
display: none; | |||
.btn { | |||
display: block; | |||
width: 100%; | |||
} | |||
} | |||
.different-price { | |||
position: relative; | |||
top: 5px; | |||
} | |||
} | |||
} |
@@ -7,17 +7,17 @@ class Ajax | |||
const RESPONSE_TYPE_ERROR = 'error'; | |||
const RESPONSE_TYPE_SUCCESS = 'success'; | |||
public static function responseSuccess(string $message): array | |||
public static function responseSuccess(string $message, array $datas = []): array | |||
{ | |||
return self::response(self::RESPONSE_TYPE_SUCCESS, $message); | |||
return self::response(self::RESPONSE_TYPE_SUCCESS, $message, $datas); | |||
} | |||
public static function responseError(string $message): array | |||
public static function responseError(string $message, array $datas = []): array | |||
{ | |||
return self::response(self::RESPONSE_TYPE_ERROR, $message); | |||
return self::response(self::RESPONSE_TYPE_ERROR, $message, $datas); | |||
} | |||
private static function response(string $responseType, string $message): array | |||
private static function response(string $responseType, string $message, array $datas = []): array | |||
{ | |||
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | |||
@@ -26,7 +26,8 @@ class Ajax | |||
'alert' => [ | |||
'type' => self::getAlertClass($responseType), | |||
'message' => $message | |||
] | |||
], | |||
'datas' => $datas | |||
]; | |||
} | |||
@@ -58,21 +58,26 @@ class ProductOrderBuilder extends AbstractBuilder | |||
'quantity' => $quantity | |||
]); | |||
$this->saveUpdate($productOrder); | |||
$this->update($productOrder); | |||
return $productOrder; | |||
} | |||
public function updateProductOrderInvoicePrice(ProductOrder $productOrder, array $params = []): void | |||
{ | |||
$productOrder->invoice_price = $this->productSolver->getPrice($productOrder->product, [ | |||
'user' => (isset($params['user']) && $params['user']) ? $params['user'] : null, | |||
'user_producer' => (isset($params['user_producer']) && $params['user_producer']) ? $params['user_producer'] : null, | |||
'point_sale' => (isset($params['point_sale']) && $params['point_sale']) ? $params['point_sale'] : null, | |||
'quantity' => $productOrder->quantity | |||
]); | |||
$this->saveUpdate($productOrder); | |||
$this->update($productOrder); | |||
} | |||
public function updateProductOrderInvoicePriceByValue(ProductOrder $productOrder, float $invoicePrice) | |||
{ | |||
$productOrder->invoice_price = $invoicePrice; | |||
$this->update($productOrder); | |||
} | |||
public function deleteProductOrdersByOrder(Order $order): void |
@@ -63,7 +63,7 @@ class ProductOrderSolver extends AbstractService implements SolverInterface | |||
public function getPriceByTypeTotal(ProductOrder $productOrder, string $typeTotal = Order::AMOUNT_TOTAL) | |||
{ | |||
if ($typeTotal == Order::INVOICE_AMOUNT_TOTAL && $productOrder->invoice_price) { | |||
if ($typeTotal == Order::INVOICE_AMOUNT_TOTAL && $productOrder->invoice_price !== null) { | |||
return $productOrder->invoice_price; | |||
} | |||