cius-pt
v0.1.1
Published
Validação de faturas eletrónicas CIUS-PT 2.1.1 (UBL 2.1) para a Administração Pública portuguesa, localmente e em integração contínua.
Maintainers
Readme
cius-pt
Validação de faturas eletrónicas para a Administração Pública portuguesa, CIUS-PT 2.1.1 em UBL 2.1, localmente e em integração contínua. Sem Java, sem servidor, sem conta.
$ npx cius-pt fatura.xml
INVÁLIDO fatura.xml Fatura 2 erros, 0 avisos
✗ DT-CIUS-PT-002 [DT-CIUS-PT-002]-The BT-2 does not meet the defined format: YYYY-MM-DD.
em /Invoice[1]/cbc:IssueDate[1]
✗ DT-CIUS-PT-003_i [DT-CIUS-PT-003]-The BT-3 only allows the following values: 380, 383, 386, 389, FT, FS, FR, ND, RP, RE, CS, LD, RA.
em /Invoice[1]/cbc:InvoiceTypeCode[1]
1 documento: 0 válidos, 1 inválido.O código de saída é 1 quando algum documento tem um erro fatal, por isso funciona tal como está num passo de CI.
O que verifica
As regras são as da eSPap. O Schematron publicado com a CIUS-PT 2.1.1 (26 de fevereiro de 2021) é compilado numa tabela de regras e executado no próprio processo por um motor XPath 3.1. São 1.155 asserções: as regras base da EN 16931 mais 65 verificações BR-CIUS-PT e 291 DT-CIUS-PT. Os identificadores e as mensagens das regras são os da eSPap, por isso um erro aqui corresponde ao que a plataforma FE-AP indicaria. As mensagens estão em inglês porque é assim que a eSPap as publica.
Cada resultado traz um bloco coverage. assertionsEvaluated indica quantas asserções foram avaliadas no documento e unsupported lista as que o motor não conseguiu avaliar, com o erro do motor. Nos quinze documentos de exemplo da eSPap essa lista está vazia.
Não verifica, por opção:
- A estrutura XML Schema (XSD UBL 2.1 da OASIS). O Schematron apanha a maioria dos erros estruturais, mas um documento pode estar bem formado, passar aqui e ainda assim ser rejeitado por razões de esquema.
- Assinaturas digitais e certificados.
- A transmissão para a FE-AP.
- SAF-T, ATCUD e código QR. Pertencem ao software de faturação certificado, e este pacote fica fora desse âmbito.
Biblioteca
import { validate } from 'cius-pt';
const result = validate(xmlString);
result.valid; // sem erros fatais
result.documentType; // 'Invoice' | 'CreditNote' | null
result.customizationId; // o texto de cbc:CustomizationID
result.errors; // erros fatais: { id, flag, message, location, pattern }
result.warnings; // avisos
result.coverage; // { assertionsInSpecification, assertionsEvaluated, unsupported, notChecked }location é um XPath posicional para o elemento onde a regra falhou, com os prefixos do próprio documento.
Linha de comandos
npx cius-pt fatura.xml nota-de-credito.xml # texto legível, código de saída 1 se algum for inválido
npx cius-pt --json fatura.xml # o objeto de resultado completo de cada ficheiroDesempenho
Medido num portátil, com o motor já carregado: 0,25 segundos para o exemplo mais pequeno da eSPap, 0,7 segundos para o maior, cerca de 15 segundos para uma fatura de 500 linhas e cerca de 65 segundos para 2.000 linhas, de forma linear no número de linhas. Duas coisas tornam isto possível. Uma regra da eSPap verifica o tamanho dos anexos com uma expressão regular que um motor JavaScript demoraria minutos a avaliar, por isso o compilador reescreve-a no teste equivalente ao comprimento do texto. E as expressões que não dependem do nó de contexto, como a verificação de identificadores de linha únicos, são avaliadas uma vez por documento em vez de uma vez por nó.
Estado
Fase inicial. Validado com os quinze documentos de exemplo que a eSPap publica com a especificação; todos passam. Comparado com o validador público da eSPap a 23 de outubro de 2026: os exemplos válidos também são válidos lá, e um código de tipo de fatura errado devolve o mesmo identificador de regra, DT-CIUS-PT-003_i. Há uma diferença intencional: a eSPap corre primeiro o XSD UBL, por isso uma data mal formatada é lá um erro de esquema e aqui DT-CIUS-PT-002. Faturas geradas com 50, 500 e 2.000 linhas e totais exatos são válidas nos dois. scripts/compare-espap.ts repete esta comparação para qualquer documento seu, e scripts/make-stress-fixtures.ts gera os documentos grandes. Se um documento for rejeitado pela FE-AP e aceite aqui, ou o contrário, abra um issue com o documento, alterando os montantes e as entidades.
Desenvolvimento
npm install
npm run compile-rules # spec/cius-pt-2.1.1/schematron -> src/rules/cius-pt-2.1.1.ts
npm test
npm run build # dist/ com tsup
npx tsx scripts/compare-espap.ts fixtures/espap-2.1.1/F_e.xml # compara com o validador público da eSPapOs ficheiros Schematron em spec/ são da eSPap, reproduzidos sem alterações. Ver spec/cius-pt-2.1.1/NOTICE.md e fixtures/espap-2.1.1/NOTICE.md.
