@@ -529,6 +529,66 @@ public function testRuntimeXmlBuilderStartsInfDpsWithTpAmbBeforeMunicipalityFiel
529529 self ::assertStringNotContainsString ('<cMun>3303302</cMun> ' , $ normalizedXml );
530530 }
531531
532+ public function testEmitFallsBackToNoRetentionWhenTypeRequiresCsllButConfiguredValueIsZero (): void
533+ {
534+ ControllerIsolationState::$ settings ['nfse.federal_piscofins_tipo_retencao ' ] = '4 ' ;
535+ ControllerIsolationState::$ settings ['nfse.federal_valor_csll ' ] = '0.00 ' ;
536+
537+ $ invoice = InvoiceControllerIsolationState::makeInvoice (
538+ id: 204 ,
539+ amount: 1000.00 ,
540+ items: [
541+ ['name ' => 'Servico fallback retencao ' ],
542+ ],
543+ );
544+
545+ $ client = new class () implements NfseClientInterface {
546+ public ?DpsData $ capturedDps = null ;
547+
548+ public function emit (DpsData $ dps ): ReceiptData
549+ {
550+ $ this ->capturedDps = $ dps ;
551+
552+ return new ReceiptData (
553+ nfseNumber: 'NF-204 ' ,
554+ chaveAcesso: 'CHAVE-204 ' ,
555+ dataEmissao: '2026-04-03T12:00:00-03:00 ' ,
556+ );
557+ }
558+
559+ public function query (string $ chaveAcesso ): ReceiptData
560+ {
561+ throw new \BadMethodCallException ('Not used in this test. ' );
562+ }
563+
564+ public function cancel (string $ chaveAcesso , string $ motivo ): bool
565+ {
566+ throw new \BadMethodCallException ('Not used in this test. ' );
567+ }
568+ };
569+
570+ $ controller = new class ($ client ) extends InvoiceController {
571+ public function __construct (private readonly NfseClientInterface $ client )
572+ {
573+ }
574+
575+ protected function makeClient (bool $ sandboxMode ): NfseClientInterface
576+ {
577+ return $ this ->client ;
578+ }
579+
580+ protected function hasCertificateSecret (string $ cnpj ): bool
581+ {
582+ return true ;
583+ }
584+ };
585+
586+ $ controller ->emit ($ invoice );
587+
588+ self ::assertSame ('0 ' , $ client ->capturedDps ?->federalPiscofinsTipoRetencao);
589+ self ::assertSame ('' , $ client ->capturedDps ?->federalValorCsll);
590+ }
591+
532592 public function testEmitPrefersDefaultCompanyServiceOverLegacyFiscalSettings (): void
533593 {
534594 $ invoice = InvoiceControllerIsolationState::makeInvoice (
0 commit comments