Commit bc0c0106 authored by Mahmoud Aglan's avatar Mahmoud Aglan

Fix price override printing original value instead of overridden price

The program invoice item was stored with unit_price = original programFee,
then recalculateTotals() summed items and overwrote total_amount back to
the original — so the printed invoice showed the pre-override amount.

Fix: apply the override delta directly to the item's unit_price so the item
row and invoice total are consistent. Metadata now stores original_price =
programFee (per-item, not order total) for the strikethrough display on print.
Co-Authored-By: 's avatarClaude Sonnet 4.6 <noreply@anthropic.com>
parent 6472b1f0
...@@ -955,35 +955,44 @@ public function confirm(): void ...@@ -955,35 +955,44 @@ public function confirm(): void
if ($subtotal > 0 || $finalTotal !== $computedTotal) { if ($subtotal > 0 || $finalTotal !== $computedTotal) {
$invoiceItems = []; $invoiceItems = [];
// When override is active, compute how much the program fee is adjusted.
// The override replaces the entire order total, so the delta comes off the program item.
$effectiveProgramFee = $programFee;
$programItemMeta = [];
if ($this->priceOverrideEnabled && $actor->is_super_admin && $finalTotal !== $computedTotal && $programFee > 0) {
// Override delta = difference between computed and final totals (hotbuy items are untouched)
$overrideDelta = $finalTotal - $computedTotal; // negative = discount, positive = surcharge
$effectiveProgramFee = max(0, $programFee + $overrideDelta);
$programItemMeta = [
'original_price' => $programFee, // per-item original, not order total
'overridden_price' => $effectiveProgramFee,
'override_reason' => $this->priceOverrideReason,
'overridden_by' => $actor->name,
];
}
if ($programFee > 0) { if ($programFee > 0) {
$description = $program->name_ar; $description = $program->name_ar;
if ($prorationResult->applied) { if ($prorationResult->applied) {
$description .= ' (' . $prorationResult->description . ')'; $description .= ' (' . $prorationResult->description . ')';
} }
$programItemMeta = [];
if ($this->priceOverrideEnabled && $actor->is_super_admin && $finalTotal !== $computedTotal) {
$programItemMeta['original_price'] = $computedTotal;
$programItemMeta['overridden_price'] = $finalTotal;
$programItemMeta['override_reason'] = $this->priceOverrideReason;
$programItemMeta['overridden_by'] = $actor->name;
}
$invoiceItems[] = [ $invoiceItems[] = [
'description' => $description, 'description' => $description,
'quantity' => 1, 'quantity' => 1,
'unit_price' => $programFee, 'unit_price' => $effectiveProgramFee, // ← overridden value, not original
'discount_amount' => 0, 'discount_amount' => 0,
'tax_amount' => 0, 'tax_amount' => 0,
'metadata' => $programItemMeta ?: [], 'metadata' => $programItemMeta ?: [],
]; ];
} }
foreach ($this->hotbuyCart as $cartItem) { foreach ($this->hotbuyCart as $cartItem) {
$itemEntry = [ $itemEntry = [
'description' => $cartItem['name_ar'], 'description' => $cartItem['name_ar'],
'quantity' => $cartItem['quantity'], 'quantity' => $cartItem['quantity'],
'unit_price' => $cartItem['price'], 'unit_price' => $cartItem['price'],
'discount_amount' => 0, 'discount_amount' => 0,
'tax_amount' => 0, 'tax_amount' => 0,
]; ];
if ($cartItem['type'] === 'product') { if ($cartItem['type'] === 'product') {
$itemEntry['itemable_type'] = Product::class; $itemEntry['itemable_type'] = Product::class;
...@@ -995,11 +1004,9 @@ public function confirm(): void ...@@ -995,11 +1004,9 @@ public function confirm(): void
$invoiceItems[] = $itemEntry; $invoiceItems[] = $itemEntry;
} }
// If override changed total, reflect as a discount line // No separate discount line needed — the program item already carries the overridden price,
// so recalculateTotals() will sum to $finalTotal correctly.
$discountAmount = 0; $discountAmount = 0;
if ($this->priceOverrideEnabled && $actor->is_super_admin && $finalTotal < $computedTotal) {
$discountAmount = $computedTotal - $finalTotal;
}
$invoice = $invoiceService->create([ $invoice = $invoiceService->create([
'academy_id' => app('current_academy')->id, 'academy_id' => app('current_academy')->id,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment