Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/Dto/DpsData.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 = '',
) {
}
}
48 changes: 48 additions & 0 deletions src/Xml/XmlBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down Expand Up @@ -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 !== '';
}
}
50 changes: 50 additions & 0 deletions tests/Unit/Xml/XmlBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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('<tribFed>', $xml);
self::assertStringContainsString('<sitTribPISCOFINS>1</sitTribPISCOFINS>', $xml);
self::assertStringContainsString('<tpRetPISCOFINSCSLL>3</tpRetPISCOFINSCSLL>', $xml);
self::assertStringContainsString('<vBCPISCOFINS>1000.00</vBCPISCOFINS>', $xml);
self::assertStringContainsString('<pAliqPIS>1.65</pAliqPIS>', $xml);
self::assertStringContainsString('<vPIS>16.50</vPIS>', $xml);
self::assertStringContainsString('<pAliqCOFINS>7.60</pAliqCOFINS>', $xml);
self::assertStringContainsString('<vCOFINS>76.00</vCOFINS>', $xml);
self::assertStringContainsString('<vIRRF>15.00</vIRRF>', $xml);
self::assertStringContainsString('<vCSLL>10.00</vCSLL>', $xml);
self::assertStringContainsString('<vCP>5.00</vCP>', $xml);
}

// -------------------------------------------------------------------------

public function testNonSimplesnacionalMustNotIncludeIndtottribAndPaliq(): void
Expand Down Expand Up @@ -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,
Expand All @@ -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,
);
}
}
Loading