@@ -241,6 +241,7 @@ class DistributionController extends BackendController | |||
'quantity' => $productOrder->quantity * Product::$unitsArray[$productOrder->unit]['coefficient'], | |||
'unit' => $productOrder->unit, | |||
'price' => number_format($productOrder->price, 3), | |||
'invoice_price' => number_format($productOrder->invoice_price, 2), | |||
'price_with_tax' => Price::getPriceWithTax($productOrder->price, $productOrder->taxRate->value), | |||
]; | |||
} | |||
@@ -303,7 +304,8 @@ class DistributionController extends BackendController | |||
'pointSale' => $order->pointSale ? ['id' => $order->pointSale->id, 'name' => $order->pointSale->name] : null, | |||
'productOrder' => $productOrderArray, | |||
'creditHistory' => $creditHistoryArray, | |||
'oneProductUnactivated' => $oneProductUnactivated | |||
'oneProductUnactivated' => $oneProductUnactivated, | |||
'isLinkedToValidDocument' => $order->isLinkedToValidDocument(), | |||
]); | |||
} | |||
} | |||
@@ -449,6 +451,7 @@ class DistributionController extends BackendController | |||
) { | |||
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; | |||
$order = Order::searchOne(['id' => $idOrder]); | |||
$distribution = Distribution::findOne($idDistribution); | |||
$user = User::findOne($idUser); | |||
$pointSale = PointSale::findOne($idPointSale); | |||
@@ -467,19 +470,65 @@ class DistributionController extends BackendController | |||
foreach ($productsArray as $product) { | |||
$priceArray = $product->getPriceArray($user, $pointSale); | |||
$quantity = 0; | |||
$invoicePrice = null; | |||
foreach($order->productOrder as $productOrder) { | |||
if($productOrder->id_product == $product['id']) { | |||
if($productOrder->invoice_price) { | |||
$invoicePrice = number_format($productOrder->invoice_price, 2); | |||
} | |||
else { | |||
$invoicePrice = number_format($productOrder->price, 3); | |||
} | |||
$quantity = $productOrder->quantity; | |||
} | |||
} | |||
$productOrderArray[$product['id']] = [ | |||
'quantity' => 0, | |||
'quantity' => $quantity, | |||
'unit' => $product->unit, | |||
'unit_coefficient' => Product::$unitsArray[$product->unit]['coefficient'], | |||
'prices' => $priceArray, | |||
'active' => $product->productDistribution[0]->active | |||
&& (!$pointSale || $product->isAvailableOnPointSale($pointSale)) | |||
&& (!$pointSale || $product->isAvailableOnPointSale($pointSale)), | |||
'invoice_price' => $invoicePrice | |||
]; | |||
} | |||
return $productOrderArray; | |||
} | |||
public function actionAjaxUpdateInvoicePrices($idOrder) | |||
{ | |||
$order = Order::searchOne([ | |||
'id' => (int)$idOrder | |||
]); | |||
if($order && $order->distribution->id_producer == GlobalParam::getCurrentProducerId()) { | |||
$userProducer = null; | |||
if($order->id_user) { | |||
$userProducer = UserProducer::searchOne([ | |||
'id_user' => $order->id_user, | |||
'id_producer' => GlobalParam::getCurrentProducerId() | |||
]); | |||
} | |||
foreach($order->productOrder as $productOrder) { | |||
$invoicePrice = $productOrder->product->getPrice([ | |||
'user' => $order->user ?: null, | |||
'point_sale' => $order->pointSale, | |||
'user_producer' => $userProducer, | |||
'quantity' => $productOrder->quantity | |||
]); | |||
if($invoicePrice != $productOrder->price) { | |||
$productOrder->invoice_price = $invoicePrice; | |||
$productOrder->save(); | |||
} | |||
} | |||
} | |||
} | |||
/** | |||
* Génére un PDF récapitulatif des des commandes d'un producteur pour une | |||
* date donnée (Méthode appelable via CRON) |
@@ -316,11 +316,10 @@ class DocumentController extends BackendController | |||
return $document->downloadPdf(); | |||
} | |||
public function actionSend($id) | |||
public function actionSend($id, $backUpdateForm = false) | |||
{ | |||
$document = $this->findModel($id); | |||
if ($document->send()) { | |||
$document->is_sent = true; | |||
$document->save(); | |||
@@ -328,7 +327,13 @@ class DocumentController extends BackendController | |||
} else { | |||
Yii::$app->getSession()->setFlash('danger', $this->getFlashMessage('send', $document)); | |||
} | |||
$this->redirect([$this->getControllerUrl() . '/index']); | |||
if($backUpdateForm) { | |||
return $this->redirect([$this->getControllerUrl() . '/update', 'id' => $id]); | |||
} | |||
else { | |||
return $this->redirect([$this->getControllerUrl() . '/index']); | |||
} | |||
} | |||
public function actionAjaxUserInfos($typeAction, $idUser, $classDocument, $idDocument = false) | |||
@@ -397,7 +402,7 @@ class DocumentController extends BackendController | |||
return ['return' => 'error']; | |||
} | |||
public function actionValidate($id) | |||
public function actionValidate($id, $backUpdateForm = false) | |||
{ | |||
$classDocument = $this->getClass(); | |||
@@ -414,7 +419,13 @@ class DocumentController extends BackendController | |||
$document->generatePdf(Pdf::DEST_FILE); | |||
Yii::$app->getSession()->setFlash('success', $this->getFlashMessage('validate', $document)); | |||
return $this->redirect([$this->getControllerUrl() . '/index']); | |||
if($backUpdateForm) { | |||
return $this->redirect([$this->getControllerUrl() . '/update', 'id' => $id]); | |||
} | |||
else { | |||
return $this->redirect([$this->getControllerUrl() . '/index']); | |||
} | |||
} | |||
} | |||
@@ -472,7 +483,9 @@ class DocumentController extends BackendController | |||
$order->init(); | |||
$productsOrderArray = []; | |||
foreach ($order->productOrder as $productOrder) { | |||
$productsOrderArray[$productOrder->id] = $productOrder->getAttributes(); | |||
$productsOrderArray[$productOrder->id] = array_merge($productOrder->getAttributes(), [ | |||
'url_order' => Yii::$app->urlManager->createUrl(['distribution/index', 'idOrderUpdate' => $productOrder->id_order]) | |||
]); | |||
} | |||
$ordersArray[$order->id] = array_merge( | |||
$order->getAttributes(), |
@@ -210,8 +210,8 @@ $this->setPageTitle('Distributions') ; | |||
<a :href="distribution.url_report" class="btn btn-xs btn-default" v-if="countOrders > 0">Liste (PDF)</a> | |||
<a :href="distribution.url_report+'&type=csv'" class="btn btn-xs btn-default" v-if="countOrders > 0">Tableau (CSV)</a> | |||
<br v-if="producer.option_display_export_grid && countOrders > 0" /> | |||
<a :href="distribution.url_report_grid" class="btn btn-xs btn-default" v-if="producer.option_display_export_grid && countOrders > 0">Grille (PDF)</a> | |||
<br v-if="producer && producer.option_display_export_grid && countOrders > 0" /> | |||
<a :href="distribution.url_report_grid" class="btn btn-xs btn-default" v-if="producer && producer.option_display_export_grid && countOrders > 0">Grille (PDF)</a> | |||
</span> | |||
</div> | |||
</div> | |||
@@ -278,11 +278,11 @@ $this->setPageTitle('Distributions') ; | |||
</ul> | |||
</div> | |||
<button id="btn-add-subscriptions" @click="addSubscriptions" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-plus"></span> Importer les abonnements</button> | |||
<template v-if="producer.tiller == true"> | |||
<template v-if="producer && producer.tiller == true"> | |||
<button v-if="tillerIsSynchro" id="btn-tiller" class="btn btn-success btn-xs" disabled><span class="glyphicon glyphicon-refresh"></span> Synchronisé avec Tiller</button> | |||
<button v-else id="btn-tiller" class="btn btn-xs btn-default" @click="synchroTiller"><span class="glyphicon glyphicon-refresh"></span> Synchroniser avec Tiller</button> | |||
</template> | |||
<button v-if="producer.credit" id="btn-pay-orders" class="btn btn-default btn-xs" @click="payOrders"><span class="glyphicon glyphicon-euro"></span> Payer les commandes</button> | |||
<button v-if="producer && producer.credit" id="btn-pay-orders" class="btn btn-default btn-xs" @click="payOrders"><span class="glyphicon glyphicon-euro"></span> Payer les commandes</button> | |||
<button id="btn-add-order" @click="openModalFormOrderCreate" class="btn btn-xs btn-primary"><span class="glyphicon glyphicon-plus"></span> Ajouter une commande</button> | |||
</div> | |||
<div class="left"> | |||
@@ -320,7 +320,7 @@ $this->setPageTitle('Distributions') ; | |||
<th class="column-amount">Montant</th> | |||
<th class="column-state-payment">Paiement</th> | |||
<th class="column-payment"></th> | |||
<th class="column-tiller" v-if="producer.tiller">Tiller</th> | |||
<th class="column-tiller" v-if="producer && producer.tiller">Tiller</th> | |||
<th class="column-actions"></th> | |||
<th class="column-delivery-note"></th> | |||
</tr> | |||
@@ -368,10 +368,10 @@ $this->setPageTitle('Distributions') ; | |||
<span class="label label-default input-group-addon" v-else-if="order.amount_paid > order.amount">surplus</span> | |||
<span class="label label-warning input-group-addon" v-else-if="order.amount_paid < order.amount">reste à payer</span> | |||
<span class="glyphicon glyphicon-time" title="Paiement automatique" v-if="order.auto_payment && producer.credit && (order.amount_paid == 0 || order.amount_paid < order.amount)"></span> | |||
<span class="glyphicon glyphicon-time" title="Paiement automatique" v-if="order.auto_payment && producer && producer.credit && (order.amount_paid == 0 || order.amount_paid < order.amount)"></span> | |||
</div> | |||
</td> | |||
<td class="column-payment" v-if="producer.credit"> | |||
<td class="column-payment" v-if="producer && producer.credit"> | |||
<div class="btn-group" v-if="order.user && !order.date_delete"> | |||
<button class="btn btn-xs btn-default" v-if="order.amount_paid == order.amount" @click="orderPaymentClick" :data-id-order="order.id" data-type="refund" :data-amount="order.amount"> | |||
<span class="glyphicon glyphicon-euro"></span> Rembourser | |||
@@ -395,7 +395,7 @@ $this->setPageTitle('Distributions') ; | |||
</ul> | |||
</div> | |||
</td> | |||
<td v-if="producer.tiller" class="tiller column-tiller"> | |||
<td v-if="producer && producer.tiller" class="tiller column-tiller"> | |||
<input v-if="order.tiller_synchronization == true" type="checkbox" checked="checked" :id="'checkbox-tiller-synchronization-'+order.id" :data-id-order="order.id" @change="changeSynchroTiller" /> | |||
<input v-else type="checkbox" :id="'checkbox-tiller-synchronization-'+order.id" :data-id-order="order.id" @change="changeSynchroTiller" /> | |||
<label :for="'checkbox-tiller-synchronization-'+order.id">Tiller</label> | |||
@@ -429,6 +429,7 @@ $this->setPageTitle('Distributions') ; | |||
@close="showModalFormOrderUpdate = false" | |||
@ordercreatedupdated="orderCreatedUpdated" | |||
@updateproductorderprices="updateProductOrderPrices" | |||
@updateinvoiceprices="updateInvoicePrices" | |||
></order-form> | |||
<modal v-if="showModalPayment && idOrderPayment == order.id" class="modal-payment" @close="showModalPayment = false"> | |||
@@ -586,7 +587,7 @@ $this->setPageTitle('Distributions') ; | |||
</div> | |||
<div class="col-md-4"> | |||
<div class="form-group"> | |||
<a v-if="producer.credit && order.id_user > 0 && user.id_user == order.id_user" class="btn btn-xs btn-primary btn-credit" :href="baseUrl+'/user/credit?id='+user.id_user" v-for="user in users">{{ parseFloat(user.credit).toFixed(2).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}</a> | |||
<a v-if="producer && producer.credit && order.id_user > 0 && user.id_user == order.id_user" class="btn btn-xs btn-primary btn-credit" :href="baseUrl+'/user/credit?id='+user.id_user" v-for="user in users">{{ parseFloat(user.credit).toFixed(2).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")+' €' }}</a> | |||
<label class="control-label" for="select-id-user"> | |||
Utilisateur | |||
</label> | |||
@@ -650,6 +651,14 @@ $this->setPageTitle('Distributions') ; | |||
<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> | |||
<div v-if="order.id_invoice || order.id_delivery_note || order.id_quotation"> | |||
<span class="label label-primary"> | |||
Facturé | |||
<template v-if="order.productOrder[product.id].invoice_price != null">{{ order.productOrder[product.id].invoice_price }}</template> | |||
<template v-else>{{ order.productOrder[product.id].price }}</template> | |||
€ HT | |||
</span> | |||
</div> | |||
</td> | |||
<td class="quantity"> | |||
<div class="input-group"> | |||
@@ -677,12 +686,15 @@ $this->setPageTitle('Distributions') ; | |||
<button class="modal-default-button btn btn-primary" @click="submitFormUpdate" v-if="order.id && order.id_user > 0" data-process-credit="1">Modifier et payer</button> | |||
<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-primary" @click="submitFormCreate" v-if="!order.id">Créer</button> | |||
<button class="modal-default-button btn btn-danger" @click="$emit('close')">Annuler</button> | |||
<button class="modal-default-button btn btn-danger" @click="$emit('close')">Fermer</button> | |||
<div class="right"> | |||
<button class="modal-default-button btn btn-info btn-update-prices" @click="updateProductOrderPrices(true)">Recharger les prix</button> | |||
<button v-if="order.id" class="modal-default-button btn btn-info btn-update-prices" @click="updateInvoicePrices(true)"> | |||
Réinitialiser les prix facturés | |||
</button> | |||
<button class="modal-default-button btn btn-info btn-display-prices-without-tax" @click="toggleVatMode()"> | |||
<template v-if="vatMode == 'all'">Cacher</template> | |||
<template v-else>Afficher</template> |
@@ -139,7 +139,11 @@ use common\models\Producer; | |||
<div id="" class="info-box"> | |||
<span class="info-box-icon bg-green"><i class="fa fa-sticky-note-o"></i></span> | |||
<div class="info-box-content"> | |||
<span class="info-box-text"><?= $typeDocument ?> <span v-html="document.html_label"></span></span> | |||
<span class="info-box-text"> | |||
<?= $typeDocument ?> | |||
<span v-html="document.html_label"></span> | |||
<span v-if="document.is_sent" class="label label-success">Envoyé</span> | |||
</span> | |||
<span class="info-box-number">{{ document.reference }}</span> | |||
<span class="info-box-text">Date</span> | |||
<span class="info-box-number">{{ document.date }}</span> | |||
@@ -152,29 +156,39 @@ use common\models\Producer; | |||
<span class="info-box-number">{{ formatPrice(total_with_tax) }}</span> | |||
</div> | |||
</div> | |||
<div id="" class="info-box"> | |||
<span class="info-box-icon bg-yellow"><i class="fa fa-calendar"></i></span> | |||
<div class="info-box-content"> | |||
<span class="info-box-text">Commandes</span> | |||
<?php foreach($model->orders as $order): ?> | |||
<a class="btn btn-sm btn-default" href="<?= Yii::$app->urlManager->createUrl(['distribution/index', 'idOrderUpdate' => $order->id]); ?>"> | |||
<?= date('d/m/Y', strtotime($order->distribution->date)) ?> | |||
</a> | |||
<?php endforeach; ?> | |||
</div> | |||
</div> | |||
<div id="" class="info-box"> | |||
<span class="info-box-icon bg-blue"><i class="fa fa-download"></i></span> | |||
<div class="info-box-content"> | |||
<a href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/download', 'id' => $model->id]) ?>" | |||
class="btn btn-default"><span class="glyphicon glyphicon-download-alt"></span> Télécharger (PDF)</a> | |||
class="btn btn-sm btn-default"><span class="glyphicon glyphicon-download-alt"></span> Télécharger (PDF)</a> | |||
<?php if ($model->getClass() == 'Invoice' && Producer::getConfig('option_export_evoliz')): ?> | |||
<a href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/export-csv-evoliz', 'id' => $model->id]) ?>" | |||
class="btn btn-default"><span class="glyphicon glyphicon-save-file"></span> Export Evoliz | |||
class="btn btn-sm btn-default"><span class="glyphicon glyphicon-save-file"></span> Export Evoliz | |||
(CSV)</a> | |||
<?php endif; ?> | |||
</div> | |||
</div> | |||
<div v-if="document.status == 'draft'" id="" class="info-box"> | |||
<div v-if="document.status == 'draft' || !document.is_sent" class="info-box"> | |||
<span class="info-box-icon bg-red"><i class="fa fa-flash"></i></span> | |||
<div class="info-box-content"> | |||
<form action="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/validate']) ?>"> | |||
<?= Html::hiddenInput('id', $model->id); ?> | |||
<button class="btn btn-default"><span class="glyphicon glyphicon-ok"></span> Valider le document | |||
</button> | |||
</form> | |||
<a v-if="document.status == 'draft'" 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 (isset($model->user) && strlen($model->user->email) > 0): ?> | |||
<a href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/send', 'id' => $model->id]) ?>" | |||
class="btn btn-default"><span class="glyphicon glyphicon-send"></span> Envoyer le | |||
<a v-if="!document.is_sent" href="<?= Yii::$app->urlManager->createUrl([Yii::$app->controller->getControllerUrl() . '/send', 'id' => $model->id, 'backUpdateForm' => 1]) ?>" | |||
class="btn btn-sm btn-default"><span class="glyphicon glyphicon-send"></span> Envoyer le | |||
document</a> | |||
<?php endif; ?> | |||
</div> | |||
@@ -267,9 +281,9 @@ use common\models\Producer; | |||
<div class="product-name">{{ getProductById(productOrder.id_product).name }} | |||
</div> | |||
<ul class="product-order-meta"> | |||
<li>{{ order.username }}</li> | |||
<li v-if="order.distribution_date">{{ order.distribution_date }}</li> | |||
<li v-if="order.point_sale_name">{{ order.point_sale_name }}</li> | |||
<li v-if="order.distribution_date">Commande : <a class="btn btn-sm btn-default" :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"> |
@@ -634,7 +634,7 @@ 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); | |||
Vue.set(app.ordersUpdate[keyOrderUpdate].productOrder[idProduct], 'invoice_price', response.data[idProduct].invoice_price); | |||
if(updatePricesOnUpdateOrder) { | |||
Vue.set( | |||
@@ -660,6 +660,29 @@ var app = new Vue({ | |||
}); | |||
} | |||
}, | |||
updateInvoicePrices: function() { | |||
var order = null; | |||
if(app.showModalFormOrderUpdate && app.idOrderUpdate) { | |||
for (keyOrderUpdate in app.ordersUpdate) { | |||
if (app.ordersUpdate[keyOrderUpdate].id == app.idOrderUpdate) { | |||
order = app.ordersUpdate[keyOrderUpdate] ; | |||
} | |||
} | |||
} | |||
if(order) { | |||
axios.get(UrlManager.getBaseUrlAbsolute() + "distribution/ajax-update-invoice-prices", { | |||
params: { | |||
idOrder: order.id | |||
} | |||
}) | |||
.then(function (response) { | |||
app.updateProductOrderPrices(false); | |||
appAlerts.alert('info','Prix facturés réinitialisés.') ; | |||
}); | |||
} | |||
}, | |||
getBestProductPrice: function(order, idProduct, theQuantity, withTax) { | |||
var thePrice = 9999; | |||
var pricesArray = order.productOrder[idProduct].prices; | |||
@@ -717,7 +740,7 @@ Vue.component('modal', { | |||
Vue.component('order-form',{ | |||
props: ['date', 'dateFormat', 'pointsSale', 'idActivePointSale', 'meansPayment', 'users', 'products', 'order', 'producer', 'loadingUpdateProductOrder'], | |||
emits: ['updateProductPrice'], | |||
emits: ['updateProductPrice', 'updateInvoicePrices'], | |||
data: function() { | |||
return { | |||
errors: [], | |||
@@ -726,7 +749,7 @@ Vue.component('order-form',{ | |||
username : '', | |||
comment: '', | |||
baseUrl: $('meta[name=baseurl]').attr('content'), | |||
vatMode: 'with_tax' | |||
vatMode: 'all' // 'with_tax' | |||
} ; | |||
}, | |||
template: '#order-form-template', | |||
@@ -904,7 +927,10 @@ Vue.component('order-form',{ | |||
this.updateProductOrderPrices(true) ; | |||
}, | |||
updateProductOrderPrices: function(updateProductOrderPrices) { | |||
this.$emit('updateproductorderprices', updateProductOrderPrices) ; | |||
this.$emit('updateproductorderprices', updateProductOrderPrices); | |||
}, | |||
updateInvoicePrices: function() { | |||
this.$emit('updateinvoiceprices'); | |||
}, | |||
toggleVatMode: function() { | |||
if(this.vatMode == 'all') { |
@@ -1094,4 +1094,11 @@ class Order extends ActiveRecordCommon | |||
return $comment; | |||
} | |||
public function isLinkedToValidDocument() | |||
{ | |||
return ($this->deliveryNote && $this->deliveryNote->isStatusValid()) | |||
|| ($this->quotation && $this->quotation->isStatusValid()) | |||
|| ($this->invoice && $this->invoice->isStatusValid()); | |||
} | |||
} |
@@ -409,18 +409,18 @@ class Product extends ActiveRecordCommon | |||
foreach ($specificPriceArray as $specificPrice) { | |||
$priceArray[] = [ | |||
'from_quantity' => $specificPrice->from_quantity ? $specificPrice->from_quantity : 0, | |||
'price' => $this->getPrice([ | |||
'price' => number_format($this->getPrice([ | |||
'user' => $user, | |||
'user_producer' => $userProducer, | |||
'point_sale' => $pointSale, | |||
'quantity' => $specificPrice->from_quantity | |||
]), | |||
'price_with_tax' => $this->getPriceWithTax([ | |||
]), 3), | |||
'price_with_tax' => number_format($this->getPriceWithTax([ | |||
'user' => $user, | |||
'user_producer' => $userProducer, | |||
'point_sale' => $pointSale, | |||
'quantity' => $specificPrice->from_quantity | |||
]), | |||
]), 2), | |||
]; | |||
} | |||