diff --git a/app/app/Services/Billing/BalancePreflightService.php b/app/app/Services/Billing/BalancePreflightService.php new file mode 100644 index 00000000..b56249f1 --- /dev/null +++ b/app/app/Services/Billing/BalancePreflightService.php @@ -0,0 +1,49 @@ + $tiers + */ + public function evaluate( + string $balanceRub, + int $deliveredInMonth, + int $requiredLeads, + Collection $tiers, + ): PreflightResult { + if ($requiredLeads <= 0) { + return new PreflightResult(true, 0, 0, 0); + } + + $capacity = (int) $this->converter->convert($balanceRub, $deliveredInMonth, $tiers)['leads']; + $passes = $capacity >= $requiredLeads; + + return new PreflightResult( + passes: $passes, + requiredLeads: $requiredLeads, + capacityLeads: $capacity, + deficitLeads: $passes ? 0 : ($requiredLeads - $capacity), + ); + } +} diff --git a/app/app/Services/Billing/PreflightResult.php b/app/app/Services/Billing/PreflightResult.php new file mode 100644 index 00000000..eb99899e --- /dev/null +++ b/app/app/Services/Billing/PreflightResult.php @@ -0,0 +1,20 @@ + 1, 'leads_in_tier' => null, 'price_per_lead_kopecks' => 5000, 'is_active' => true]), + ]); +} + +it('passes when balance covers full daily limit', function () { + $service = new BalancePreflightService; + // 2000₽ / 50₽ = 40 лидов capacity; нужно 30 → проходит. + $result = $service->evaluate( + balanceRub: '2000.00', + deliveredInMonth: 0, + requiredLeads: 30, + tiers: makeTiers(), + ); + + expect($result->passes)->toBeTrue(); + expect($result->capacityLeads)->toBe(40); + expect($result->requiredLeads)->toBe(30); + expect($result->deficitLeads)->toBe(0); +}); + +it('fails when balance below full daily limit', function () { + $service = new BalancePreflightService; + // 1000₽ / 50₽ = 20 лидов capacity; нужно 30 → не проходит, дефицит 10. + $result = $service->evaluate( + balanceRub: '1000.00', + deliveredInMonth: 0, + requiredLeads: 30, + tiers: makeTiers(), + ); + + expect($result->passes)->toBeFalse(); + expect($result->capacityLeads)->toBe(20); + expect($result->deficitLeads)->toBe(10); +}); + +it('passes trivially when requiredLeads is zero', function () { + $service = new BalancePreflightService; + $result = $service->evaluate('0.00', 0, 0, makeTiers()); + expect($result->passes)->toBeTrue(); +});