feat: majoration 5% affichee partout (PDF, email, admin, page client)
Entite Echeancier : - MAJORATION_RATE = 0.05 constante - getMajoration() : montant de la majoration - getTotalWithMajoration() : total creance + 5% - getMonthlyAmount() : calcule sur le total majore Controller create : - Echeances calculees sur le total majore (pas le total brut) PDF EcheancierPdf : - Bloc resume : creance, majoration (rouge), total a payer - Tableau total : "TOTAL (creance + majoration 5%)" Email proposition : - Lignes creance, majoration +5% (rouge), total a payer Page process (client) : - 4 colonnes : creance, majoration 5%, total a payer, mensualite Admin show : - Carte "Creance + majoration 5%" avec detail Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -51,7 +51,9 @@ class EcheancierController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
$totalHtFloat = (float) str_replace(',', '.', $totalHt);
|
$totalHtFloat = (float) str_replace(',', '.', $totalHt);
|
||||||
$monthlyAmount = round($totalHtFloat / $nbEcheances, 2);
|
$majoration = round($totalHtFloat * Echeancier::MAJORATION_RATE, 2);
|
||||||
|
$totalMajore = round($totalHtFloat + $majoration, 2);
|
||||||
|
$monthlyAmount = round($totalMajore / $nbEcheances, 2);
|
||||||
|
|
||||||
$echeancier = new Echeancier($customer, $description, number_format($totalHtFloat, 2, '.', ''));
|
$echeancier = new Echeancier($customer, $description, number_format($totalHtFloat, 2, '.', ''));
|
||||||
|
|
||||||
@@ -65,7 +67,7 @@ class EcheancierController extends AbstractController
|
|||||||
for ($i = 1; $i <= $nbEcheances; ++$i) {
|
for ($i = 1; $i <= $nbEcheances; ++$i) {
|
||||||
$scheduledAt = $start->modify('+'.($i - 1).' months');
|
$scheduledAt = $start->modify('+'.($i - 1).' months');
|
||||||
$amount = $i === $nbEcheances
|
$amount = $i === $nbEcheances
|
||||||
? number_format($totalHtFloat - ($monthlyAmount * ($nbEcheances - 1)), 2, '.', '')
|
? number_format($totalMajore - ($monthlyAmount * ($nbEcheances - 1)), 2, '.', '')
|
||||||
: number_format($monthlyAmount, 2, '.', '');
|
: number_format($monthlyAmount, 2, '.', '');
|
||||||
|
|
||||||
$line = new EcheancierLine($echeancier, $i, $amount, $scheduledAt);
|
$line = new EcheancierLine($echeancier, $i, $amount, $scheduledAt);
|
||||||
|
|||||||
@@ -340,8 +340,26 @@ class Echeancier
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public const MAJORATION_RATE = 0.05;
|
||||||
|
|
||||||
// ── Computed ──
|
// ── Computed ──
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Montant de la majoration (5% du montant total).
|
||||||
|
*/
|
||||||
|
public function getMajoration(): float
|
||||||
|
{
|
||||||
|
return round((float) $this->totalAmountHt * self::MAJORATION_RATE, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Montant total avec majoration (total + 5%).
|
||||||
|
*/
|
||||||
|
public function getTotalWithMajoration(): float
|
||||||
|
{
|
||||||
|
return round((float) $this->totalAmountHt + $this->getMajoration(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
public function getNbLines(): int
|
public function getNbLines(): int
|
||||||
{
|
{
|
||||||
return $this->lines->count();
|
return $this->lines->count();
|
||||||
@@ -391,12 +409,12 @@ class Echeancier
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Montant mensuel (total / nb echeances).
|
* Montant mensuel (total majore / nb echeances).
|
||||||
*/
|
*/
|
||||||
public function getMonthlyAmount(): float
|
public function getMonthlyAmount(): float
|
||||||
{
|
{
|
||||||
$nb = $this->getNbLines();
|
$nb = $this->getNbLines();
|
||||||
|
|
||||||
return $nb > 0 ? round((float) $this->totalAmountHt / $nb, 2) : 0.0;
|
return $nb > 0 ? round($this->getTotalWithMajoration() / $nb, 2) : 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,10 +128,22 @@ class EcheancierPdf extends Fpdi
|
|||||||
$labelW = 55;
|
$labelW = 55;
|
||||||
|
|
||||||
$this->SetFont('Arial', '', 10);
|
$this->SetFont('Arial', '', 10);
|
||||||
$this->Cell($labelW, 6, $this->enc('Montant total HT :'), 0, 0, 'L');
|
$this->Cell($labelW, 6, $this->enc('Montant de la creance :'), 0, 0, 'L');
|
||||||
$this->SetFont('Arial', 'B', 10);
|
$this->SetFont('Arial', 'B', 10);
|
||||||
$this->Cell(0, 6, number_format((float) $this->echeancier->getTotalAmountHt(), 2, ',', ' ').' '.EURO, 0, 1, 'L');
|
$this->Cell(0, 6, number_format((float) $this->echeancier->getTotalAmountHt(), 2, ',', ' ').' '.EURO, 0, 1, 'L');
|
||||||
|
|
||||||
|
$this->SetFont('Arial', '', 10);
|
||||||
|
$this->Cell($labelW, 6, $this->enc('Majoration (5%) :'), 0, 0, 'L');
|
||||||
|
$this->SetFont('Arial', 'B', 10);
|
||||||
|
$this->SetTextColor(220, 38, 38);
|
||||||
|
$this->Cell(0, 6, '+ '.number_format($this->echeancier->getMajoration(), 2, ',', ' ').' '.EURO, 0, 1, 'L');
|
||||||
|
$this->SetTextColor(0, 0, 0);
|
||||||
|
|
||||||
|
$this->SetFont('Arial', '', 10);
|
||||||
|
$this->Cell($labelW, 6, $this->enc('Total a payer :'), 0, 0, 'L');
|
||||||
|
$this->SetFont('Arial', 'B', 11);
|
||||||
|
$this->Cell(0, 6, number_format($this->echeancier->getTotalWithMajoration(), 2, ',', ' ').' '.EURO, 0, 1, 'L');
|
||||||
|
|
||||||
$this->SetFont('Arial', '', 10);
|
$this->SetFont('Arial', '', 10);
|
||||||
$this->Cell($labelW, 6, $this->enc('Nombre d\'echeances :'), 0, 0, 'L');
|
$this->Cell($labelW, 6, $this->enc('Nombre d\'echeances :'), 0, 0, 'L');
|
||||||
$this->SetFont('Arial', 'B', 10);
|
$this->SetFont('Arial', 'B', 10);
|
||||||
@@ -182,11 +194,11 @@ class EcheancierPdf extends Fpdi
|
|||||||
$fill = !$fill;
|
$fill = !$fill;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Total
|
// Total avec majoration
|
||||||
$this->SetFont('Arial', 'B', 10);
|
$this->SetFont('Arial', 'B', 10);
|
||||||
$this->SetFillColor(253, 191, 4);
|
$this->SetFillColor(253, 191, 4);
|
||||||
$this->Cell(70, 8, $this->enc(' TOTAL'), 0, 0, 'L', true);
|
$this->Cell(70, 8, $this->enc(' TOTAL (creance + majoration 5%)'), 0, 0, 'L', true);
|
||||||
$this->Cell(50, 8, number_format((float) $this->echeancier->getTotalAmountHt(), 2, ',', ' ').' '.EURO, 0, 0, 'R', true);
|
$this->Cell(50, 8, number_format($this->echeancier->getTotalWithMajoration(), 2, ',', ' ').' '.EURO, 0, 0, 'R', true);
|
||||||
$this->Cell(50, 8, '', 0, 1, 'C', true);
|
$this->Cell(50, 8, '', 0, 1, 'C', true);
|
||||||
|
|
||||||
$this->Ln(5);
|
$this->Ln(5);
|
||||||
|
|||||||
@@ -39,8 +39,9 @@
|
|||||||
{# Resume #}
|
{# Resume #}
|
||||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
|
||||||
<div class="glass p-4">
|
<div class="glass p-4">
|
||||||
<p class="text-[9px] font-bold uppercase tracking-wider text-gray-400">Montant total</p>
|
<p class="text-[9px] font-bold uppercase tracking-wider text-gray-400">Creance + majoration 5%</p>
|
||||||
<p class="text-2xl font-bold mt-1">{{ echeancier.totalAmountHt|number_format(2, ',', ' ') }} €</p>
|
<p class="text-2xl font-bold mt-1">{{ echeancier.totalWithMajoration|number_format(2, ',', ' ') }} €</p>
|
||||||
|
<p class="text-[10px] text-gray-400 mt-1">{{ echeancier.totalAmountHt|number_format(2, ',', ' ') }} + <span class="text-red-500 font-bold">{{ echeancier.majoration|number_format(2, ',', ' ') }} €</span></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="glass p-4">
|
<div class="glass p-4">
|
||||||
<p class="text-[9px] font-bold uppercase tracking-wider text-gray-400">Mensualite</p>
|
<p class="text-[9px] font-bold uppercase tracking-wider text-gray-400">Mensualite</p>
|
||||||
|
|||||||
@@ -28,14 +28,19 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{# Resume #}
|
{# Resume #}
|
||||||
<div class="grid grid-cols-3 gap-3 mb-6">
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-3 mb-6">
|
||||||
<div class="glass p-3 text-center">
|
<div class="glass p-3 text-center">
|
||||||
<p class="text-[9px] font-bold uppercase tracking-wider text-gray-400">Total HT</p>
|
<p class="text-[9px] font-bold uppercase tracking-wider text-gray-400">Creance</p>
|
||||||
<p class="text-lg font-bold mt-1">{{ echeancier.totalAmountHt|number_format(2, ',', ' ') }} €</p>
|
<p class="text-lg font-bold mt-1">{{ echeancier.totalAmountHt|number_format(2, ',', ' ') }} €</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="glass p-3 text-center">
|
<div class="glass p-3 text-center">
|
||||||
<p class="text-[9px] font-bold uppercase tracking-wider text-gray-400">Echeances</p>
|
<p class="text-[9px] font-bold uppercase tracking-wider text-gray-400">Majoration 5%</p>
|
||||||
<p class="text-lg font-bold mt-1">{{ echeancier.nbLines }} mois</p>
|
<p class="text-lg font-bold mt-1 text-red-500">+ {{ echeancier.majoration|number_format(2, ',', ' ') }} €</p>
|
||||||
|
</div>
|
||||||
|
<div class="glass p-3 text-center">
|
||||||
|
<p class="text-[9px] font-bold uppercase tracking-wider text-gray-400">Total a payer</p>
|
||||||
|
<p class="text-lg font-bold mt-1">{{ echeancier.totalWithMajoration|number_format(2, ',', ' ') }} €</p>
|
||||||
|
<p class="text-[10px] text-gray-400">en {{ echeancier.nbLines }} mois</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="glass p-3 text-center">
|
<div class="glass p-3 text-center">
|
||||||
<p class="text-[9px] font-bold uppercase tracking-wider text-gray-400">Mensualite</p>
|
<p class="text-[9px] font-bold uppercase tracking-wider text-gray-400">Mensualite</p>
|
||||||
|
|||||||
@@ -17,8 +17,16 @@
|
|||||||
<td style="padding: 10px 16px; font-size: 13px; font-weight: 700;">{{ echeancier.description }}</td>
|
<td style="padding: 10px 16px; font-size: 13px; font-weight: 700;">{{ echeancier.description }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="padding: 10px 16px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; color: #9ca3af; background: #f9fafb;">Montant total HT</td>
|
<td style="padding: 10px 16px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; color: #9ca3af; background: #f9fafb;">Montant de la creance</td>
|
||||||
<td style="padding: 10px 16px; font-family: monospace; font-size: 16px; font-weight: 700;">{{ echeancier.totalAmountHt }} €</td>
|
<td style="padding: 10px 16px; font-family: monospace; font-size: 14px; font-weight: 700;">{{ echeancier.totalAmountHt }} €</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 10px 16px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; color: #9ca3af; background: #f9fafb;">Majoration (5%)</td>
|
||||||
|
<td style="padding: 10px 16px; font-family: monospace; font-size: 14px; font-weight: 700; color: #dc2626;">+ {{ echeancier.majoration|number_format(2, ',', ' ') }} €</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 10px 16px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; color: #9ca3af; background: #f9fafb;">Total a payer</td>
|
||||||
|
<td style="padding: 10px 16px; font-family: monospace; font-size: 16px; font-weight: 700;">{{ echeancier.totalWithMajoration|number_format(2, ',', ' ') }} €</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="padding: 10px 16px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; color: #9ca3af; background: #f9fafb;">Nombre d'echeances</td>
|
<td style="padding: 10px 16px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; color: #9ca3af; background: #f9fafb;">Nombre d'echeances</td>
|
||||||
|
|||||||
Reference in New Issue
Block a user