Browse Source

[Administration] Documents > Factures : génération sur base des commandes #1218

feature/souke
Guillaume Bourgeois 1 year ago
parent
commit
a97d3a35d1
7 changed files with 238 additions and 76 deletions
  1. +21
    -0
      backend/controllers/DocumentController.php
  2. +42
    -30
      backend/controllers/InvoiceController.php
  3. +92
    -43
      backend/views/document/_form.php
  4. +35
    -1
      backend/web/js/vuejs/document-form.js
  5. +22
    -0
      common/logic/Order/Order/Repository/OrderRepository.php
  6. +16
    -0
      common/logic/Order/Order/Repository/OrderRepositoryQuery.php
  7. +10
    -2
      common/logic/Order/Order/Service/OrderBuilder.php

+ 21
- 0
backend/controllers/DocumentController.php View File

{ {
$userManager = $this->getUserManager(); $userManager = $this->getUserManager();
$documentManager = $this->getDocumentManager(); $documentManager = $this->getDocumentManager();
$orderManager = $this->getOrderManager();


\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;


], $options); ], $options);
$json['delivery_note_create_array'] = $this->initDeliveryNoteArray('create', $deliveryNotesCreateArray); $json['delivery_note_create_array'] = $this->initDeliveryNoteArray('create', $deliveryNotesCreateArray);
$json['delivery_note_update_array'] = $this->initDeliveryNoteArray('update', $deliveryNotesUpdateArray); $json['delivery_note_update_array'] = $this->initDeliveryNoteArray('update', $deliveryNotesUpdateArray);

$json['orders_create_array'] = $this->initOrdersArray($orderManager->findOrdersByUserNotInvoiced($user));
$json['orders_update_array'] = $this->initOrdersArray($orderManager->findOrdersByUserAndInvoice($user, $document));
} }


return $json; return $json;
return ['return' => 'error']; return ['return' => 'error'];
} }


public function initOrdersArray(array $ordersArray)
{
$orderManager = $this->getOrderManager();
$ordersReturnArray = [];

foreach($ordersArray as &$order) {
$orderManager->initOrder($order);
$ordersReturnArray[] = [
'id' => $order->id,
'date' => $order->distribution->date,
'amount_with_tax' => $order->invoice_amount_with_tax
];
}

return $ordersReturnArray;
}

public function initDeliveryNoteArray($type, $deliveryNoteArrayResults) public function initDeliveryNoteArray($type, $deliveryNoteArrayResults)
{ {
$deliveryNoteArray = []; $deliveryNoteArray = [];

+ 42
- 30
backend/controllers/InvoiceController.php View File



namespace backend\controllers; namespace backend\controllers;


use common\helpers\Ajax;
use common\logic\Document\Invoice\Model\InvoiceSearch; use common\logic\Document\Invoice\Model\InvoiceSearch;
use common\logic\Order\Order\Model\Order; use common\logic\Order\Order\Model\Order;




public function actionAjaxDeleteDeliveryNote($idInvoice, $idDeliveryNote) public function actionAjaxDeleteDeliveryNote($idInvoice, $idDeliveryNote)
{ {
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

$invoiceManager = $this->getInvoiceManager(); $invoiceManager = $this->getInvoiceManager();


$invoice = $invoiceManager->findOneInvoiceById($idInvoice); $invoice = $invoiceManager->findOneInvoiceById($idInvoice);
], [ ], [
'id_delivery_note' => $idDeliveryNote 'id_delivery_note' => $idDeliveryNote
]); ]);

return [
'alert' => [
'type' => 'success',
'message' => 'Bon de livraison supprimé de la facture.'
]
];
return Ajax::responseSuccess('Bon de livraison supprimé de la facture.');
} else { } else {
return [
'alert' => [
'type' => 'error',
'message' => 'Une erreur est survenue lors de la suppression du bon de livraison.'
]
];
return Ajax::responseError('Une erreur est survenue lors de la suppression du bon de livraison.');
} }
} }


public function actionAjaxAddDeliveryNote($idInvoice, $idDeliveryNote) public function actionAjaxAddDeliveryNote($idInvoice, $idDeliveryNote)
{ {
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

$invoiceManager = $this->getInvoiceManager(); $invoiceManager = $this->getInvoiceManager();
$deliveryNoteManager = $this->getDeliveryNoteManager(); $deliveryNoteManager = $this->getDeliveryNoteManager();


], [ ], [
'id_delivery_note' => $idDeliveryNote 'id_delivery_note' => $idDeliveryNote
]); ]);

return [
'alert' => [
'type' => 'success',
'message' => 'Bon de livraison ajouté à la facture.'
]
];
return Ajax::responseSuccess("Bon de livraison ajouté à la facture.");
} else { } else {
return [
'alert' => [
'type' => 'error',
'message' => 'Une erreur est survenue lors de l\'ajout du bon de livraison.'
]
];
return Ajax::responseError("Une erreur est survenue lors de l'ajout du bon de livraison.");
}
}

public function actionAjaxAddOrder($idInvoice, $idOrder)
{
$invoiceManager = $this->getInvoiceManager();
$orderManager = $this->getOrderManager();

$invoice = $invoiceManager->findOneInvoiceById($idInvoice);
$order = $orderManager->findOneOrderById($idOrder);

if ($invoice && $invoiceManager->isStatusDraft($invoice) && $order) {
$order->id_invoice = $idInvoice;
$order->update();

return Ajax::responseSuccess("Commande ajoutée à la facture.");
}
else {
return Ajax::responseError("Une erreur est survenue lors de l'ajout de la commande.");
} }
} }


public function actionAjaxDeleteOrder($idInvoice, $idOrder)
{
$invoiceManager = $this->getInvoiceManager();
$orderManager = $this->getOrderManager();

$invoice = $invoiceManager->findOneInvoiceById($idInvoice);
$order = $orderManager->findOneOrderById($idOrder);

if ($invoice && $invoiceManager->isStatusDraft($invoice)) {
$order->id_invoice = null;
$order->update();

return Ajax::responseSuccess('Commande supprimée de la facture.');
}
else {
return Ajax::responseError('Une erreur est survenue lors de la suppression de la commande.');
}
}
} }

+ 92
- 43
backend/views/document/_form.php View File

<?php ActiveForm::end(); ?> <?php ActiveForm::end(); ?>
</div> </div>
</div> </div>

<?php if ($action == 'update' && $documentClass == 'Invoice'): ?>
<div class="panel panel-default">
<div class="panel-heading">
Bons de livraison
</div>
<div class="panel-body">
<table v-if="deliveryNoteUpdateArray && deliveryNoteUpdateArray.length > 0" class="table table-bordered">
<thead>
<tr>
<th>Libellé</th>
<th v-if="taxRateProducer != 0">Montant (TTC)</th>
<th v-else>Montant</th>
<th v-if="document.status == 'draft'"></th>
</tr>
</thead>
<tbody>
<tr v-for="deliveryNote in deliveryNoteUpdateArray">
<td><a :href="deliveryNote.url">{{ deliveryNote.name }}</a></td>
<td>{{ formatPrice(deliveryNote.total) }}</td>
<td v-if="document.status == 'draft'"><a class="btn btn-default" href="javascript:void(0);" @click="deleteDeliveryNoteOfInvoice" :data-id="deliveryNote.id"><span class="glyphicon glyphicon-trash"></span></a></td>
</tr>
</tbody>
</table>
<div v-else class="alert alert-warning">Aucun bon de livraison associé.</div>

<div v-if="document.status == 'draft'" id="delivery-note-add">
<div class="col-md-8">
<select class="form-control" v-model="deliveryNoteAddId">
<option value="0" selected="selected">--</option>
<option v-for="deliveryNote in deliveryNoteCreateArray" :value="deliveryNote.id">
{{ deliveryNote.name }}
</option>
</select>
</div>
<div class="col-md-4">
<button class="btn btn-primary" value="Ajouter" @click="submitDeliveryNoteAddToInvoice">Ajouter</button>
</div>
</div>
</div>
</div>
<?php endif; ?>

</div> </div>


<?php if ($action == 'update'): ?> <?php if ($action == 'update'): ?>
</div> </div>
<div class="clr"></div> <div class="clr"></div>


<?php if ($action == 'update' && $documentClass == 'Invoice'): ?>
<div class="row">
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading">
Bons de livraison
</div>
<div class="panel-body">
<table v-if="deliveryNoteUpdateArray && deliveryNoteUpdateArray.length > 0" class="table table-bordered">
<thead>
<tr>
<th>Libellé</th>
<th v-if="taxRateProducer != 0">Montant (TTC)</th>
<th v-else>Montant</th>
<th v-if="document.status == 'draft'"></th>
</tr>
</thead>
<tbody>
<tr v-for="deliveryNote in deliveryNoteUpdateArray">
<td><a :href="deliveryNote.url">{{ deliveryNote.name }}</a></td>
<td>{{ formatPrice(deliveryNote.total) }}</td>
<td v-if="document.status == 'draft'"><a class="btn btn-default" href="javascript:void(0);" @click="deleteDeliveryNoteFromInvoice" :data-id="deliveryNote.id"><span class="glyphicon glyphicon-trash"></span></a></td>
</tr>
</tbody>
</table>
<div v-else class="alert alert-warning">Aucun bon de livraison associé.</div>

