TbrBillingPreviewService.php 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. <?php
  2. namespace App\Services;
  3. use App\Models\FranchiseeContract;
  4. use Illuminate\Support\Collection;
  5. class TbrBillingPreviewService
  6. {
  7. private const MAINTENANCE_RATE = 0.30;
  8. private const EXEMPT_MONTHS = 3;
  9. public function getAll(): Collection
  10. {
  11. $latestContracts = FranchiseeContract::with('unit')
  12. ->whereNotNull('tbr_fixed_value')
  13. ->whereNotNull('unit_id')
  14. ->orderByDesc('created_at')
  15. ->get()
  16. ->unique('unit_id')
  17. ->values();
  18. return $latestContracts->map(fn ($contract) => $this->buildPreview($contract));
  19. }
  20. private function buildPreview(FranchiseeContract $contract): array
  21. {
  22. $tbrValue = (float) $contract->tbr_fixed_value;
  23. $contractMonth = $this->resolveContractMonth($contract);
  24. $isExempt = $contractMonth <= self::EXEMPT_MONTHS;
  25. $royaltiesValue = $isExempt ? 0.0 : round($tbrValue * (float) $contract->tbr_fixed_value_percentage, 2);
  26. $fnmValue = $isExempt ? 0.0 : round($tbrValue * (float) $contract->marketing_fund_percentage, 2);
  27. $maintenanceValue = round($tbrValue * self::MAINTENANCE_RATE, 2);
  28. return [
  29. 'id' => $contract->unit_id,
  30. 'unit_name' => $contract->unit?->fantasy_name,
  31. 'tbr_value' => $tbrValue,
  32. 'royalties_value' => $royaltiesValue,
  33. 'royalties_rule' => 'Fixo TBR',
  34. 'fnm_value' => $fnmValue,
  35. 'fnm_rule' => 'Fixo TBR',
  36. 'maintenance_value' => $maintenanceValue,
  37. 'total' => round($royaltiesValue + $fnmValue + $maintenanceValue, 2),
  38. ];
  39. }
  40. private function resolveContractMonth(FranchiseeContract $contract): int
  41. {
  42. $startDate = $contract->start_date ?? $contract->signature_date;
  43. if (!$startDate) {
  44. return 1;
  45. }
  46. return (int) $startDate->startOfMonth()->diffInMonths(now()->startOfMonth()) + 1;
  47. }
  48. }