Browse Source

[Administration] Factures > modifier : liens vers les commandes associées #643

refactoring
Guillaume Bourgeois 2 years ago
parent
commit
89dc760725
7 changed files with 163 additions and 42 deletions
  1. +52
    -3
      backend/controllers/DistributionController.php
  2. +19
    -6
      backend/controllers/DocumentController.php
  3. +23
    -11
      backend/views/distribution/index.php
  4. +28
    -14
      backend/views/document/_form.php
  5. +30
    -4
      backend/web/js/vuejs/distribution-index.js
  6. +7
    -0
      common/models/Order.php
  7. +4
    -4
      common/models/Product.php

+ 52
- 3
backend/controllers/DistributionController.php View File

@@ -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)

+ 19
- 6
backend/controllers/DocumentController.php View File

@@ -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(),

+ 23
- 11
backend/views/distribution/index.php View File

@@ -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,")+'&nbsp;€' }}</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,")+'&nbsp;€' }}</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>

+ 28
- 14
backend/views/document/_form.php View File

@@ -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">

+ 30
- 4
backend/web/js/vuejs/distribution-index.js View File

@@ -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') {

+ 7
- 0
common/models/Order.php View File

@@ -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());
}
}

+ 4
- 4
common/models/Product.php View File

@@ -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),
];
}


Loading…
Cancel
Save