Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Délégation ChangeLog

## 1.0.2 (2026-01-20)

- Ajout d'une page récapitulative des factures fournisseurs en délégation dans les modèles PDF Inpose et Crabe BTP.

## 1.0.1 (2026-01-19)

- Ajout du support de l'autoliquidation de TVA sur les devis, commandes et factures client liés à un contrat de sous-traitance.
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Ce module gère :
- les contrats de sous-traitance ;
- l'autoliquidation de TVA sur les documents clients liés aux contrats de sous-traitance ;
- le formulaire DC4 (saisie, génération et données associées).
- un récapitulatif des factures fournisseurs en délégation dans certains modèles PDF.

Compatibilité : Dolibarr v21+.

Expand Down
265 changes: 265 additions & 0 deletions core/modules/facture/doc/pdf_crabe_btp_inpose.modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';

// TSubtotal
if (!empty($conf->subtotal->enabled)) dol_include_once('/subtotal/class/subtotal.class.php');
Expand Down Expand Up @@ -972,6 +974,10 @@ function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hid

}

// EN: Add supplier invoices summary page for delegation.
// FR: Ajouter la page récapitulative des factures fournisseurs en délégation.
$this->_addDelegationSupplierInvoicesSummaryPage($pdf, $object, $outputlangs, $tplidx);

$pdf->Close();

$pdf->Output($file,'F');
Expand Down Expand Up @@ -1003,6 +1009,265 @@ function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hid
}


/**
* Add supplier invoices summary page for delegation.
*
* @param TCPDF $pdf Object PDF
* @param Object $object Object invoice
* @param Translate $outputlangs Object lang for output
* @param int $tplidx Template index
* @return int <0 if KO, >=0 if OK
*/
protected function _addDelegationSupplierInvoicesSummaryPage(&$pdf, $object, $outputlangs, $tplidx)
{
global $conf;

if (empty($conf->delegation->enabled))
{
return 0;
}

$outputlangs->load("delegation@delegation");

// Load delegation lines and supplier invoice ids.
dol_include_once("/delegation/class/delegation.class.php");
$GLOBALS['object'] = $object;
$delegation = new Delegation($this->db);
$delegation->fetch();

$supplierInvoiceIds = array();
foreach ($delegation->lines as $line)
{
if (! empty($line->fk_facture_fourn))
{
$supplierInvoiceIds[] = (int) $line->fk_facture_fourn;
}
}
$supplierInvoiceIds = array_unique($supplierInvoiceIds);

if (empty($supplierInvoiceIds))
{
return 0;
}

// Order supplier invoices with same source as delegation tab.
$sql = "SELECT f.rowid";
$sql.= " FROM ".MAIN_DB_PREFIX."facture_fourn as f";
$sql.= " WHERE f.rowid IN (".implode(',', $supplierInvoiceIds).")";
$sql.= " ORDER BY f.datef DESC";

$resql = $this->db->query($sql);
if (! $resql)
{
$this->error = $this->db->lasterror();
return -1;
}

$supplierInvoices = array();
$total_ht = 0;
$total_tva = 0;
$total_ttc = 0;
while ($obj = $this->db->fetch_object($resql))
{
$invoice = new FactureFournisseur($this->db);
if ($invoice->fetch((int) $obj->rowid) > 0)
{
$invoice->fetch_thirdparty();
$supplierInvoices[] = $invoice;
$total_ht += (float) $invoice->total_ht;
$total_tva += (float) $invoice->total_tva;
$total_ttc += (float) $invoice->total_ttc;
}
}

if (empty($supplierInvoices))
{
return 0;
}

$default_font_size = pdf_getPDFFontSize($outputlangs);
$line_height = 6;
$title_top_offset = 25;
$table_top_offset = 5;
$posx = $this->marge_gauche;
$posy = $this->marge_haute;

// Start summary page.
$pdf->AddPage();
if (! empty($tplidx)) $pdf->useTemplate($tplidx);
if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);

$pdf->SetFont('', 'B', $default_font_size);
$pdf->SetXY($posx, $posy + $title_top_offset);
$pdf->MultiCell(0, 6, $outputlangs->transnoentities('DelegationSupplierInvoicesSummaryTitle'), 0, 'L', 0);
$posy = $pdf->GetY() + 2 + $table_top_offset;

$base_columns = array(
array('label' => $outputlangs->transnoentities('Ref'), 'width' => 26, 'align' => 'L'),
array('label' => $outputlangs->transnoentities('Supplier'), 'width' => 54, 'align' => 'L'),
array('label' => $outputlangs->transnoentities('AmountHT'), 'width' => 18, 'align' => 'R'),
array('label' => $outputlangs->transnoentities('AmountVAT'), 'width' => 18, 'align' => 'R'),
array('label' => $outputlangs->transnoentities('AmountTTC'), 'width' => 18, 'align' => 'R'),
array('label' => $outputlangs->transnoentities('DateInvoice'), 'width' => 28, 'align' => 'C'),
array('label' => $outputlangs->transnoentities('DateDue'), 'width' => 28, 'align' => 'C'),
);
$usable_width = $this->page_largeur - $this->marge_gauche - $this->marge_droite;
$base_total = 0;
foreach ($base_columns as $base_column)
{
$base_total += $base_column['width'];
}
$columns = array();
$running_width = 0;
foreach ($base_columns as $index => $base_column)
{
$column = $base_column;
if ($index === (count($base_columns) - 1))
{
$column['width'] = $usable_width - $running_width;
}
else
{
$column['width'] = $base_total > 0 ? round($base_column['width'] * $usable_width / $base_total, 2) : $base_column['width'];
$running_width += $column['width'];
}
$columns[] = $column;
}

// Draw table header.
$pdf->SetFillColor(230, 230, 230);
$pdf->SetFont('', 'B', $default_font_size - 1);
$curx = $posx;
foreach ($columns as $column)
{
$pdf->SetXY($curx, $posy);
$pdf->MultiCell($column['width'], $line_height, $column['label'], 1, 'C', 1);
$curx += $column['width'];
}
$posy += $line_height;

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

foreach ($supplierInvoices as $invoice)
{
// Robust dates for supplier invoices (Dolibarr v20+ / retro-compatible)
$invDate = ! empty($invoice->date) ? $invoice->date : (! empty($invoice->datef) ? $invoice->datef : 0);
$dueDate = ! empty($invoice->date_echeance) ? $invoice->date_echeance : (! empty($invoice->date_lim_reglement) ? $invoice->date_lim_reglement : 0);
$invoice_datef = ! empty($invDate) ? dol_print_date($invDate, 'day', false, $outputlangs) : '';
$invoice_date_due = ! empty($dueDate) ? dol_print_date($dueDate, 'day', false, $outputlangs, true) : '';
$values = array(
$invoice->ref,
$invoice->thirdparty->name,
price($invoice->total_ht, 0, $outputlangs),
price($invoice->total_tva, 0, $outputlangs),
price($invoice->total_ttc, 0, $outputlangs),
$invoice_datef,
$invoice_date_due,
);

$row_height = $line_height;
if (method_exists($pdf, 'getStringHeight'))
{
foreach ($values as $index => $value)
{
$row_height = max($row_height, $pdf->getStringHeight($columns[$index]['width'], $value));
}
}

if ($posy + $row_height > ($this->page_hauteur - $this->marge_basse))
{
$this->_pagefoot($pdf, $object, $outputlangs);
$pdf->AddPage();
if (! empty($tplidx)) $pdf->useTemplate($tplidx);
if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
$posy = $this->marge_haute;

$pdf->SetFont('', 'B', $default_font_size);
$pdf->SetXY($posx, $posy + $title_top_offset);
$pdf->MultiCell(0, 6, $outputlangs->transnoentities('DelegationSupplierInvoicesSummaryTitle'), 0, 'L', 0);
$posy = $pdf->GetY() + 2 + $table_top_offset;

$pdf->SetFillColor(230, 230, 230);
$pdf->SetFont('', 'B', $default_font_size - 1);
$curx = $posx;
foreach ($columns as $column)
{
$pdf->SetXY($curx, $posy);
$pdf->MultiCell($column['width'], $line_height, $column['label'], 1, 'C', 1);
$curx += $column['width'];
}
$posy += $line_height;
$pdf->SetFont('', '', $default_font_size - 1);
}

$curx = $posx;
foreach ($values as $index => $value)
{
$pdf->SetXY($curx, $posy);
$pdf->MultiCell($columns[$index]['width'], $row_height, $value, 1, $columns[$index]['align'], 0);
$curx += $columns[$index]['width'];
}
$posy += $row_height;
}

// Totals row with invoice count.
$total_label = $outputlangs->transnoentities('DelegationTotalsWithCount', count($supplierInvoices));
$row_height = $line_height;
if (method_exists($pdf, 'getStringHeight'))
{
$row_height = max($row_height, $pdf->getStringHeight($columns[0]['width'] + $columns[1]['width'], $total_label));
}

if ($posy + $row_height > ($this->page_hauteur - $this->marge_basse))
{
$this->_pagefoot($pdf, $object, $outputlangs);
$pdf->AddPage();
if (! empty($tplidx)) $pdf->useTemplate($tplidx);
if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
$posy = $this->marge_haute;

$pdf->SetFont('', 'B', $default_font_size);
$pdf->SetXY($posx, $posy + $title_top_offset);
$pdf->MultiCell(0, 6, $outputlangs->transnoentities('DelegationSupplierInvoicesSummaryTitle'), 0, 'L', 0);
$posy = $pdf->GetY() + 2 + $table_top_offset;

$pdf->SetFillColor(230, 230, 230);
$pdf->SetFont('', 'B', $default_font_size - 1);
$curx = $posx;
foreach ($columns as $column)
{
$pdf->SetXY($curx, $posy);
$pdf->MultiCell($column['width'], $line_height, $column['label'], 1, 'C', 1);
$curx += $column['width'];
}
$posy += $line_height;
}

$pdf->SetFont('', 'B', $default_font_size - 1);
$pdf->SetXY($posx, $posy);
$pdf->MultiCell($columns[0]['width'] + $columns[1]['width'], $row_height, $total_label, 1, 'L', 0);

$curx = $posx + $columns[0]['width'] + $columns[1]['width'];
$totals_values = array(
price($total_ht, 0, $outputlangs),
price($total_tva, 0, $outputlangs),
price($total_ttc, 0, $outputlangs),
'',
'',
);
foreach ($totals_values as $index => $value)
{
$column_index = $index + 2;
$pdf->SetXY($curx, $posy);
$pdf->MultiCell($columns[$column_index]['width'], $row_height, $value, 1, $columns[$column_index]['align'], 0);
$curx += $columns[$column_index]['width'];
}

$this->_pagefoot($pdf, $object, $outputlangs);

return 1;
}

/**
* Show payments table
*
Expand Down
Loading