feat(discount): apply a discount rule to a session with audit
Extend PatientService::applyDiscount to carry the source rule id/label and add applyDiscountRule, which computes the rial amount via the engine (DiscountEngine::computeForRule now public) and records the rule for audit. updateSession accepts discount_rule_uuid (owner-scoped, takes precedence over the manual discount; ''/null clears). Verified end-to-end. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -50,6 +50,7 @@ class PatientService
|
||||
private readonly BillingCalculator $billingCalculator,
|
||||
private readonly WalletService $walletService,
|
||||
private readonly EntityInsurancePricingRepository $pricingRepo,
|
||||
private readonly \App\Discount\Service\DiscountEngine $discountEngine,
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -268,7 +269,7 @@ class PatientService
|
||||
* type=null → حذف تخفیف. percent باید 0..100 و fixed حداکثر برابر مبلغ نهایی باشد.
|
||||
* تخفیف نمیتواند از ماندهی قابلتخفیف (مبلغ نهایی منهای پرداختهای ثبتشده) بیشتر شود.
|
||||
*/
|
||||
public function applyDiscount(PatientSession $session, ?string $type, int $value): PatientSession
|
||||
public function applyDiscount(PatientSession $session, ?string $type, int $value, ?int $ruleId = null, ?string $ruleLabel = null): PatientSession
|
||||
{
|
||||
if ($type === null) {
|
||||
$session->setDiscount(null, 0, 0);
|
||||
@@ -298,15 +299,35 @@ class PatientService
|
||||
throw new AppException(ErrorCodes::ERR_SESSION_DISCOUNT_INVALID, null, 422, 'discount_value');
|
||||
}
|
||||
|
||||
$session->setDiscount($type, $value, $rials);
|
||||
$this->persistDiscount($session, $type, $value, $rials, $ruleId, $ruleLabel);
|
||||
|
||||
return $session;
|
||||
}
|
||||
|
||||
/**
|
||||
* اعمال یک قانون تخفیف روی مراجعه؛ مبلغ ریالی از موتور (با در نظر گرفتن نوع/مبنا)
|
||||
* محاسبه و منبع قانون برای audit ثبت میشود.
|
||||
*/
|
||||
public function applyDiscountRule(PatientSession $session, \App\Discount\Entity\DiscountRule $rule): PatientSession
|
||||
{
|
||||
$rials = $this->discountEngine->computeForRule($session, $rule);
|
||||
if ($rials <= 0) {
|
||||
throw new AppException(ErrorCodes::ERR_SESSION_DISCOUNT_INVALID, null, 422, 'discount_rule_uuid');
|
||||
}
|
||||
$this->persistDiscount($session, $rule->getDiscountType(), $rule->getValue(), $rials, $rule->getId(), $rule->getName());
|
||||
|
||||
return $session;
|
||||
}
|
||||
|
||||
private function persistDiscount(PatientSession $session, string $type, int $value, int $rials, ?int $ruleId, ?string $ruleLabel): void
|
||||
{
|
||||
$session->setDiscount($type, $value, $rials, $ruleId, $ruleLabel);
|
||||
if ($session->getRemainingRials() === 0 && $session->getPaymentMethod() === 'pending') {
|
||||
// تخفیف صددرصدی بدهی را صفر کرد — مراجعه تسویهشده تلقی میشود
|
||||
$session->setPaymentMethod('cash');
|
||||
$session->setPaidAt(time());
|
||||
}
|
||||
$this->sessionRepo->save($session);
|
||||
|
||||
return $session;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user