Skip to content

Commit fad7fa2

Browse files
committed
feat: add XmlBuilder for DPS XML generation (ABRASF 2.04)
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
1 parent d838f40 commit fad7fa2

1 file changed

Lines changed: 73 additions & 0 deletions

File tree

src/Xml/XmlBuilder.php

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
// SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
4+
// SPDX-License-Identifier: AGPL-3.0-or-later
5+
6+
declare(strict_types=1);
7+
8+
namespace LibreCodeCoop\NfsePHP\Xml;
9+
10+
use LibreCodeCoop\NfsePHP\Dto\DpsData;
11+
12+
/**
13+
* Builds the DPS (Documento Padrão de Serviço) XML payload.
14+
* Spec: ABRASF 2.04 / SEFIN Nacional 1.0.
15+
*/
16+
class XmlBuilder
17+
{
18+
private const XSD_NAMESPACE = 'http://www.sped.fazenda.gov.br/nfse';
19+
private const XSD_SCHEMA = 'http://www.sped.fazenda.gov.br/nfse tiDPS_v1.00.xsd';
20+
21+
public function buildDps(DpsData $dps): string
22+
{
23+
$doc = new \DOMDocument('1.0', 'UTF-8');
24+
$doc->preserveWhiteSpace = false;
25+
$doc->formatOutput = true;
26+
27+
$root = $doc->createElementNS(self::XSD_NAMESPACE, 'DPS');
28+
$root->setAttribute('xsi:schemaLocation', self::XSD_SCHEMA);
29+
$root->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
30+
$doc->appendChild($root);
31+
32+
$infDps = $doc->createElement('infDPS');
33+
$infDps->setAttribute('Id', 'DPS' . $dps->cnpjPrestador . date('YmdHis'));
34+
$root->appendChild($infDps);
35+
36+
// Municipality
37+
$cMun = $doc->createElement('cMun', $dps->municipioIbge);
38+
$infDps->appendChild($cMun);
39+
40+
// Prestador
41+
$prest = $doc->createElement('prest');
42+
$cnpj = $doc->createElement('CNPJ', $dps->cnpjPrestador);
43+
$prest->appendChild($cnpj);
44+
$infDps->appendChild($prest);
45+
46+
// Service block
47+
$serv = $doc->createElement('serv');
48+
49+
$itemListaServico = $doc->createElement('cServ');
50+
$itemListaServico->appendChild($doc->createElement('cTribNac', $dps->itemListaServico));
51+
$serv->appendChild($itemListaServico);
52+
53+
$serv->appendChild($doc->createElement('xDescServ', htmlspecialchars($dps->discriminacao, ENT_XML1)));
54+
$infDps->appendChild($serv);
55+
56+
// Values
57+
$valores = $doc->createElement('valores');
58+
$valores->appendChild($doc->createElement('vServ', $dps->valorServico));
59+
$valores->appendChild($doc->createElement('trib', $this->buildTrib($doc, $dps)));
60+
$infDps->appendChild($valores);
61+
62+
return $doc->saveXML() ?: '';
63+
}
64+
65+
private function buildTrib(\DOMDocument $doc, DpsData $dps): \DOMElement
66+
{
67+
$trib = $doc->createElement('tribMun');
68+
$trib->appendChild($doc->createElement('tribISSQN', $dps->issRetido ? '2' : '1'));
69+
$trib->appendChild($doc->createElement('pAliq', $dps->aliquota));
70+
71+
return $trib;
72+
}
73+
}

0 commit comments

Comments
 (0)