service = app(TbrBillingPreviewService::class); $country = Country::create(['name' => 'Brasil', 'code' => 'BR']); $state = State::create(['name' => 'Paraná', 'code' => 'PR', 'country_id' => $country->id]); $city = City::create(['name' => 'Maringá', 'country_id' => $country->id, 'state_id' => $state->id]); $this->unit = Unit::create([ 'fantasy_name' => 'Unidade Teste', 'social_reason' => 'Unidade Teste LTDA', 'cnpj' => '00000000000191', 'street' => 'Rua Teste', 'neighborhood' => 'Centro', 'postal_code' => '87000000', 'city_id' => $city->id, 'state_id' => $state->id, 'email' => 'unidade@teste.com', 'name_responsible' => 'Responsável Teste', ]); $size = MunicipalitySize::create(['acronym' => 'GP', 'description' => 'De 100 mil a 200 mil habitantes']); foreach ([[1, 3, 0.0], [4, 12, 0.75], [13, 60, 1.00]] as [$start, $end, $percentage]) { InhabitantClassification::create([ 'municipality_size_id' => $size->id, 'description' => "Faixa {$start}-{$end}", 'start' => $start, 'end' => $end, 'tbr_percentage' => $percentage, 'is_renewal' => false, ]); } Tbr::create([ 'year' => 2026, 'tbr_value' => 1000.00, 'royalties_percentage' => 0.08, 'fnm_percentage' => 0.20, 'maintenance_percentage' => 0.30, ]); FranchiseeContract::create([ 'unit_id' => $this->unit->id, 'protocol' => 1, 'name' => 'Contrato de Franquia', 'description' => 'Contrato de teste', 'start_date' => '2026-01-01', 'end_date' => '2031-01-01', 'signature_date' => '2026-01-01', 'validity_months' => 60, 'invoice_due_date' => 10, 'municipality_size_id' => $size->id, 'tbr_fixed_value' => 1000.00, ]); } protected function tearDown(): void { Carbon::setTestNow(); parent::tearDown(); } /** * Regra: A tela usa exatamente a mesma fórmula do cálculo oficial — fixo (8% * base x 75% da faixa GP = 6% da TBR = R$ 60,00) vence porque não há faturamento * lançado (nenhuma parcela cadastrada). */ public function test_usa_a_mesma_regra_do_calculo_oficial(): void { $result = $this->service->getAll()->firstWhere('id', $this->unit->id); $this->assertNotNull($result); $this->assertEquals(60.0, $result['royalties_value']); $this->assertSame('Fixo TBR', $result['royalties_rule']); $this->assertEquals(200.0, $result['fnm_value']); $this->assertSame('Fixo TBR', $result['fnm_rule']); $this->assertEquals(300.0, $result['maintenance_value']); $this->assertEquals(560.0, $result['total']); } /** * Regra: Respeita a flag charge_roi da unidade — royalties zerado, rótulo * "Não cobrado", assim como no cálculo oficial. */ public function test_respeita_a_flag_charge_roi(): void { UnitFinancial::create(['unit_id' => $this->unit->id, 'charge_roi' => false, 'charge_fnm' => true]); $result = $this->service->getAll()->firstWhere('id', $this->unit->id); $this->assertEquals(0.0, $result['royalties_value']); $this->assertSame('Não cobrado', $result['royalties_rule']); } /** * Regra: Mês 1-3 aparece como "Isento" em vez de "Fixo TBR". */ public function test_marca_isento_nos_meses_1_a_3(): void { Carbon::setTestNow(Carbon::create(2026, 2, 15)); // mês de contrato 2 $result = $this->service->getAll()->firstWhere('id', $this->unit->id); $this->assertEquals(0.0, $result['royalties_value']); $this->assertSame('Isento', $result['royalties_rule']); $this->assertEquals(0.0, $result['fnm_value']); $this->assertSame('Isento', $result['fnm_rule']); $this->assertEquals(300.0, $result['maintenance_value']); } }