Skip to content

Commit

Permalink
NEW: PDF Invoice show vat analysis per rate (#31381)
Browse files Browse the repository at this point in the history
* Show vat analysis

* Show vat analysis

* Show vat analysis

* fix white space

* Update main.lang

* Show vat analysis

* Show vat analysis

* add copyright

* fix pre-commit

* fix pre-commit

* fix pre-commit

* fix php-stan (8.2)

* fix php-stan (8.2)

* fix php-stan (8.2)

* fix pre-commit tab

* Update pdf_other.php

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
  • Loading branch information
sonikf and eldy authored Nov 13, 2024
1 parent 2c4d103 commit 1f2bb29
Show file tree
Hide file tree
Showing 6 changed files with 375 additions and 121 deletions.
39 changes: 28 additions & 11 deletions htdocs/admin/pdf_other.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Copyright (C) 2019 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2021-2024 Anthony Berton <anthony.berton@bb2a.fr>
* Copyright (C) 2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 Nick Fragoulis
*
* This program is free software; you can redistribute it and/or modify
Expand Down Expand Up @@ -128,6 +128,20 @@
dolibarr_set_const($db, "INVOICE_SHOW_SHIPPING_ADDRESS", GETPOSTINT("INVOICE_SHOW_SHIPPING_ADDRESS"), 'chaine', 0, '', $conf->entity);
dolibarr_del_const($db, "INVOICE_SHOW_SHIPPING_ADDRESS", $conf->entity);
}
if (GETPOSTISSET('PDF_INVOICE_SHOW_VAT_ANALYSIS')) {
dolibarr_set_const($db, "PDF_INVOICE_SHOW_VAT_ANALYSIS", GETPOSTINT("PDF_INVOICE_SHOW_VAT_ANALYSIS"), 'chaine', 0, '', $conf->entity);
dolibarr_del_const($db, "PDF_INVOICE_SHOW_VAT_ANALYSIS", $conf->entity);
}
if (GETPOSTISSET('BARCODE_ON_SHIPPING_PDF')) {
dolibarr_set_const($db, "BARCODE_ON_SHIPPING_PDF", GETPOSTINT("BARCODE_ON_SHIPPING_PDF"), 'chaine', 0, '', $conf->entity);
}
if (GETPOSTISSET('BARCODE_ON_RECEPTION_PDF')) {
dolibarr_set_const($db, "BARCODE_ON_RECEPTION_PDF", GETPOSTINT("BARCODE_ON_RECEPTION_PDF"), 'chaine', 0, '', $conf->entity);
}
if (GETPOSTISSET('BARCODE_ON_STOCKTRANSFER_PDF')) {
dolibarr_set_const($db, "BARCODE_ON_STOCKTRANSFER_PDF", GETPOSTINT("BARCODE_ON_STOCKTRANSFER_PDF"), 'chaine', 0, '', $conf->entity);
}

// Terms of sale
if ($_FILES['termsofsale']["name"]) {
if (!preg_match('/(\.pdf)$/i', $_FILES['termsofsale']["name"])) { // Document can be used on a lot of different places. Only pdf can be supported.
Expand All @@ -143,16 +157,6 @@
}
}

if (GETPOSTISSET('BARCODE_ON_SHIPPING_PDF')) {
dolibarr_set_const($db, "BARCODE_ON_SHIPPING_PDF", GETPOSTINT("BARCODE_ON_SHIPPING_PDF"), 'chaine', 0, '', $conf->entity);
}
if (GETPOSTISSET('BARCODE_ON_RECEPTION_PDF')) {
dolibarr_set_const($db, "BARCODE_ON_RECEPTION_PDF", GETPOSTINT("BARCODE_ON_RECEPTION_PDF"), 'chaine', 0, '', $conf->entity);
}
if (GETPOSTISSET('BARCODE_ON_STOCKTRANSFER_PDF')) {
dolibarr_set_const($db, "BARCODE_ON_STOCKTRANSFER_PDF", GETPOSTINT("BARCODE_ON_STOCKTRANSFER_PDF"), 'chaine', 0, '', $conf->entity);
}

setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');

header("Location: ".$_SERVER["PHP_SELF"]."?mainmenu=home&leftmenu=setup");
Expand Down Expand Up @@ -437,6 +441,19 @@
}
print '</td></tr>';

