Commit 2e65dd2e authored by Mahmoud Aglan's avatar Mahmoud Aglan

Apply mandated 50% discount for 2023/2024 subscriptions

- Migration: retroactively applies 50% discount to all unpaid 2023/2024
  subscription rows (discount on gross total = base + dev fee)
- SubscriptionGenerator: year-specific discount now applied on per-row total
  (base + dev_fee) and stored in discount_amount column, not just on base rate

Business rule: SUBSCRIPTION_YEAR_ADJUSTMENT_2023 mandates 50% reduction on
the final subscription total for all person types in that fiscal year.
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent fc2128c5
...@@ -26,15 +26,11 @@ final class SubscriptionGenerator ...@@ -26,15 +26,11 @@ final class SubscriptionGenerator
$devFeeData = RuleEngine::get('DEVELOPMENT_FEE'); $devFeeData = RuleEngine::get('DEVELOPMENT_FEE');
$devFee = $devFeeData['amount'] ?? '35.00'; $devFee = $devFeeData['amount'] ?? '35.00';
// Apply year-specific discount/increase from rules // Year-specific discount: applied on final total (base + dev fee) per row
$yearAdjustment = RuleEngine::get('SUBSCRIPTION_YEAR_ADJUSTMENT_' . $yearSuffix); $yearAdjustment = RuleEngine::get('SUBSCRIPTION_YEAR_ADJUSTMENT_' . $yearSuffix);
$discountPct = null;
if ($yearAdjustment && isset($yearAdjustment['discount_percentage'])) { if ($yearAdjustment && isset($yearAdjustment['discount_percentage'])) {
$discPct = $yearAdjustment['discount_percentage']; $discountPct = $yearAdjustment['discount_percentage'];
$multiplier = bcsub('1.00', bcdiv($discPct, '100', 4), 4);
$memberRate = bcmul($memberRate, $multiplier, 2);
$spouseRate = bcmul($spouseRate, $multiplier, 2);
$childRate = bcmul($childRate, $multiplier, 2);
$tempRate = bcmul($tempRate, $multiplier, 2);
} }
// Get exempt membership types from subscription_rate_overrides // Get exempt membership types from subscription_rate_overrides
...@@ -78,7 +74,9 @@ final class SubscriptionGenerator ...@@ -78,7 +74,9 @@ final class SubscriptionGenerator
if ($existing) { $skipped++; continue; } if ($existing) { $skipped++; continue; }
// Member subscription // Member subscription
$total = bcadd($memberRate, $devFee, 2); $gross = bcadd($memberRate, $devFee, 2);
$discount = $discountPct ? bcdiv(bcmul($gross, $discountPct, 4), '100', 2) : '0.00';
$total = bcsub($gross, $discount, 2);
$db->insert('subscriptions', [ $db->insert('subscriptions', [
'member_id' => $memberId, 'member_id' => $memberId,
'financial_year' => $financialYear, 'financial_year' => $financialYear,
...@@ -87,6 +85,7 @@ final class SubscriptionGenerator ...@@ -87,6 +85,7 @@ final class SubscriptionGenerator
'person_name' => $member['full_name_ar'], 'person_name' => $member['full_name_ar'],
'base_amount' => $memberRate, 'base_amount' => $memberRate,
'development_fee' => $devFee, 'development_fee' => $devFee,
'discount_amount' => $discount,
'total_amount' => $total, 'total_amount' => $total,
'status' => 'pending', 'status' => 'pending',
'created_at' => $ts, 'created_at' => $ts,
...@@ -104,6 +103,8 @@ final class SubscriptionGenerator ...@@ -104,6 +103,8 @@ final class SubscriptionGenerator
[$memberId, $financialYear, (int) $sp['id']] [$memberId, $financialYear, (int) $sp['id']]
); );
if ($existingSp) { $skipped++; continue; } if ($existingSp) { $skipped++; continue; }
$spDiscount = $discountPct ? bcdiv(bcmul($spouseRate, $discountPct, 4), '100', 2) : '0.00';
$spTotal = bcsub($spouseRate, $spDiscount, 2);
$db->insert('subscriptions', [ $db->insert('subscriptions', [
'member_id' => $memberId, 'member_id' => $memberId,
'financial_year' => $financialYear, 'financial_year' => $financialYear,
...@@ -112,7 +113,8 @@ final class SubscriptionGenerator ...@@ -112,7 +113,8 @@ final class SubscriptionGenerator
'person_name' => $sp['full_name_ar'], 'person_name' => $sp['full_name_ar'],
'base_amount' => $spouseRate, 'base_amount' => $spouseRate,
'development_fee' => '0.00', 'development_fee' => '0.00',
'total_amount' => $spouseRate, 'discount_amount' => $spDiscount,
'total_amount' => $spTotal,
'status' => 'pending', 'status' => 'pending',
'created_at' => $ts, 'created_at' => $ts,
'updated_at' => $ts, 'updated_at' => $ts,
...@@ -131,6 +133,8 @@ final class SubscriptionGenerator ...@@ -131,6 +133,8 @@ final class SubscriptionGenerator
[$memberId, $financialYear, (int) $ch['id']] [$memberId, $financialYear, (int) $ch['id']]
); );
if ($existingCh) { $skipped++; continue; } if ($existingCh) { $skipped++; continue; }
$chDiscount = $discountPct ? bcdiv(bcmul($childRate, $discountPct, 4), '100', 2) : '0.00';
$chTotal = bcsub($childRate, $chDiscount, 2);
$db->insert('subscriptions', [ $db->insert('subscriptions', [
'member_id' => $memberId, 'member_id' => $memberId,
'financial_year' => $financialYear, 'financial_year' => $financialYear,
...@@ -139,7 +143,8 @@ final class SubscriptionGenerator ...@@ -139,7 +143,8 @@ final class SubscriptionGenerator
'person_name' => $ch['full_name_ar'], 'person_name' => $ch['full_name_ar'],
'base_amount' => $childRate, 'base_amount' => $childRate,
'development_fee' => '0.00', 'development_fee' => '0.00',
'total_amount' => $childRate, 'discount_amount' => $chDiscount,
'total_amount' => $chTotal,
'status' => 'pending', 'status' => 'pending',
'created_at' => $ts, 'created_at' => $ts,
'updated_at' => $ts, 'updated_at' => $ts,
...@@ -158,6 +163,8 @@ final class SubscriptionGenerator ...@@ -158,6 +163,8 @@ final class SubscriptionGenerator
[$memberId, $financialYear, (int) $t['id']] [$memberId, $financialYear, (int) $t['id']]
); );
if ($existingTmp) { $skipped++; continue; } if ($existingTmp) { $skipped++; continue; }
$tmpDiscount = $discountPct ? bcdiv(bcmul($tempRate, $discountPct, 4), '100', 2) : '0.00';
$tmpTotal = bcsub($tempRate, $tmpDiscount, 2);
$db->insert('subscriptions', [ $db->insert('subscriptions', [
'member_id' => $memberId, 'member_id' => $memberId,
'financial_year' => $financialYear, 'financial_year' => $financialYear,
...@@ -166,7 +173,8 @@ final class SubscriptionGenerator ...@@ -166,7 +173,8 @@ final class SubscriptionGenerator
'person_name' => $t['full_name_ar'], 'person_name' => $t['full_name_ar'],
'base_amount' => $tempRate, 'base_amount' => $tempRate,
'development_fee' => '0.00', 'development_fee' => '0.00',
'total_amount' => $tempRate, 'discount_amount' => $tmpDiscount,
'total_amount' => $tmpTotal,
'status' => 'pending', 'status' => 'pending',
'created_at' => $ts, 'created_at' => $ts,
'updated_at' => $ts, 'updated_at' => $ts,
......
<?php
declare(strict_types=1);
/**
* Apply the mandated 50% discount to all 2023/2024 subscriptions.
* Business rule: SUBSCRIPTION_YEAR_ADJUSTMENT_2023 = 50% discount on total (base + dev fee).
* The rule was created after subscriptions were already generated, so existing records
* were never updated. This migration retroactively applies the discount.
*
* Only updates UNPAID records. Paid records are left as-is (already settled).
*/
return function (\App\Core\Database $db): void {
$rows = $db->select(
"SELECT id, base_amount, development_fee, total_amount, discount_amount
FROM subscriptions
WHERE financial_year = '2023/2024' AND status IN ('pending', 'overdue')"
);
foreach ($rows as $row) {
$gross = bcadd($row['base_amount'], $row['development_fee'], 2);
$discount = bcdiv($gross, '2', 2); // 50%
$newTotal = bcsub($gross, $discount, 2);
$db->query(
"UPDATE subscriptions SET discount_amount = ?, total_amount = ?, updated_at = NOW() WHERE id = ?",
[$discount, $newTotal, (int) $row['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