<div v-if="document.status == 'draft'" id="delivery-note-add">
<div class="col-md-8">
<select class="form-control" v-model="deliveryNoteAddId">
<option value="0" selected="selected">--</option>
<option v-for="deliveryNote in deliveryNoteCreateArray" :value="deliveryNote.id">
{{ deliveryNote.name }}
</option>
</select>
</div>
<div class="col-md-4">
<button class="btn btn-primary" value="Ajouter" @click="submitDeliveryNoteAddToInvoice">Ajouter</button>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading">
Commandes
</div>
<div class="panel-body">
<table v-if="ordersUpdateArray && ordersUpdateArray.length > 0" class="table table-bordered">
<thead>
<tr>
<th>Libellé</th>
<th v-if="taxRateProducer != 0">Montant (TTC)</th>
<th v-else>Montant</th>
<th v-if="document.status == 'draft'"></th>
</tr>
</thead>
<tbody>
<tr v-for="order in ordersUpdateArray">
<td>{{ order.date }}</td>
<td>{{ formatPrice(order.amount_with_tax) }}</td>
<td v-if="document.status == 'draft'">
<a class="btn btn-default" href="javascript:void(0);" @click="deleteOrderFromInvoice" :data-id="order.id">
<span class="glyphicon glyphicon-trash"></span>
</a>
</td>
</tr>
</tbody>
</table>
<div v-else class="alert alert-warning">Aucune commande associée.</div>

<div v-if="document.status == 'draft'" id="order-add">
<div class="col-md-8">
<select class="form-control" v-model="orderAddId">
<option value="0" selected="selected">--</option>
<option v-for="order in ordersCreateArray" :value="order.id">
{{ order.date }}
</option>
</select>
</div>
<div class="col-md-4">
<button class="btn btn-primary" value="Ajouter" @click="submitOrderAddToInvoice">Ajouter</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="clr"></div>
<?php endif; ?>

<div class=""> <div class="">
<div class="panel panel-default" id="block-add-product"> <div class="panel panel-default" id="block-add-product">
<div class="panel-heading"> <div class="panel-heading">

+ 35
- 1
backend/web/js/vuejs/document-form.js View File

