orderBy('created_at', 'desc') ->paginate($perPage); } public function findById(int $id): ?TbrCalculation { return TbrCalculation::with([ 'unit', 'user', 'royaltiesBracket', 'fnmBracket', 'maintenanceBracket', ])->find($id); } public function calculate(array $data): TbrCalculation { return DB::transaction(function () use ($data) { $unit = Unit::findOrFail($data['unit_id']); $franchiseeUnit = FranchiseeUnit::where('unit_id', $unit->id)->firstOrFail(); $franchiseeTbr = FranchiseeTbr::where('franchisee_id', $franchiseeUnit->franchisee_id) ->where('year', now()->year) ->firstOrFail(); $tbrValue = (float) $franchiseeTbr->tbr_value; $contractMonth = (int) $data['contract_month_reference']; $revenueValue = (float) $data['revenue_value']; $royaltiesBracket = $this->findBracket(FranchiseeRoyaltiesBracket::class, $franchiseeUnit->franchisee_id, $contractMonth); $fnmBracket = $this->findBracket(FranchiseeFnmBracket::class, $franchiseeUnit->franchisee_id, $contractMonth); $maintenanceBracket = $this->findBracket(FranchiseeMaintenanceBracket::class, $franchiseeUnit->franchisee_id, $contractMonth); $royaltiesBracketValue = round((float) $royaltiesBracket->percentage * $tbrValue, 2); $fnmBracketValue = round((float) $fnmBracket->percentage * $tbrValue, 2); $maintenanceBracketValue = round((float) $maintenanceBracket->percentage * $tbrValue, 2); [$royaltiesEffectiveValue, $royaltiesEffectivePercentage, $royaltiesAppliedCriteria, $fnmEffectiveValue, $fnmEffectivePercentage] = $this->resolveEffectiveValues( $contractMonth, $revenueValue, $royaltiesBracket, $royaltiesBracketValue, $fnmBracket, $fnmBracketValue, ); $maintenanceEffectiveValue = $maintenanceBracketValue; $maintenanceEffectivePercentage = (float) $maintenanceBracket->percentage; $bracketSubtotal = round($royaltiesBracketValue + $fnmBracketValue + $maintenanceBracketValue, 2); $subtotal = round($royaltiesEffectiveValue + $fnmEffectiveValue + $maintenanceEffectiveValue, 2); return TbrCalculation::create([ 'unit_id' => $unit->id, 'revenue_value' => $revenueValue, 'contract_month_reference' => $contractMonth, 'tbr_value' => $tbrValue, 'royalties_bracket_id' => $royaltiesBracket->id, 'royalties_bracket_percentage' => $royaltiesBracket->percentage, 'royalties_bracket_value' => $royaltiesBracketValue, 'fnm_bracket_id' => $fnmBracket->id, 'fnm_bracket_percentage' => $fnmBracket->percentage, 'fnm_bracket_value' => $fnmBracketValue, 'maintenance_bracket_id' => $maintenanceBracket->id, 'maintenance_bracket_percentage' => $maintenanceBracket->percentage, 'maintenance_bracket_value' => $maintenanceBracketValue, 'royalties_effective_percentage' => $royaltiesEffectivePercentage, 'royalties_effective_value' => $royaltiesEffectiveValue, 'fnm_effective_percentage' => $fnmEffectivePercentage, 'fnm_effective_value' => $fnmEffectiveValue, 'maintenance_effective_percentage' => $maintenanceEffectivePercentage, 'maintenance_effective_value' => $maintenanceEffectiveValue, 'bracket_subtotal' => $bracketSubtotal, 'subtotal' => $subtotal, 'final_value' => $subtotal, 'user_id' => Auth::id(), 'royalties_applied_criteria' => $royaltiesAppliedCriteria, 'receivable_generated' => false, ]); }); } private function resolveEffectiveValues( int $contractMonth, float $revenueValue, FranchiseeRoyaltiesBracket $royaltiesBracket, float $royaltiesBracketValue, FranchiseeFnmBracket $fnmBracket, float $fnmBracketValue, ): array { if ($contractMonth <= self::EXEMPT_THRESHOLD_MONTH) { return [0.0, 0.0, 'tbr_fixo', 0.0, 0.0]; } $royaltiesFromRevenue = round(self::ROYALTIES_REVENUE_RATE * $revenueValue, 2); $fnmFromRevenue = round(self::FNM_REVENUE_RATE * $revenueValue, 2); if ($royaltiesBracketValue >= $royaltiesFromRevenue) { $royaltiesEffectiveValue = $royaltiesBracketValue; $royaltiesEffectivePercentage = (float) $royaltiesBracket->percentage; $royaltiesAppliedCriteria = 'tbr_fixo'; } else { $royaltiesEffectiveValue = $royaltiesFromRevenue; $royaltiesEffectivePercentage = self::ROYALTIES_REVENUE_RATE; $royaltiesAppliedCriteria = 'percentual_faturamento'; } if ($fnmBracketValue >= $fnmFromRevenue) { $fnmEffectiveValue = $fnmBracketValue; $fnmEffectivePercentage = (float) $fnmBracket->percentage; } else { $fnmEffectiveValue = $fnmFromRevenue; $fnmEffectivePercentage = self::FNM_REVENUE_RATE; } return [$royaltiesEffectiveValue, $royaltiesEffectivePercentage, $royaltiesAppliedCriteria, $fnmEffectiveValue, $fnmEffectivePercentage]; } private function findBracket(string $modelClass, int $franchiseeId, int $contractMonth): mixed { return $modelClass::where('franchisee_id', $franchiseeId) ->where('start_month', '<=', $contractMonth) ->where(function ($q) use ($contractMonth) { $q->whereNull('end_month')->orWhere('end_month', '>=', $contractMonth); }) ->firstOrFail(); } }