diff --git a/src/Dto/DpsData.php b/src/Dto/DpsData.php index 40be054..bd51b83 100644 --- a/src/Dto/DpsData.php +++ b/src/Dto/DpsData.php @@ -74,6 +74,36 @@ public function __construct( /** Whether ISS is retained at source. */ public bool $issRetido = false, + + /** Situação Tributária do PIS/COFINS (CST). */ + public string $federalPiscofinsSituacaoTributaria = '', + + /** Tipo de retenção do PIS/COFINS/CSLL. */ + public string $federalPiscofinsTipoRetencao = '', + + /** Base de cálculo do PIS/COFINS. */ + public string $federalPiscofinsBaseCalculo = '', + + /** Alíquota do PIS. */ + public string $federalPiscofinsAliquotaPis = '', + + /** Valor do PIS. */ + public string $federalPiscofinsValorPis = '', + + /** Alíquota do COFINS. */ + public string $federalPiscofinsAliquotaCofins = '', + + /** Valor do COFINS. */ + public string $federalPiscofinsValorCofins = '', + + /** Valor do IRRF. */ + public string $federalValorIrrf = '', + + /** Valor das contribuições sociais retidas (CSLL). */ + public string $federalValorCsll = '', + + /** Valor da contribuição previdenciária retida. */ + public string $federalValorCp = '', ) { } } diff --git a/src/Xml/XmlBuilder.php b/src/Xml/XmlBuilder.php index fe162a6..61a37ee 100644 --- a/src/Xml/XmlBuilder.php +++ b/src/Xml/XmlBuilder.php @@ -101,6 +101,10 @@ private function buildTotTrib(\DOMDocument $doc, DpsData $dps): \DOMElement $totTrib->appendChild($tribMun); + if ($this->hasFederalTaxationData($dps)) { + $totTrib->appendChild($this->buildTribFederal($doc, $dps)); + } + // E0715: indTotTrib is ALWAYS included to avoid schema validation errors $totTrib->appendChild($doc->createElement('indTotTrib', (string) $dps->indicadorTributacao)); @@ -133,4 +137,48 @@ private function buildToma(\DOMDocument $doc, DpsData $dps): \DOMElement return $toma; } + + private function buildTribFederal(\DOMDocument $doc, DpsData $dps): \DOMElement + { + $tribFed = $doc->createElement('tribFed'); + + if ($dps->federalPiscofinsSituacaoTributaria !== '') { + $tribFed->appendChild($doc->createElement('sitTribPISCOFINS', $dps->federalPiscofinsSituacaoTributaria)); + } + + if ($dps->federalPiscofinsTipoRetencao !== '') { + $tribFed->appendChild($doc->createElement('tpRetPISCOFINSCSLL', $dps->federalPiscofinsTipoRetencao)); + } + + foreach ([ + 'vBCPISCOFINS' => $dps->federalPiscofinsBaseCalculo, + 'pAliqPIS' => $dps->federalPiscofinsAliquotaPis, + 'vPIS' => $dps->federalPiscofinsValorPis, + 'pAliqCOFINS' => $dps->federalPiscofinsAliquotaCofins, + 'vCOFINS' => $dps->federalPiscofinsValorCofins, + 'vIRRF' => $dps->federalValorIrrf, + 'vCSLL' => $dps->federalValorCsll, + 'vCP' => $dps->federalValorCp, + ] as $tag => $value) { + if ($value !== '') { + $tribFed->appendChild($doc->createElement($tag, $value)); + } + } + + return $tribFed; + } + + private function hasFederalTaxationData(DpsData $dps): bool + { + return $dps->federalPiscofinsSituacaoTributaria !== '' + || $dps->federalPiscofinsTipoRetencao !== '' + || $dps->federalPiscofinsBaseCalculo !== '' + || $dps->federalPiscofinsAliquotaPis !== '' + || $dps->federalPiscofinsValorPis !== '' + || $dps->federalPiscofinsAliquotaCofins !== '' + || $dps->federalPiscofinsValorCofins !== '' + || $dps->federalValorIrrf !== '' + || $dps->federalValorCsll !== '' + || $dps->federalValorCp !== ''; + } } diff --git a/tests/Unit/Xml/XmlBuilderTest.php b/tests/Unit/Xml/XmlBuilderTest.php index 57b6345..ee22abe 100644 --- a/tests/Unit/Xml/XmlBuilderTest.php +++ b/tests/Unit/Xml/XmlBuilderTest.php @@ -195,6 +195,36 @@ public function testBuildDpsAlwaysIncludesProviderTaxRegime(): void self::assertSame('0', $nodes->item(0)->textContent); } + public function testBuildDpsIncludesFederalTaxationBlockWhenConfigured(): void + { + $dps = $this->makeDps( + federalPiscofinsSituacaoTributaria: '1', + federalPiscofinsTipoRetencao: '3', + federalPiscofinsBaseCalculo: '1000.00', + federalPiscofinsAliquotaPis: '1.65', + federalPiscofinsValorPis: '16.50', + federalPiscofinsAliquotaCofins: '7.60', + federalPiscofinsValorCofins: '76.00', + federalValorIrrf: '15.00', + federalValorCsll: '10.00', + federalValorCp: '5.00', + ); + + $xml = $this->builder->buildDps($dps); + + self::assertStringContainsString('', $xml); + self::assertStringContainsString('1', $xml); + self::assertStringContainsString('3', $xml); + self::assertStringContainsString('1000.00', $xml); + self::assertStringContainsString('1.65', $xml); + self::assertStringContainsString('16.50', $xml); + self::assertStringContainsString('7.60', $xml); + self::assertStringContainsString('76.00', $xml); + self::assertStringContainsString('15.00', $xml); + self::assertStringContainsString('10.00', $xml); + self::assertStringContainsString('5.00', $xml); + } + // ------------------------------------------------------------------------- public function testNonSimplesnacionalMustNotIncludeIndtottribAndPaliq(): void @@ -261,6 +291,16 @@ private function makeDps( int $tipoRetencaoIss = 1, int $opcaoSimplesNacional = 1, int $indicadorTributacao = 0, + string $federalPiscofinsSituacaoTributaria = '', + string $federalPiscofinsTipoRetencao = '', + string $federalPiscofinsBaseCalculo = '', + string $federalPiscofinsAliquotaPis = '', + string $federalPiscofinsValorPis = '', + string $federalPiscofinsAliquotaCofins = '', + string $federalPiscofinsValorCofins = '', + string $federalValorIrrf = '', + string $federalValorCsll = '', + string $federalValorCp = '', ): DpsData { return new DpsData( cnpjPrestador: $cnpjPrestador, @@ -279,6 +319,16 @@ private function makeDps( issRetido: $issRetido, opcaoSimplesNacional: $opcaoSimplesNacional, indicadorTributacao: $indicadorTributacao, + federalPiscofinsSituacaoTributaria: $federalPiscofinsSituacaoTributaria, + federalPiscofinsTipoRetencao: $federalPiscofinsTipoRetencao, + federalPiscofinsBaseCalculo: $federalPiscofinsBaseCalculo, + federalPiscofinsAliquotaPis: $federalPiscofinsAliquotaPis, + federalPiscofinsValorPis: $federalPiscofinsValorPis, + federalPiscofinsAliquotaCofins: $federalPiscofinsAliquotaCofins, + federalPiscofinsValorCofins: $federalPiscofinsValorCofins, + federalValorIrrf: $federalValorIrrf, + federalValorCsll: $federalValorCsll, + federalValorCp: $federalValorCp, ); } }