deliveryNoteCreateArray: [], deliveryNoteCreateArray: [],
deliveryNoteUpdateArray: [], deliveryNoteUpdateArray: [],
deliveryNoteAddId: 0, deliveryNoteAddId: 0,
ordersCreateArray: [],
ordersUpdateArray: [],
orderAddId: 0,
idDocument: 0, idDocument: 0,
typeDocument: '', typeDocument: '',
idUser: '', idUser: '',
Vue.set(app.document, 'address', response.data.address); Vue.set(app.document, 'address', response.data.address);
app.deliveryNoteCreateArray = response.data.delivery_note_create_array; app.deliveryNoteCreateArray = response.data.delivery_note_create_array;
app.deliveryNoteUpdateArray = response.data.delivery_note_update_array; app.deliveryNoteUpdateArray = response.data.delivery_note_update_array;
app.ordersCreateArray = response.data.orders_create_array;
app.ordersUpdateArray = response.data.orders_update_array;
} else { } else {
app.document.address = ''; app.document.address = '';
} }
app.init(); app.init();
}); });
}, },
deleteDeliveryNoteOfInvoice: function(event) {
deleteDeliveryNoteFromInvoice: function(event) {
var app = this; var app = this;
var idDeliveryNote = event.currentTarget.getAttribute('data-id'); var idDeliveryNote = event.currentTarget.getAttribute('data-id');


app.init(); app.init();
}); });
}, },
submitOrderAddToInvoice: function() {
var app = this;
axios.get(UrlManager.getBaseUrlAbsolute() + "invoice/ajax-add-order", {
params: {
idInvoice: this.getDocumentId(),
idOrder: app.orderAddId,
}
})
.then(function (response) {
appAlerts.alertResponse(response);
app.deliveryNoteAddId = 0;
app.init();
});
},
deleteOrderFromInvoice: function() {
var app = this;
var idOrder = event.currentTarget.getAttribute('data-id');

axios.get(UrlManager.getBaseUrlAbsolute() + "invoice/ajax-delete-order", {
params: {
idInvoice: app.getDocumentId(),
idOrder: idOrder
}
})
.then(function (response) {
appAlerts.alertResponse(response);
app.init();
});
},
getStepProductAdd: function () { getStepProductAdd: function () {
var step = parseInt(this.getProductById(this.productAddId).step); var step = parseInt(this.getProductById(this.productAddId).step);
if(!step) { if(!step) {

+ 22
- 0
common/logic/Order/Order/Repository/OrderRepository.php View File

use common\logic\Distribution\Distribution\Model\Distribution; use common\logic\Distribution\Distribution\Model\Distribution;
use common\logic\Distribution\Distribution\Repository\DistributionRepository; use common\logic\Distribution\Distribution\Repository\DistributionRepository;
use common\logic\Distribution\ProductDistribution\Repository\ProductDistributionRepository; use common\logic\Distribution\ProductDistribution\Repository\ProductDistributionRepository;
use common\logic\Document\Invoice\Model\Invoice;
use common\logic\Order\Order\Model\Order; use common\logic\Order\Order\Model\Order;
use common\logic\Order\Order\Service\OrderSolver; use common\logic\Order\Order\Service\OrderSolver;
use common\logic\Order\ProductOrder\Repository\ProductOrderRepository; use common\logic\Order\ProductOrder\Repository\ProductOrderRepository;
->find(); ->find();
} }


public function findOrdersByUserAndInvoice(User $user, Invoice $invoice)
{
return $this
->createDefaultQuery()
->filterByUser($user)
->filterIsInvoiced($invoice)
->filterIsValid()
->find();
}

public function findOrdersByUserNotInvoiced(User $user)
{
return $this
->createDefaultQuery()
->filterByUser($user)
->filterIsNotInvoiced()
->filterIsPassed()
->filterIsValid()
->find();
}

public function queryOrdersHistory(Producer $producer, User $user) public function queryOrdersHistory(Producer $producer, User $user)
{ {
$queryIncoming = clone $this->createDefaultQuery() $queryIncoming = clone $this->createDefaultQuery()

+ 16
- 0
common/logic/Order/Order/Repository/OrderRepositoryQuery.php View File

namespace common\logic\Order\Order\Repository; namespace common\logic\Order\Order\Repository;


use common\logic\AbstractRepositoryQuery; use common\logic\AbstractRepositoryQuery;
use common\logic\Document\Invoice\Model\Invoice;
use common\logic\Order\Order\Service\OrderDefinition; use common\logic\Order\Order\Service\OrderDefinition;
use common\logic\User\User\Model\User; use common\logic\User\User\Model\User;




return $this; return $this;
} }

public function filterIsInvoiced(Invoice $invoice): self
{
$this->andWhere('order.id_invoice IS NOT NULL AND order.id_invoice = :id_invoice')
->params([':id_invoice' => $invoice->id]);

return $this;
}

public function filterIsNotInvoiced(): self
{
$this->andWhere('order.id_invoice IS NULL');

return $this;
}
} }

+ 10
- 2
common/logic/Order/Order/Service/OrderBuilder.php View File

/** /**
* Initialise le montant total, le montant déjà payé et le poids de la commande. * Initialise le montant total, le montant déjà payé et le poids de la commande.
*/ */
// init
public function initOrder(Order $order, string $taxCalculationMethod = Document::TAX_CALCULATION_METHOD_DEFAULT): void public function initOrder(Order $order, string $taxCalculationMethod = Document::TAX_CALCULATION_METHOD_DEFAULT): void
{ {
// @TODO : récupérer le bon taxCalculationMethod
//$taxCalculationMethod = Document::TAX_CALCULATION_METHOD_SUM_OF_ROUNDINGS;

$this->initOrderAmount($order, $taxCalculationMethod); $this->initOrderAmount($order, $taxCalculationMethod);
$this->initOrderPaidAmount($order); $this->initOrderPaidAmount($order);

// @TODO : faire le bon calcul pour la TVA
/*$totalVat = 0;
foreach($order->invoice_amount_vat as $vat) {
$totalVat += $vat;
}
$order->invoice_amount_with_tax = Price::round($order->invoice_amount + $totalVat);*/
} }


/** /**
* Initialise le montant de la commande. * Initialise le montant de la commande.
*/ */
// initAmount
public function initOrderAmount(Order $order, string $taxCalculationMethod = Document::TAX_CALCULATION_METHOD_DEFAULT): void public function initOrderAmount(Order $order, string $taxCalculationMethod = Document::TAX_CALCULATION_METHOD_DEFAULT): void
{ {
$order->amount = 0; $order->amount = 0;

Loading…
Cancel
Save