/* too late to have it enabled by default in v21
print '<tr class="oddeven"><td>';
print $form->textwithpicto($langs->trans("PDF_INVOICE_SHOW_VAT_ANALYSIS"), '');
print '</td><td>';
if ($conf->use_javascript_ajax) {
print ajax_constantonoff('PDF_INVOICE_SHOW_VAT_ANALYSIS');
} else {
$arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
print $form->selectarray("PDF_INVOICE_SHOW_VAT_ANALYSIS", $arrval, $conf->global->PDF_INVOICE_SHOW_VAT_ANALYSIS);
}
print '</td></tr>';
*/

Check failure on line 456 in htdocs/admin/pdf_other.php

View workflow job for this annotation

GitHub Actions / pre-commit / pre-commit

Whitespace found at end of line
/* Keep this option hidden for the moment to avoid options inflation. We'll see later if it is used enough...
print '<tr class="oddeven"><td>';
print $form->textwithpicto($langs->trans("SUPPLIER_PROPOSAL_ADD_BILLING_CONTACT"), $langs->trans("SUPPLIER_PROPOSAL_ADD_BILLING_CONTACTMore"));
Expand Down
133 changes: 105 additions & 28 deletions htdocs/core/modules/facture/doc/pdf_crabe.modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -796,10 +796,17 @@ public function write_file($object, $outputlangs, $srctemplatepath = '', $hidede
}
$this->tva[$vatrate] += $tvaligne; // ->tva is abandoned, we use now ->tva_array that is more complete
$vatcode = $object->lines[$i]->vat_src_code;
if (empty($this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'])) {
$this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] = 0;
if (getDolGlobalInt('PDF_INVOICE_SHOW_VAT_ANALYSIS')) {
if (empty($this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['tot_ht'])) {
$this->tva_array[$vatrate . ($vatcode ? ' (' . $vatcode . ')' : '')]['tot_ht'] = 0;
}
$this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate'=>$vatrate, 'vatcode'=>$vatcode, 'amount'=> $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne, 'tot_ht'=> $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['tot_ht'] + $object->lines[$i]->total_ht);
} else {
if (empty($this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'])) {
$this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] = 0;
}
$this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate' => $vatrate, 'vatcode' => $vatcode, 'amount' => $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne);
}
$this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')] = array('vatrate' => $vatrate, 'vatcode' => $vatcode, 'amount' => $this->tva_array[$vatrate.($vatcode ? ' ('.$vatcode.')' : '')]['amount'] + $tvaligne);

if ($posYAfterImage > $posYAfterDescription) {
$nexY = $posYAfterImage;
Expand Down Expand Up @@ -1161,6 +1168,65 @@ protected function _tableau_info(&$pdf, $object, $posy, $outputlangs, $outputlan

$pdf->SetFont('', '', $default_font_size - 1);

krsort($this->tva_array);

// Show VAT details
if ($object->total_tva != 0 && getDolGlobalInt('PDF_INVOICE_SHOW_VAT_ANALYSIS')) {
$pdf->SetFillColor(224, 224, 224);

$pdf->SetFont('', '', $default_font_size - 2);
$pdf->SetXY($this->marge_gauche, $posy);
$titre = $outputlangs->transnoentities("VAT");
$pdf->MultiCell(25, 4, $titre, 0, 'L', true);

$pdf->SetFont('', '', $default_font_size - 2);
$pdf->SetXY($this->marge_gauche + 25, $posy);
$titre = $outputlangs->transnoentities("NetTotal");
$pdf->MultiCell(25, 4, $titre, 0, 'L', true);

$pdf->SetFont('', '', $default_font_size - 2);
$pdf->SetXY($this->marge_gauche + 50, $posy);
$titre = $outputlangs->transnoentities("VATAmount");
$pdf->MultiCell(25, 4, $titre, 0, 'L', true);

$pdf->SetFont('', '', $default_font_size - 2);
$pdf->SetXY($this->marge_gauche + 75, $posy);
$titre = $outputlangs->transnoentities("AmountTotal");
$pdf->MultiCell(25, 4, $titre, 0, 'L', true);

$posy = $pdf->GetY();
$tot_ht = 0;
$tot_tva = 0;
$tot_ttc = 0;

foreach ($this->tva_array as $tvakey => $tvaval) {
$pdf->SetFont('', '', $default_font_size - 2);
$pdf->SetXY($this->marge_gauche, $posy);
$titre = round((float) $tvakey, 2) . "%";
$pdf->MultiCell(25, 4, $titre, 0, 'L');

$pdf->SetFont('', '', $default_font_size - 2);
$pdf->SetXY($this->marge_gauche + 25, $posy);
$titre = price($tvaval['tot_ht']);
$pdf->MultiCell(25, 4, $titre, 0, 'L');
$tot_ht += $tvaval['tot_ht'];

$pdf->SetFont('', '', $default_font_size - 2);
$pdf->SetXY($this->marge_gauche + 50, $posy);
$titre = price($tvaval['amount']);
$pdf->MultiCell(25, 4, $titre, 0, 'L');
$tot_tva += $tvaval['amount'];

$pdf->SetFont('', '', $default_font_size - 2);
$pdf->SetXY($this->marge_gauche + 75, $posy);
$titre = price($tvaval['tot_ht'] + $tvaval['amount']);
$pdf->MultiCell(25, 4, $titre, 0, 'L');
$tot_ttc += ($tvaval['tot_ht'] + $tvaval['amount']);

$posy = $pdf->GetY();
}
}

// If France, show VAT mention if not applicable
if ($this->emetteur->country_code == 'FR' && empty($mysoc->tva_assuj)) {
$pdf->SetFont('', 'B', $default_font_size - 2);
Expand Down Expand Up @@ -1456,6 +1522,16 @@ protected function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($sign * ($total_ht + (!empty($object->remise) ? $object->remise : 0)), 0, $outputlangs), 0, 'R', 1);

if (getDolGlobalInt('PDF_INVOICE_SHOW_VAT_ANALYSIS')) {
$index++;
$pdf->SetFillColor(255, 255, 255);
$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $outputlangs->transnoentities("TotalVAT"), 0, 'L', 1);

$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($sign * $object->total_tva), 0, 'R', 1);
}

// Show VAT by rates and total
$pdf->SetFillColor(248, 248, 248);

Expand Down Expand Up @@ -1542,34 +1618,35 @@ protected function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs
}
}

// VAT
foreach ($this->tva_array as $tvakey => $tvaval) {
if ($tvakey != 0) { // On affiche pas taux 0
$this->atleastoneratenotnull++;
if (!getDolGlobalInt('PDF_INVOICE_SHOW_VAT_ANALYSIS')) {
// VAT
foreach ($this->tva_array as $tvakey => $tvaval) {
if ($tvakey != 0) { // On affiche pas taux 0
$this->atleastoneratenotnull++;

$index++;
$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
$index++;
$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);

$tvacompl = '';
if (preg_match('/\*/', $tvakey)) {
$tvakey = str_replace('*', '', $tvakey);
$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
}
$totalvat = $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalVAT", $mysoc->country_code) : '');
$totalvat .= ' ';
if (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'rateonly') {
$totalvat .= vatrate($tvaval['vatrate'], true).$tvacompl;
} elseif (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'codeonly') {
$totalvat .= $tvaval['vatcode'].$tvacompl;
} elseif (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
$totalvat .= $tvacompl;
} else {
$totalvat .= vatrate($tvaval['vatrate'], true).($tvaval['vatcode'] ? ' ('.$tvaval['vatcode'].')' : '').$tvacompl;
$tvacompl = '';
if (preg_match('/\*/', $tvakey)) {
$tvakey = str_replace('*', '', $tvakey);
$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
}
$totalvat = $outputlangs->transcountrynoentities("TotalVAT", $mysoc->country_code).(is_object($outputlangsbis) ? ' / '.$outputlangsbis->transcountrynoentities("TotalVAT", $mysoc->country_code) : '');
$totalvat .= ' ';
if (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'rateonly') {
$totalvat .= vatrate($tvaval['vatrate'], true).$tvacompl;
} elseif (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'codeonly') {
$totalvat .= $tvaval['vatcode'].$tvacompl;
} elseif (getDolGlobalString('PDF_VAT_LABEL_IS_CODE_OR_RATE') == 'nocodenorate') {
$totalvat .= $tvacompl;
} else {
$totalvat .= vatrate($tvaval['vatrate'], true).($tvaval['vatcode'] ? ' ('.$tvaval['vatcode'].')' : '').$tvacompl;
}
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price(price2num($tvaval['amount'], 'MT'), 0, $outputlangs), 0, 'R', 1);
}
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);

$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price(price2num($tvaval['amount'], 'MT'), 0, $outputlangs), 0, 'R', 1);
}
}

Expand Down
Loading

0 comments on commit 1f2bb29

Please sign in to comment.