feat multi tva
This commit is contained in:
parent
b60bb6e0b2
commit
666c54dc83
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -2657,9 +2657,7 @@ class PageController extends Controller
|
||||
public function getTotalDevis($numdevis)
|
||||
{
|
||||
$total = $this->myDb->getTotalDevis($numdevis, $this->idNextcloud);
|
||||
$res = array();
|
||||
$res['total'] = $total;
|
||||
return json_encode($res);
|
||||
return json_encode($total);
|
||||
}
|
||||
|
||||
private function calculAge($dateNaissance)
|
||||
|
||||
@ -41,7 +41,7 @@ class Bdd
|
||||
public function __construct(IDbConnection $db, IL10N $l, LoggerInterface $logger)
|
||||
{
|
||||
$this->whiteColumn = array("date", "num", "id_client", "id_thanato", "entreprise", "nom", "prenom", "legal_one", "telephone", "mail", "adresse", "produit_id",
|
||||
"quantite", "date_paiement", "type_paiement", "id_devis", "reference", "description", "prix_unitaire", "legal_two", "path", "tva_default", "coefficient_ik",
|
||||
"quantite", "date_paiement", "type_paiement", "id_devis", "reference", "description", "prix_unitaire", "tva", "legal_two", "path", "tva_default", "coefficient_ik",
|
||||
"mentions_default", "version", "mentions", "comment", "status_paiement", "devise", "auto_invoice_number", "changelog", "format", "comment", "user_id",
|
||||
"facture_prefixe", "arrivee", "depart", "latitude", "longitude", "id_lieu", "rang", "mois", "annee", "id_trajet", "commentaire","source",
|
||||
"date_habilitation", "sexe", "observations_generales", "ref_pacemaker", "id_defunt", "article_id", "corpulence", "lieu_deces",
|
||||
@ -79,14 +79,50 @@ class Bdd
|
||||
{
|
||||
$articles = json_decode($this->getListArticle($iddevis, $idNextcloud));
|
||||
$produits = json_decode($this->getListProduit($iddevis, $idNextcloud));
|
||||
$total = 0;
|
||||
|
||||
// Grouper les totaux par taux de TVA
|
||||
$totalsByTva = array();
|
||||
|
||||
// Traiter les articles
|
||||
foreach($articles as $key => $article) {
|
||||
$total += $article->prix_unitaire * $article->quantite;
|
||||
$tva = floatval($article->tva ?? 20.00);
|
||||
$totalHT = floatval($article->prix_unitaire) * floatval($article->quantite);
|
||||
|
||||
if (!isset($totalsByTva[$tva])) {
|
||||
$totalsByTva[$tva] = 0;
|
||||
}
|
||||
$totalsByTva[$tva] += $totalHT;
|
||||
}
|
||||
|
||||
// Traiter les produits
|
||||
foreach($produits as $key => $produit) {
|
||||
$total += $produit->prix_unitaire * $produit->quantite;
|
||||
$tva = floatval($produit->tva ?? 20.00);
|
||||
$totalHT = floatval($produit->prix_unitaire) * floatval($produit->quantite);
|
||||
|
||||
if (!isset($totalsByTva[$tva])) {
|
||||
$totalsByTva[$tva] = 0;
|
||||
}
|
||||
$totalsByTva[$tva] += $totalHT;
|
||||
}
|
||||
return $total;
|
||||
|
||||
// Convertir en tableau de résultats
|
||||
$result = array();
|
||||
$totalGeneral = 0;
|
||||
|
||||
foreach($totalsByTva as $tva => $totalHT) {
|
||||
$result[] = array(
|
||||
'tva' => $tva,
|
||||
'totalHT' => round($totalHT, 2),
|
||||
'totalTVA' => round($totalHT * $tva / 100, 2),
|
||||
'totalTTC' => round($totalHT * (1 + $tva / 100), 2)
|
||||
);
|
||||
$totalGeneral += $totalHT;
|
||||
}
|
||||
|
||||
return array(
|
||||
'details' => $result,
|
||||
'totalGeneral' => round($totalGeneral, 2)
|
||||
);
|
||||
}
|
||||
|
||||
public function getClients($idNextcloud)
|
||||
@ -891,6 +927,7 @@ class Bdd
|
||||
$this->tableprefix."produit.id as pid,"
|
||||
.$this->tableprefix."produit_devis.id as pdid, reference, description,"
|
||||
.$this->tableprefix."produit_devis.comment, quantite, prix_unitaire, "
|
||||
.$this->tableprefix."produit_devis.tva, "
|
||||
.$this->tableprefix."devis.id_client
|
||||
FROM ".$this->tableprefix."produit, ".$this->tableprefix."devis, ".$this->tableprefix."produit_devis
|
||||
WHERE ".$this->tableprefix."produit.id = produit_id AND ".$this->tableprefix."devis.id = devis_id AND ".$this->tableprefix."devis.id = ?";
|
||||
@ -910,7 +947,12 @@ class Bdd
|
||||
|
||||
public function getListArticle($numdevis, $idNextcloud)
|
||||
{
|
||||
$sql = "SELECT ".$this->tableprefix."article.id as aid,".$this->tableprefix."article_devis.id as adid, reference, description,".$this->tableprefix."article_devis.comment, quantite, prix_unitaire FROM ".$this->tableprefix."article, ".$this->tableprefix."devis, ".$this->tableprefix."article_devis WHERE ".$this->tableprefix."article.id = article_id AND ".$this->tableprefix."devis.id = devis_id AND ".$this->tableprefix."devis.id = ?";
|
||||
$sql = "SELECT ".$this->tableprefix."article.id as aid,"
|
||||
.$this->tableprefix."article_devis.id as adid, reference, description,"
|
||||
.$this->tableprefix."article_devis.comment, quantite, prix_unitaire, "
|
||||
.$this->tableprefix."article_devis.tva "
|
||||
."FROM "
|
||||
.$this->tableprefix."article, ".$this->tableprefix."devis, ".$this->tableprefix."article_devis WHERE ".$this->tableprefix."article.id = article_id AND ".$this->tableprefix."devis.id = devis_id AND ".$this->tableprefix."devis.id = ?";
|
||||
return $this->execSQL($sql, array($numdevis));
|
||||
}
|
||||
|
||||
@ -3075,6 +3117,7 @@ class Bdd
|
||||
produit_devis.quantite,
|
||||
produit_devis.discount,
|
||||
produit_devis.devis_id,
|
||||
produit_devis.tva,
|
||||
produit.prix_unitaire as produit_price,
|
||||
produit.reference as produit_reference,
|
||||
produit.description as produit_description,
|
||||
|
||||
@ -74,9 +74,26 @@ class DevisDataProcessor
|
||||
// Variables pour gérer les articles comme dans les factures
|
||||
$produitsReferenceArray = [];
|
||||
|
||||
// ⭐ NOUVEAU: Réinitialiser les montants
|
||||
$devis_temp['montant_htc'] = 0;
|
||||
$devis_temp['montant_tva'] = 0;
|
||||
$devis_temp['montant_ttc'] = 0;
|
||||
|
||||
foreach ($produits as $produit) {
|
||||
$htPrice = $this->getProductPrice($produit, $devis, $filter);
|
||||
$devis_temp['montant_htc'] += $htPrice * $produit->quantite;
|
||||
$totalHT = $htPrice * $produit->quantite;
|
||||
|
||||
// ⭐ NOUVEAU: Récupérer le taux de TVA spécifique du produit (défaut 20%)
|
||||
$tvaValue = isset($produit->tva) && $produit->tva !== null ? floatval($produit->tva) : 20.00;
|
||||
|
||||
// ⭐ NOUVEAU: Calculer le montant TTC avec le bon taux
|
||||
$totalTTC = $totalHT * (1 + $tvaValue / 100);
|
||||
$totalTVA = $totalTTC - $totalHT;
|
||||
|
||||
// ⭐ NOUVEAU: Additionner les montants
|
||||
$devis_temp['montant_htc'] += $totalHT;
|
||||
$devis_temp['montant_tva'] += $totalTVA;
|
||||
$devis_temp['montant_ttc'] += $totalTTC;
|
||||
|
||||
// Collecter les références comme dans les factures
|
||||
if (isset($produit->reference) && !empty($produit->reference)) {
|
||||
@ -89,9 +106,6 @@ class DevisDataProcessor
|
||||
$produitsReferenceAsString = implode("-", $produitsReferenceArray);
|
||||
$devis_temp['article'] = !empty($produitsReferenceAsString) ? $produitsReferenceAsString : 'SOINS';
|
||||
|
||||
$devis_temp['montant_tva'] = ($devis_temp['montant_htc'] * $devis_temp['tva']) / 100;
|
||||
$devis_temp['montant_ttc'] = $devis_temp['montant_tva'] + $devis_temp['montant_htc'];
|
||||
|
||||
return $devis_temp;
|
||||
}
|
||||
|
||||
|
||||
@ -27,18 +27,17 @@ declare(strict_types=1);
|
||||
namespace OCA\Gestion\Service\Devis\Pdf;
|
||||
|
||||
use DateTime;
|
||||
use \FPDF;
|
||||
use FPDF;
|
||||
use OCA\Gestion\Helpers\FileExportHelpers;
|
||||
use OCA\Gestion\Helpers\PriceHelpers;
|
||||
|
||||
class DevisPdfHandler extends FPDF
|
||||
{
|
||||
|
||||
private $multipleDevisData = [];
|
||||
private $devisData = [];
|
||||
private $logo = null;
|
||||
private $logoPath = "/var/www/html/data/admin/files/.gestion/";
|
||||
function Header()
|
||||
public function Header()
|
||||
{
|
||||
if ($this->logo != "nothing") {
|
||||
$this->Image($this->logoPath . "logo.png", 4, 2, 36, 37);
|
||||
@ -46,7 +45,7 @@ class DevisPdfHandler extends FPDF
|
||||
$this->Cell(55, 30, '');
|
||||
}
|
||||
}
|
||||
function Footer()
|
||||
public function Footer()
|
||||
{
|
||||
$this->SetY(-40);
|
||||
$this->SetFont('Arial', '', 7);
|
||||
@ -118,7 +117,6 @@ class DevisPdfHandler extends FPDF
|
||||
|
||||
private function DrawArticlesTableHeader()
|
||||
{
|
||||
$tvaValue = $this->devisData["configuration"]->tva_default;
|
||||
$this->SetFont('Arial', '', 10);
|
||||
$this->SetXY(10, 106);
|
||||
$this->Cell(20, 8, "Date", 0, 0, 'C');
|
||||
@ -130,56 +128,109 @@ class DevisPdfHandler extends FPDF
|
||||
$this->Cell(20, 8, "Prix Uni. HT", 0, 0, 'C');
|
||||
|
||||
$this->SetXY(155, 106);
|
||||
$this->Cell(20, 8, 'TVA ' . $tvaValue . '%', 0, 0, 'C');
|
||||
$this->Cell(20, 8, 'TVA', 0, 0, 'C');
|
||||
|
||||
$this->SetXY(175, 106);
|
||||
$this->Cell(25, 8, "Prix Uni. TTC", 0, 0, 'C');
|
||||
|
||||
}
|
||||
|
||||
public function DrawArticlesTableValueAndReturnTotalPrice()
|
||||
{
|
||||
$this->SetFont('Arial', '', 10);
|
||||
$tvaValue = $this->devisData["configuration"]->tva_default;
|
||||
$totalHt = 0;
|
||||
$totalTtc = 0;
|
||||
$totalTva = 0;
|
||||
|
||||
// Grouper les totaux par taux de TVA
|
||||
$totalsByTva = [];
|
||||
$products = $this->devisData["products"];
|
||||
$yValue = 116;
|
||||
|
||||
foreach ($products as $product) {
|
||||
// Récupérer le taux de TVA du produit (défaut à 20% si non défini)
|
||||
$tvaValue = isset($product['tva']) ? floatval($product['tva']) : 20.00;
|
||||
|
||||
$valueHt = $product['produit_price'] * $product['quantite'];
|
||||
$valueTtc = PriceHelpers::calculPriceWithVatValue($valueHt, $tvaValue);
|
||||
$totalHt += $valueHt;
|
||||
$totalTtc += $valueTtc;
|
||||
$tvaAmount = $valueTtc - $valueHt;
|
||||
|
||||
// Grouper par taux de TVA
|
||||
if (!isset($totalsByTva[$tvaValue])) {
|
||||
$totalsByTva[$tvaValue] = [
|
||||
'totalHT' => 0,
|
||||
'totalTVA' => 0,
|
||||
'totalTTC' => 0
|
||||
];
|
||||
}
|
||||
|
||||
$totalsByTva[$tvaValue]['totalHT'] += $valueHt;
|
||||
$totalsByTva[$tvaValue]['totalTVA'] += $tvaAmount;
|
||||
$totalsByTva[$tvaValue]['totalTTC'] += $valueTtc;
|
||||
|
||||
// Affichage du produit
|
||||
$productDescription = $product["produit_description"];
|
||||
$dateValue = "";
|
||||
if ($product === end($products)) {
|
||||
$dateValue = $this->devisData['devis_date'];
|
||||
$productDescription .= " de " . FileExportHelpers::GetSexeLabel($this->devisData['defunt_sexe']) . ' ' . $this->devisData["defunt_nom"];
|
||||
}
|
||||
$tvaAmount = $valueTtc - $valueHt;
|
||||
|
||||
$this->SetXY(10, $yValue);
|
||||
$this->Cell(20, 6, $dateValue, 0, 0);
|
||||
|
||||
$this->SetXY(35, $yValue);
|
||||
$this->MultiAlignCell(100, 6, utf8_decode(html_entity_decode($productDescription)), 0, '0', );
|
||||
$this->MultiAlignCell(100, 6, utf8_decode(html_entity_decode($productDescription)), 0, '0');
|
||||
|
||||
$this->SetXY(135, $yValue);
|
||||
$this->Cell(20, 6, number_format($valueHt, 2, '.', '') . chr(128), 0, 0, 'C');
|
||||
|
||||
$this->SetXY(155, $yValue);
|
||||
$this->Cell(20, 6, number_format($tvaAmount, 2, '.', '') . chr(128), 0, 0, 'C');
|
||||
$this->Cell(20, 6, $tvaValue . '%', 0, 0, 'C');
|
||||
|
||||
$this->SetXY(175, $yValue);
|
||||
$this->Cell(25, 6, number_format($valueTtc, 2, '.', '') . chr(128), 0, 1, 'C');
|
||||
$yValue += 12;
|
||||
$totalTva += $tvaAmount;
|
||||
}
|
||||
|
||||
// Trier par taux de TVA
|
||||
ksort($totalsByTva);
|
||||
|
||||
// ⭐ NOUVEAU: Ajouter les lignes de totaux par TVA DANS le tableau
|
||||
$this->SetFont('Arial', 'B', 10);
|
||||
|
||||
// Ligne de séparation avant les totaux
|
||||
$this->Line(10, $yValue - 2, 200, $yValue - 2);
|
||||
$yValue += 2;
|
||||
|
||||
foreach ($totalsByTva as $tva => $totals) {
|
||||
$this->SetXY(35, $yValue);
|
||||
$this->Cell(100, 6, 'Total TVA ' . number_format($tva, 0) . '%', 0, 0, 'L');
|
||||
|
||||
$this->SetXY(135, $yValue);
|
||||
$this->Cell(20, 6, number_format($totals['totalHT'], 2, '.', '') . chr(128), 0, 0, 'C');
|
||||
|
||||
$this->SetXY(155, $yValue);
|
||||
$this->Cell(20, 6, number_format($totals['totalTVA'], 2, '.', '') . chr(128), 0, 0, 'C');
|
||||
|
||||
$this->SetXY(175, $yValue);
|
||||
$this->Cell(25, 6, number_format($totals['totalTTC'], 2, '.', '') . chr(128), 0, 0, 'C');
|
||||
|
||||
$yValue += 8;
|
||||
}
|
||||
|
||||
// Calculer les totaux généraux pour le cadre en bas à droite
|
||||
$totalGeneralHT = 0;
|
||||
$totalGeneralTVA = 0;
|
||||
$totalGeneralTTC = 0;
|
||||
|
||||
foreach ($totalsByTva as $totals) {
|
||||
$totalGeneralHT += $totals['totalHT'];
|
||||
$totalGeneralTVA += $totals['totalTVA'];
|
||||
$totalGeneralTTC += $totals['totalTTC'];
|
||||
}
|
||||
|
||||
// Retourner uniquement les totaux généraux
|
||||
return [
|
||||
"TOTAL HT" => $totalHt,
|
||||
"TVA " . $tvaValue . "%" => $totalTva,
|
||||
"TOTAL TTC" => $totalTtc
|
||||
'totalHT' => $totalGeneralHT,
|
||||
'totalTVA' => $totalGeneralTVA,
|
||||
'totalTTC' => $totalGeneralTTC
|
||||
];
|
||||
}
|
||||
|
||||
@ -200,17 +251,27 @@ class DevisPdfHandler extends FPDF
|
||||
$ibanCursorX = $this->GetX();
|
||||
$this->Cell($ibanWidth, 7, 'Code SWIFT : AGRI FR PP 836', 1, 1, 'C');
|
||||
|
||||
//TABLE HT
|
||||
//TABLE DES TOTAUX GÉNÉRAUX UNIQUEMENT (3 lignes)
|
||||
$ibanLastPositionX = $ibanCursorX + $ibanWidth + 20;
|
||||
$startOfArrayX = $ibanLastPositionX;
|
||||
$startOfArrayY = $ibanCursorY;
|
||||
foreach ($totalPriceArray as $label => $price) {
|
||||
$this->SetXY($startOfArrayX, $startOfArrayY);
|
||||
$this->Cell(40, 7, $label, 1, 1, 'C');
|
||||
$this->SetXY($startOfArrayX + 40, $startOfArrayY);
|
||||
$this->Cell(40, 7, number_format($price, 2, '.', '') . chr(128), 1, 1, 'C');
|
||||
$startOfArrayY += 7;
|
||||
}
|
||||
|
||||
// Afficher les 3 totaux généraux
|
||||
$this->SetFont('Arial', 'B', 11);
|
||||
|
||||
$this->SetXY($startOfArrayX, $startOfArrayY);
|
||||
$this->Cell(40, 7, 'TOTAL HT', 1, 0, 'C');
|
||||
$this->Cell(40, 7, number_format($totalPriceArray['totalHT'], 2, '.', '') . chr(128), 1, 1, 'C');
|
||||
$startOfArrayY += 7;
|
||||
|
||||
$this->SetXY($startOfArrayX, $startOfArrayY);
|
||||
$this->Cell(40, 7, 'TOTAL TVA', 1, 0, 'C');
|
||||
$this->Cell(40, 7, number_format($totalPriceArray['totalTVA'], 2, '.', '') . chr(128), 1, 1, 'C');
|
||||
$startOfArrayY += 7;
|
||||
|
||||
$this->SetXY($startOfArrayX, $startOfArrayY);
|
||||
$this->Cell(40, 7, 'TOTAL TTC', 1, 0, 'C');
|
||||
$this->Cell(40, 7, number_format($totalPriceArray['totalTTC'], 2, '.', '') . chr(128), 1, 1, 'C');
|
||||
}
|
||||
|
||||
public function SetMultipleDevisContent()
|
||||
@ -233,7 +294,7 @@ class DevisPdfHandler extends FPDF
|
||||
$this->DrawBankAndTotalPriceInfo($totalPriceValue);
|
||||
}
|
||||
|
||||
function MultiAlignCell($w, $h, $text, $border = 0, $ln = 0, $align = 'L', $fill = false)
|
||||
public function MultiAlignCell($w, $h, $text, $border = 0, $ln = 0, $align = 'L', $fill = false)
|
||||
{
|
||||
// Store reset values for (x,y) positions
|
||||
$x = $this->GetX() + $w;
|
||||
@ -248,19 +309,22 @@ class DevisPdfHandler extends FPDF
|
||||
}
|
||||
}
|
||||
|
||||
function NbLines($w, $txt)
|
||||
public function NbLines($w, $txt)
|
||||
{
|
||||
// Compute the number of lines a MultiCell of width w will take
|
||||
if (!isset($this->CurrentFont))
|
||||
if (!isset($this->CurrentFont)) {
|
||||
$this->Error('No font has been set');
|
||||
}
|
||||
$cw = $this->CurrentFont['cw'];
|
||||
if ($w == 0)
|
||||
if ($w == 0) {
|
||||
$w = $this->w - $this->rMargin - $this->x;
|
||||
}
|
||||
$wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
|
||||
$s = str_replace("\r", '', (string) $txt);
|
||||
$nb = strlen($s);
|
||||
if ($nb > 0 && $s[$nb - 1] == "\n")
|
||||
if ($nb > 0 && $s[$nb - 1] == "\n") {
|
||||
$nb--;
|
||||
}
|
||||
$sep = -1;
|
||||
$i = 0;
|
||||
$j = 0;
|
||||
@ -276,21 +340,25 @@ class DevisPdfHandler extends FPDF
|
||||
$nl++;
|
||||
continue;
|
||||
}
|
||||
if ($c == ' ')
|
||||
if ($c == ' ') {
|
||||
$sep = $i;
|
||||
}
|
||||
$l += $cw[$c];
|
||||
if ($l > $wmax) {
|
||||
if ($sep == -1) {
|
||||
if ($i == $j)
|
||||
if ($i == $j) {
|
||||
$i++;
|
||||
} else
|
||||
}
|
||||
} else {
|
||||
$i = $sep + 1;
|
||||
}
|
||||
$sep = -1;
|
||||
$j = $i;
|
||||
$l = 0;
|
||||
$nl++;
|
||||
} else
|
||||
} else {
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
return $nl;
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ import "@nextcloud/dialogs/dist/index.css";
|
||||
import "datatables.net-dt/css/jquery.dataTables.css";
|
||||
import "../css/mycss.css";
|
||||
|
||||
import { getArticlesById, getMailServerFrom, getProduitsById, savePdfToNextcloud,exportDevisToPdf} from "./modules/ajaxRequest.mjs";
|
||||
import { getArticlesById, getMailServerFrom, getProduitsById, savePdfToNextcloud, exportDevisToPdf, updateDB} from "./modules/ajaxRequest.mjs";
|
||||
import { getGlobal, globalConfiguration } from "./modules/mainFunction.mjs";
|
||||
import "./listener/main_listener";
|
||||
import { Client } from "./objects/client.mjs";
|
||||
@ -34,4 +34,23 @@ window.addEventListener("DOMContentLoaded", function () {
|
||||
capture(sendMail);
|
||||
(document.getElementById("modalMail")).style.display = "none";
|
||||
});
|
||||
|
||||
$(document).on('change', '.tva-select', function() {
|
||||
var table = $(this).data('table');
|
||||
var column = $(this).data('column');
|
||||
var id = $(this).data('id');
|
||||
var value = $(this).val();
|
||||
|
||||
// Mettre à jour la base de données
|
||||
updateDB(table, column, value, id);
|
||||
|
||||
// Recharger les produits ou articles selon la table
|
||||
setTimeout(function() {
|
||||
if (table === 'produit_devis') {
|
||||
getProduitsById();
|
||||
} else if (table === 'article_devis') {
|
||||
getArticlesById();
|
||||
}
|
||||
}, 500);
|
||||
});
|
||||
});
|
||||
@ -357,7 +357,7 @@ export function getProduitsByIdDevis(id_devis) {
|
||||
/**
|
||||
* Get a product in database using id
|
||||
*/
|
||||
export function getProduitsById() {
|
||||
export function getProduitsById() {
|
||||
var devis_id = $('#devisid').data('id');
|
||||
var myData = { numdevis: devis_id, };
|
||||
|
||||
@ -376,12 +376,49 @@ export function getProduitsByIdDevis(id_devis) {
|
||||
}
|
||||
|
||||
$.each(JSON.parse(response), function (arrayID, myresp) {
|
||||
$('#produits tbody').append('<tr><td><div data-html2canvas-ignore data-modifier="getProduitsById" data-id="' + myresp.pdid + '" data-table="produit_devis" class="' + deleteDisable + ' deleteItem icon-delete"></div><div style="display:inline;" data-val="' + myresp.pid + '" data-id="' + myresp.pdid + '" class="selectable">' + myresp.reference + '</div></td>' +
|
||||
var tvaValue = myresp.tva || 20.00;
|
||||
var prixUnitaireHT = parseFloat(myresp.prix_unitaire);
|
||||
var quantite = parseFloat(myresp.quantite);
|
||||
|
||||
// Calculs
|
||||
var prixUnitaireTTC = prixUnitaireHT * (1 + tvaValue / 100);
|
||||
var totalHT = prixUnitaireHT * quantite;
|
||||
var totalTTC = prixUnitaireTTC * quantite;
|
||||
|
||||
$('#produits tbody').append('<tr>' +
|
||||
// Colonne 1: Reference (avec delete et selectable)
|
||||
'<td><div data-html2canvas-ignore data-modifier="getProduitsById" data-id="' + myresp.pdid + '" data-table="produit_devis" class="' + deleteDisable + ' deleteItem icon-delete"></div><div style="display:inline;" data-val="' + myresp.pid + '" data-id="' + myresp.pdid + '" class="selectable">' + myresp.reference + '</div></td>' +
|
||||
|
||||
// Colonne 2: Designation
|
||||
'<td>' + myresp.description + '</td>' +
|
||||
|
||||
// Colonne 3: Comment (editable)
|
||||
'<td><div class="editable" data-table="produit_devis" data-column="comment" data-id="' + myresp.pdid + '">' + ((myresp.comment.length === 0) ? '-' : myresp.comment) + '</div></td>' +
|
||||
'<td><div class="editableNumber getProduitsById" style="display:inline;" data-modifier="getProduitsById" data-table="produit_devis" data-column="quantite" data-id=' + myresp.pdid + '>' + myresp.quantite + '</div> </td>' +
|
||||
'<td>' + cur.format(myresp.prix_unitaire) + '</td>' +
|
||||
'<td>' + cur.format((myresp.quantite * myresp.prix_unitaire)) + '</td></tr>');
|
||||
|
||||
// Colonne 4: TVA (select)
|
||||
'<td><select class="form-select tva-select" data-table="produit_devis" data-column="tva" data-id="' + myresp.pdid + '">' +
|
||||
'<option value="10"' + (tvaValue == 10 ? ' selected' : '') + '>10%</option>' +
|
||||
'<option value="15"' + (tvaValue == 15 ? ' selected' : '') + '>15%</option>' +
|
||||
'<option value="20"' + (tvaValue == 20 ? ' selected' : '') + '>20%</option>' +
|
||||
'</select></td>' +
|
||||
|
||||
// Colonne 5: Quantity (editable)
|
||||
'<td><div class="editableNumber getProduitsById" style="display:inline;" data-modifier="getProduitsById" data-table="produit_devis" data-column="quantite" data-id=' + myresp.pdid + '>' + myresp.quantite + '</div></td>' +
|
||||
|
||||
// Colonne 6: Unit price with VAT (Prix unitaire TTC)
|
||||
'<td>' + cur.format(prixUnitaireTTC) + '</td>' +
|
||||
|
||||
// Colonne 7: Unit price without VAT (Prix unitaire HT)
|
||||
'<td>' + cur.format(prixUnitaireHT) + '</td>' +
|
||||
|
||||
// Colonne 8: Total with VAT (Total TTC)
|
||||
'<td>' + cur.format(totalTTC) + '</td>' +
|
||||
|
||||
// Colonne 9: Total without VAT (Total HT)
|
||||
'<td>' + cur.format(totalHT) + '</td>' +
|
||||
|
||||
'</tr>');
|
||||
|
||||
total += (myresp.quantite * myresp.prix_unitaire);
|
||||
});
|
||||
|
||||
@ -414,12 +451,49 @@ export function getArticlesById() {
|
||||
}
|
||||
|
||||
$.each(JSON.parse(response), function (arrayID, myresp) {
|
||||
$('#articles tbody').append('<tr><td><div data-html2canvas-ignore data-modifier="getArticlesById" data-id="' + myresp.adid + '" data-table="article_devis" class="' + deleteDisable + ' deleteItem icon-delete"></div><div style="display:inline;" data-val="' + myresp.aid + '" data-id="' + myresp.adid + '" class="articleSelectable">' + myresp.reference + '</div></td>' +
|
||||
var tvaValue = myresp.tva || 20.00;
|
||||
var prixUnitaireHT = parseFloat(myresp.prix_unitaire);
|
||||
var quantite = parseFloat(myresp.quantite);
|
||||
|
||||
// Calculs
|
||||
var totalHT = prixUnitaireHT * quantite;
|
||||
var totalTTC = totalHT * (1 + tvaValue / 100);
|
||||
|
||||
$('#articles tbody').append('<tr>' +
|
||||
// Colonne 1: Reference (avec delete et selectable)
|
||||
'<td><div data-html2canvas-ignore data-modifier="getArticlesById" data-id="' + myresp.adid + '" data-table="article_devis" class="' + deleteDisable + ' deleteItem icon-delete"></div><div style="display:inline;" data-val="' + myresp.aid + '" data-id="' + myresp.adid + '" class="articleSelectable">' + myresp.reference + '</div></td>' +
|
||||
|
||||
// Colonne 2: Designation
|
||||
'<td>' + myresp.description + '</td>' +
|
||||
|
||||
// Colonne 3: Comment (editable)
|
||||
'<td><div class="editable" data-table="article_devis" data-column="comment" data-id="' + myresp.adid + '">' + ((myresp.comment.length === 0) ? '-' : myresp.comment) + '</div></td>' +
|
||||
'<td><div class="editableNumber getArticlesById" style="display:inline;" data-modifier="getArticlesById" data-table="article_devis" data-column="quantite" data-id=' + myresp.adid + '>' + myresp.quantite + '</div> </td>' +
|
||||
'<td>' + cur.format(myresp.prix_unitaire) + '</td>' +
|
||||
'<td>' + cur.format((myresp.quantite * myresp.prix_unitaire)) + '</td></tr>');
|
||||
|
||||
// Colonne 4: TVA (select)
|
||||
'<td><select class="form-select tva-select" data-table="article_devis" data-column="tva" data-id="' + myresp.adid + '">' +
|
||||
'<option value="10"' + (tvaValue == 10 ? ' selected' : '') + '>10%</option>' +
|
||||
'<option value="15"' + (tvaValue == 15 ? ' selected' : '') + '>15%</option>' +
|
||||
'<option value="20"' + (tvaValue == 20 ? ' selected' : '') + '>20%</option>' +
|
||||
'</select></td>' +
|
||||
|
||||
// Colonne 5: Quantity (ml) (editable)
|
||||
'<td><div class="editableNumber getArticlesById" style="display:inline;" data-modifier="getArticlesById" data-table="article_devis" data-column="quantite" data-id=' + myresp.adid + '>' + myresp.quantite + '</div></td>' +
|
||||
|
||||
// Colonne 6: Unit price without VAT (Prix unitaire HT)
|
||||
'<td>' + cur.format(prixUnitaireHT) + '</td>' +
|
||||
|
||||
// Colonne 7: Total without VAT (Total HT)
|
||||
'<td>' + cur.format(totalHT) + '</td>' +
|
||||
|
||||
// Colonne 8: Total with VAT (Total TTC)
|
||||
'<td>' + cur.format(totalTTC) + '</td>' +
|
||||
|
||||
// Colonne 9: Total without VAT (Total HT - duplicate)
|
||||
'<td>' + cur.format(totalHT) + '</td>' +
|
||||
|
||||
'</tr>'
|
||||
);
|
||||
|
||||
total += (myresp.quantite * myresp.prix_unitaire);
|
||||
});
|
||||
|
||||
|
||||
@ -215,10 +215,71 @@ export function getGlobal(id_devis) {
|
||||
})
|
||||
}).done((function (res) {
|
||||
var myresp = JSON.parse(response)[0];
|
||||
var total = JSON.parse(res).total;
|
||||
var tva = parseFloat(myresp.tva_default);
|
||||
var totaux = JSON.parse(res);
|
||||
|
||||
// Fonction de formatage locale
|
||||
function formatMoney(amount) {
|
||||
if (isNaN(amount)) return '0,00 €';
|
||||
return parseFloat(amount).toFixed(2).replace('.', ',') + ' €';
|
||||
}
|
||||
|
||||
$('#totaldevis tbody').empty();
|
||||
$('#totaldevis tbody').append('<tr><td>' + cur.format(total) + '</td><td id="tva">' + tva + ' %</td><td id="totaltva">' + cur.format(Math.round((total * tva)) / 100) + '</td><td>' + cur.format(Math.round((total * (tva + 100))) / 100) + '</td></tr>');
|
||||
|
||||
// Si on a des détails par TVA
|
||||
if (totaux.details && totaux.details.length > 0) {
|
||||
var totalGeneralHT = 0;
|
||||
var totalGeneralTVA = 0;
|
||||
var totalGeneralTTC = 0;
|
||||
|
||||
// Afficher une ligne par taux de TVA
|
||||
totaux.details.forEach(function(detail) {
|
||||
var totalHT = parseFloat(detail.totalHT);
|
||||
var totalTVA = parseFloat(detail.totalTVA);
|
||||
var totalTTC = parseFloat(detail.totalTTC);
|
||||
var tva = parseFloat(detail.tva);
|
||||
|
||||
$('#totaldevis tbody').append(
|
||||
'<tr>' +
|
||||
'<td class="text-center">' + formatMoney(totalHT) + '</td>' +
|
||||
'<td class="text-center">' + tva + ' %</td>' +
|
||||
'<td class="text-center">' + formatMoney(totalTVA) + '</td>' +
|
||||
'<td class="text-center">' + formatMoney(totalTTC) + '</td>' +
|
||||
'</tr>'
|
||||
);
|
||||
|
||||
totalGeneralHT += totalHT;
|
||||
totalGeneralTVA += totalTVA;
|
||||
totalGeneralTTC += totalTTC;
|
||||
});
|
||||
|
||||
// Si plusieurs taux de TVA, afficher une ligne de total
|
||||
if (totaux.details.length > 1) {
|
||||
$('#totaldevis tbody').append(
|
||||
'<tr class="fw-bold bg-light">' +
|
||||
'<td class="text-center"><strong>' + formatMoney(totalGeneralHT) + '</strong></td>' +
|
||||
'<td class="text-center"><strong>TOTAL</strong></td>' +
|
||||
'<td class="text-center"><strong>' + formatMoney(totalGeneralTVA) + '</strong></td>' +
|
||||
'<td class="text-center"><strong>' + formatMoney(totalGeneralTTC) + '</strong></td>' +
|
||||
'</tr>'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Fallback si pas de détails (ancien format)
|
||||
var tva = parseFloat(myresp.tva_default);
|
||||
var total = parseFloat(totaux.totalGeneral) || 0;
|
||||
var montantTVA = (total * tva) / 100;
|
||||
var totalTTC = total * (1 + tva / 100);
|
||||
|
||||
$('#totaldevis tbody').append(
|
||||
'<tr>' +
|
||||
'<td class="text-center">' + formatMoney(total) + '</td>' +
|
||||
'<td class="text-center">' + tva + ' %</td>' +
|
||||
'<td class="text-center">' + formatMoney(montantTVA) + '</td>' +
|
||||
'<td class="text-center">' + formatMoney(totalTTC) + '</td>' +
|
||||
'</tr>'
|
||||
);
|
||||
}
|
||||
|
||||
$('#mentions_default').html(myresp.mentions_default);
|
||||
}));
|
||||
})
|
||||
|
||||
@ -146,70 +146,25 @@
|
||||
<h2 class="mt-3 mb-3 text-center"> <?php p($l->t('Quote')); ?>
|
||||
<div id="devisid" style="display:inline" data-table="devis" data-column="num"
|
||||
data-id="<?php echo $currentDevis->id; ?>">sur le defunt <?php echo $currentDevis->nom_defunt; ?></div>
|
||||
<span data-html2canvas-ignore>(</span>
|
||||
<div data-html2canvas-ignore id="devisversion" style="display:inline" data-table="devis"
|
||||
data-column="version" data-id="<?php echo $currentDevis->id; ?>"><?php echo $currentDevis->lieu; ?>)</div>
|
||||
</h2>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div class="col-5 h-100 m-0" style="min-height:250px;">
|
||||
<?php $res = json_decode($_['configuration'])[0]; ?>
|
||||
<h5 class="p-3 m-0 text-dark text-center border border-2 border-dark"><?php p($l->t('FROM')); ?>
|
||||
<?php echo $res->entreprise; ?></h5>
|
||||
<p
|
||||
class="p-3 m-0 h-auto text-center text-dark text-center border border-top-0 border-2 border-dark">
|
||||
<?php echo $res->prenom . " " . $res->nom; ?><br />
|
||||
<?php echo $res->adresse; ?><br />
|
||||
<?php echo $res->mail; ?><br />
|
||||
<?php echo $res->telephone; ?><br />
|
||||
<span id="nothing"></span><br />
|
||||
</p>
|
||||
<div class="col col-md">
|
||||
<label class="fw-bold"><?php p($l->t('Number')); ?> : </label>
|
||||
<div class="col col-xl mb-3 text-center" style="display:inline">
|
||||
<?php echo $currentDevis->num; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2 h-100 m-0" style="min-height:250px;">
|
||||
<?php
|
||||
if (isset($_['logo']) && $_['logo'] !== "nothing") {
|
||||
echo "<center><a><img alt='" . $l->t('Company logo') . "' class=\"img-fluid\" src=\"data:image/png;base64, " . $_['logo'] . "\"/></a></center>";
|
||||
} else {
|
||||
echo "<span style='font-size:12px' id='Company-logo' data-html2canvas-ignore><b><center>" . $l->t('You can add your company logo here.') . "</center></b><br/><i>" . $l->t('To add a logo, drop the logo.png file in ".gestion" folder at the root of your Nextcloud Files app. Remember to set "Show hidden files".') . "</i><br/><br/><center>" . $l->t('This message will not appear on generated PDF.') . "</center></span>";
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="col-5 h-100 m-0" style="min-height:250px;">
|
||||
<h5 class="p-3 m-0 text-dark text-center border border-2 border-dark"><?php p($l->t('TO')); ?>
|
||||
<span id="entreprise"><?php echo $currentDevis->entreprise ?></span></h6>
|
||||
<p
|
||||
class="p-3 m-0 h-auto text-center text-dark text-center border border-top-0 border-2 border-dark">
|
||||
<span id="nomprenom" data-id="0" data-table="devis"
|
||||
data-column="id_client"><?php echo $currentDevis->prenom . ' ' . $currentDevis->nom ?></span><br />
|
||||
<span id="adresse"><?php echo $currentDevis->adresse_cli ?></span><br />
|
||||
<span id="mail"><?php echo $currentDevis->mail_cli ?></span><br />
|
||||
<span id="telephone"><?php echo $currentDevis->telephone_cli ?></span><br />
|
||||
<span id="legal_one"><?php echo $currentDevis->legalone_cli ?></span><br />
|
||||
<span id="dateContext" style="display: none"><?php echo $facture->date ?></span>
|
||||
<span id="nomcli" style="display: none"><?php echo $currentDevis->prenom . ' ' . $currentDevis->nom ?></span>
|
||||
<span id="idcli" style="display: none"><?php echo $currentDevis->id_cli ?></span>
|
||||
<span id="etp" style="display: none"><?php echo $currentDevis->entreprise ?></span>
|
||||
<span class="pdf"
|
||||
style="display: none"><?php echo $currentDevis->entreprise . "_" . $currentDevis->id . "_v" . $currentDevis->version ?></span>
|
||||
</p>
|
||||
<div class="col col-md">
|
||||
<label class="fw-bold"><?php p($l->t('Date')); ?> : </label>
|
||||
<div class="col col-xl mb-3 text-center" style="display:inline">
|
||||
<?php echo $currentDevis->date; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col col-md">
|
||||
<hr />
|
||||
<div class="col col-xl mb-3 text-center">
|
||||
<b><span><?php p($l->t('Offer valid for 1 month from')); ?> :
|
||||
</span><span><?php echo (new DateTime($currentDevis->date))->format('d-m-Y'); ?></span></b></div>
|
||||
<hr />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col col-md">
|
||||
<div class="col col-xl text-center">
|
||||
<span>Date de soin :
|
||||
<b><?php echo (new DateTime($currentDevis->date))->format('d-m-Y'); ?></b>,</span> <span
|
||||
id="devisid" data-id=<?php echo $currentDevis->id; ?>>Defunt associé :
|
||||
<b><?php echo $currentDevis->nom_defunt; ?></b></span><br />
|
||||
<div class="d-flex flex-column">
|
||||
<span>Defunt : <b><?php echo $currentDevis->nom_defunt; ?></b></span>
|
||||
<span>Lieu : <b><?php echo $currentDevis->lieu; ?> (<?php echo $currentDevis->adresse_soin; ?>)</b>
|
||||
</div>
|
||||
</div>
|
||||
@ -245,23 +200,72 @@
|
||||
<th><?php p($l->t('Reference')); ?></th>
|
||||
<th><?php p($l->t('Designation')); ?></th>
|
||||
<th><?php p($l->t('Comment')); ?></th>
|
||||
<th><?php p($l->t('TVA'));?></th>
|
||||
<th><?php p($l->t('Quantity')); ?></th>
|
||||
<th><?php p($l->t('Unit price without VAT')); ?></th>
|
||||
<th><?php p($l->t('Total without VAT')); ?></th>
|
||||
<th><?php p($l->t('Unit price without VAT'));?></th>
|
||||
<th><?php p($l->t('Total without VAT'));?></th>
|
||||
<th><?php p($l->t('Total with VAT'));?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($currentDevis->dproduits as $key => $produit) { ?>
|
||||
<?php
|
||||
// ⭐ NOUVEAU: Grouper par taux de TVA pour les calculs
|
||||
$totalsByTva = [];
|
||||
|
||||
foreach ($currentDevis->dproduits as $key => $produit) {
|
||||
// Récupérer le taux de TVA du produit (défaut 20%)
|
||||
$tvaValue = isset($produit->tva) && $produit->tva !== null ? floatval($produit->tva) : 20.00;
|
||||
$totalHT = $produit->prix_unitaire * $produit->quantite;
|
||||
$totalTTC = $totalHT * (1 + $tvaValue / 100);
|
||||
|
||||
// Grouper par taux
|
||||
if (!isset($totalsByTva[$tvaValue])) {
|
||||
$totalsByTva[$tvaValue] = [
|
||||
'totalHT' => 0,
|
||||
'totalTVA' => 0,
|
||||
'totalTTC' => 0
|
||||
];
|
||||
}
|
||||
$totalsByTva[$tvaValue]['totalHT'] += $totalHT;
|
||||
$totalsByTva[$tvaValue]['totalTVA'] += ($totalTTC - $totalHT);
|
||||
$totalsByTva[$tvaValue]['totalTTC'] += $totalTTC;
|
||||
?>
|
||||
<tr>
|
||||
<td><?php echo $produit->reference ?></td>
|
||||
<td><?php echo $produit->description ?></td>
|
||||
<td><?php echo $produit->comment ?></td>
|
||||
<td><?php echo number_format($tvaValue, 0) ?>%</td>
|
||||
<td><?php echo $produit->quantite ?></td>
|
||||
<td>€<?php echo number_format($produit->prix_unitaire, 2) ?></td>
|
||||
<td>€<?php echo number_format($produit->prix_unitaire * $produit->quantite, 2) ?>
|
||||
</td>
|
||||
<td>€<?php echo number_format($totalHT, 2) ?></td>
|
||||
<td>€<?php echo number_format($totalTTC, 2) ?></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
<?php }
|
||||
|
||||
// ⭐ NOUVEAU: Trier par taux
|
||||
ksort($totalsByTva);
|
||||
|
||||
// ⭐ NOUVEAU: Afficher les totaux par TVA dans le tableau
|
||||
if (count($totalsByTva) > 0) {
|
||||
?>
|
||||
<tr class="table-secondary">
|
||||
<td colspan="8"><hr style="border-top: 2px solid #000; margin: 5px 0;"></td>
|
||||
</tr>
|
||||
<?php
|
||||
foreach ($totalsByTva as $tva => $totals) {
|
||||
?>
|
||||
<tr class="fw-bold">
|
||||
<td colspan="3">Total TVA <?php echo number_format($tva, 0) ?>%</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>€<?php echo number_format($totals['totalHT'], 2) ?></td>
|
||||
<td>€<?php echo number_format($totals['totalTTC'], 2) ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@ -270,28 +274,27 @@
|
||||
<thead class="bg-dark text-white">
|
||||
<tr>
|
||||
<th class="text-center"><?php p($l->t('Total without VAT')); ?></th>
|
||||
<th class="text-center"><?php p($l->t('VAT Rate')); ?></th>
|
||||
<th class="text-center"><?php p($l->t('Total VAT')); ?></th>
|
||||
<th class="text-center"><?php p($l->t('Total Price')); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$totalhtc = 0;
|
||||
$tva = json_decode($_['configuration'])[0]->tva_default;
|
||||
$totalttc = 0;
|
||||
$totalprice = 0;
|
||||
foreach ($currentDevis->dproduits as $key => $produit) {
|
||||
$totalhtc = $totalhtc + ($produit->quantite * $produit->prix_unitaire);
|
||||
// ⭐ NOUVEAU: Calculer les totaux généraux
|
||||
$totalGeneralHT = 0;
|
||||
$totalGeneralTVA = 0;
|
||||
$totalGeneralTTC = 0;
|
||||
|
||||
foreach ($totalsByTva as $totals) {
|
||||
$totalGeneralHT += $totals['totalHT'];
|
||||
$totalGeneralTVA += $totals['totalTVA'];
|
||||
$totalGeneralTTC += $totals['totalTTC'];
|
||||
}
|
||||
$totalttc = ($totalhtc * $tva) / 100;
|
||||
$totalprice = $totalhtc + $totalttc;
|
||||
?>
|
||||
<tr>
|
||||
<td>€<?php echo number_format($totalhtc, 2) ?></td>
|
||||
<td><?php echo $tva ?> %</td>
|
||||
<td>€<?php echo number_format($totalttc, 2) ?></td>
|
||||
<td>€<?php echo number_format($totalprice, 2) ?></td>
|
||||
<tr class="fw-bold">
|
||||
<td class="text-center">€<?php echo number_format($totalGeneralHT, 2) ?></td>
|
||||
<td class="text-center">€<?php echo number_format($totalGeneralTVA, 2) ?></td>
|
||||
<td class="text-center">€<?php echo number_format($totalGeneralTTC, 2) ?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -95,8 +95,11 @@
|
||||
<th><?php p($l->t('Reference'));?></th>
|
||||
<th><?php p($l->t('Designation'));?></th>
|
||||
<th><?php p($l->t('Comment'));?></th>
|
||||
<th><?php p($l->t('TVA'));?></th>
|
||||
<th><?php p($l->t('Quantity'));?></th>
|
||||
<th><?php p($l->t('Unit price with VAT'));?></th>
|
||||
<th><?php p($l->t('Unit price without VAT'));?></th>
|
||||
<th><?php p($l->t('Total with VAT'));?></th>
|
||||
<th><?php p($l->t('Total without VAT'));?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -116,9 +119,12 @@
|
||||
<th><?php p($l->t('Reference'));?></th>
|
||||
<th><?php p($l->t('Designation'));?></th>
|
||||
<th><?php p($l->t('Comment'));?></th>
|
||||
<th><?php p($l->t('TVA'));?></th>
|
||||
<th><?php p($l->t('Quantity'));?>(ml)</th>
|
||||
<th><?php p($l->t('Unit price without VAT'));?></th>
|
||||
<th><?php p($l->t('Total without VAT'));?></th>
|
||||
<th><?php p($l->t('Total with VAT'));?></th>
|
||||
<th><?php p($l->t('Total without VAT'));?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user