diff --git a/.gitignore b/.gitignore
index 8204312a..10d3305c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -54,4 +54,5 @@ target
*dependency-reduced-pom.xml
/lsp/
-bin/
\ No newline at end of file
+bin/
+.vscode/*
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index c5f3f6b9..b84f89c3 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,3 +1,4 @@
{
- "java.configuration.updateBuildConfiguration": "interactive"
+ "java.configuration.updateBuildConfiguration": "interactive",
+ "java.compile.nullAnalysis.mode": "automatic"
}
\ No newline at end of file
diff --git a/README.md b/README.md
index 56252dbd..fb7d5b9f 100644
--- a/README.md
+++ b/README.md
@@ -1,48 +1,95 @@
+# XHandler Java
+
[](https://www.apache.org/licenses/LICENSE-2.0)
[](https://github.com/project-openubl/xhandler/actions/workflows/ci.yml)
-
[](https://projectopenubl.zulipchat.com/)
[](https://github.com/project-openubl/xhandler/actions/)
-| Artifact | Version |
-|-------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| XBuilder | [](https://search.maven.org/artifact/io.github.project-openubl/xbuilder/) |
-| XBuilder Quarkus extension | [](https://search.maven.org/artifact/io.github.project-openubl/quarkus-xbuilder/) |
-| XSender | [](https://search.maven.org/artifact/io.github.project-openubl/xsender/) |
-| XSender Quarkus extension | [](https://search.maven.org/artifact/io.github.project-openubl/quarkus-xsender/) |
-| XSender Spring Boot extension | [](https://search.maven.org/artifact/io.github.project-openubl/spring-boot-xsender/) |
+**XHandler Java** es una suite de herramientas diseñada para facilitar la integración de **Facturación Electrónica en Perú (SUNAT)** en aplicaciones Java. Este repositorio es un "monorepo" que alberga las librerías `XBuilder` y `XSender`, proporcionando una solución integral para crear, firmar y enviar comprobantes de pago electrónicos.
+
+> [!TIP]
+> Si buscas integrar facturación electrónica de manera rápida y estándar, estás en el lugar correcto.
+
+---
+
+## 📦 Ecosistema
-# XBuilder
+El proyecto se divide en módulos principales y extensiones para frameworks populares:
-Librería Java para crear XMLs basados en UBL y los estándares de la SUNAT respecto a la facturación electrónica.
+| Componente | Descripción | Maven Central |
+|------------|-------------|---------------|
+| **XBuilder** | Creación y firma de XMLs (UBL 2.1) | [](https://search.maven.org/artifact/io.github.project-openubl/xbuilder/) |
+| **XSender** | Envío de comprobantes a SUNAT/OSE | [](https://search.maven.org/artifact/io.github.project-openubl/xsender/) |
+| **Quarkus XBuilder** | Extensión XBuilder para Quarkus | [](https://search.maven.org/artifact/io.github.project-openubl/quarkus-xbuilder/) |
+| **Quarkus XSender** | Extensión XSender para Quarkus | [](https://search.maven.org/artifact/io.github.project-openubl/quarkus-xsender/) |
+| **Spring Boot XSender** | Starter XSender para Spring Boot | [](https://search.maven.org/artifact/io.github.project-openubl/spring-boot-xsender/) |
-XBuilder esta diseñado para que puedas crear XMLs fácilmente.
+---
-- Crea XMLs sin que necesites conocer nada sobre manejo de archivos XMLs.
-- Hace cálculos internos por ti.
-- Requiere solamente datos mínimos.
+## 🛠️ XBuilder
-## ¿Qué puedes hacer con XBuilder?
+XBuilder abstrae la complejidad de los estándares UBL y XML, permitiéndote construir documentos tributarios válidos escribiendo código Java simple.
-- Crear XMLs
-- Firmar XMLs
+### Características
+- **Simple**: No necesitas manipular XML directamente ni conciliar namespaces complejos.
+- **Completo**: Soporte para Facturas, Boletas, Notas de Crédito/Débito, Guías de Remisión y Percepciones/Retenciones.
+- **Validado**: Realiza cálculos automáticos y validaciones básicas según normativa SUNAT.
-### Update snapshots
+### Ejemplo de Uso
-```shell
-mvn clean test -Dxbuilder.snapshot.update
+```java
+// Ejemplo simplificado de creación de factura
+Invoice invoice = Invoice.builder()
+ .serie("F001")
+ .numero(1)
+ .proveedor(proveedor)
+ .cliente(cliente)
+ .detalle(detalle)
+ .build();
+
+XMLInvoice xml = new InvoiceXMLBuilder().build(invoice);
```
-# XSender
+> [!NOTE]
+> Para actualizar los snapshots de prueba en desarrollo local, ejecuta:
+> `mvn clean test -Dxbuilder.snapshot.update`
+
+---
+
+## 🚀 XSender
+
+XSender se encarga de la comunicación con los servicios SOAP de la SUNAT o de los Operadores de Servicios Electrónicos (OSE).
+
+### Características
+- **Compatible**: Soporta los diversos endpoints de SUNAT (Beta/Producción) y OSEs.
+- **Resiliente**: Gestiona el envío de archivos ZIP y el procesamiento de respuestas (CDR, Tickets).
+- **Flexible**: Fácil integración con frameworks modernos como Quarkus y Spring Boot.
+
+---
+
+## 💻 Ejemplos
+
+Explora la carpeta `examples/` para ver implementaciones de referencia:
+
+- [**Spring Boot**](./examples/springbot): Ejemplo de integración completa usando Spring Boot.
+- [**Wildfly**](./examples/wildfly): Ejemplo para servidores de aplicaciones Jakarta EE.
+- [**Tomcat**](./examples/tomcat): Ejemplo ligero desplegable en Tomcat.
+- [**XBuilder/XSender**](./examples): Ejemplos "standalone" de uso de las librerías.
+
+---
+
+## 📚 Documentación
+
+Para guías detalladas, referencia de API y tutoriales, consulta nuestra documentación oficial.
-Libreria para realizar envíos de comprobantes electrónicos a los servicios web de la SUNAT y/o OSCE de acuerdo a lo
-especificado por la SUNAT.
+- 📖 **Sitio Web**: [project-openubl.github.io](https://project-openubl.github.io)
+- 💬 **Comunidad**: [Únete al chat en Zulip](https://projectopenubl.zulipchat.com/)
+- 🐛 **Soporte**: [Reportar un problema o discutir mejoras](https://github.com/project-openubl/xsender/discussions)
-# Getting started
+---
-- [Documentación](https://project-openubl.github.io)
-- [Discusiones](https://github.com/project-openubl/xsender/discussions)
+## 📄 Licencia
-## License
+Este proyecto se distribuye bajo la licencia **Apache 2.0**. Consulta el archivo [LICENSE](LICENSE) para más detalles.
-- [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0)
+Copyright © Project OpenUBL.
diff --git a/examples/pom.xml b/examples/pom.xml
index 9d62956b..397e7d79 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -6,7 +6,7 @@
io.github.project-openubl
xhandler-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
../pom.xml
diff --git a/examples/springbot/pom.xml b/examples/springbot/pom.xml
index 14d6115f..99797197 100644
--- a/examples/springbot/pom.xml
+++ b/examples/springbot/pom.xml
@@ -6,7 +6,7 @@
io.github.project-openubl
examples-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
../pom.xml
@@ -47,7 +47,7 @@
io.github.project-openubl
spring-boot-xsender
- 4.1.4
+ 6.0.0-SNAPSHOT
diff --git a/examples/springbot/src/main/java/io/github/project/openubl/quickstart/xbuilder/springboot/XBuilderController.java b/examples/springbot/src/main/java/io/github/project/openubl/quickstart/xbuilder/springboot/XBuilderController.java
index 626fdae0..87af376e 100644
--- a/examples/springbot/src/main/java/io/github/project/openubl/quickstart/xbuilder/springboot/XBuilderController.java
+++ b/examples/springbot/src/main/java/io/github/project/openubl/quickstart/xbuilder/springboot/XBuilderController.java
@@ -1,10 +1,13 @@
package io.github.project.openubl.quickstart.xbuilder.springboot;
-import io.github.project.openubl.xbuilder.content.catalogs.Catalog6;
+import io.github.project.openubl.xbuilder.content.catalogs.*;
import io.github.project.openubl.xbuilder.content.models.common.Cliente;
import io.github.project.openubl.xbuilder.content.models.common.Proveedor;
-import io.github.project.openubl.xbuilder.content.models.standard.general.DocumentoVentaDetalle;
-import io.github.project.openubl.xbuilder.content.models.standard.general.Invoice;
+import io.github.project.openubl.xbuilder.content.models.standard.general.*;
+import io.github.project.openubl.xbuilder.content.models.standard.guia.*;
+import io.github.project.openubl.xbuilder.content.models.sunat.baja.*;
+import io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.*;
+import io.github.project.openubl.xbuilder.content.models.sunat.resumen.*;
import io.github.project.openubl.xbuilder.enricher.ContentEnricher;
import io.github.project.openubl.xbuilder.enricher.config.DateProvider;
import io.github.project.openubl.xbuilder.enricher.config.Defaults;
@@ -13,7 +16,6 @@
import io.github.project.openubl.xbuilder.signature.CertificateDetailsFactory;
import io.github.project.openubl.xbuilder.signature.XMLSigner;
import io.github.project.openubl.xbuilder.signature.XmlSignatureHelper;
-import io.quarkus.qute.Template;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@@ -30,70 +32,366 @@
@RestController
public class XBuilderController {
- Defaults defaults = Defaults.builder()
- .icbTasa(new BigDecimal("0.2"))
- .igvTasa(new BigDecimal("0.18"))
- .build();
-
- DateProvider dateProvider = LocalDate::now;
-
- @RequestMapping(
- method = RequestMethod.POST,
- value = "/api/create-xml",
- produces = "text/plain"
- )
- public String createXML(@RequestBody String clientName) throws Exception {
- Invoice invoice = createInvoice(clientName);
-
- ContentEnricher enricher = new ContentEnricher(defaults, dateProvider);
- enricher.enrich(invoice);
-
- Template template = TemplateProducer.getInstance().getInvoice();
- String xml = template.data(invoice).render();
-
- // Sign XML
- InputStream ksInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("LLAMA-PE-CERTIFICADO-DEMO-12345678912.pfx");
- CertificateDetails certificate = CertificateDetailsFactory.create(ksInputStream, "password");
-
- X509Certificate x509Certificate = certificate.getX509Certificate();
- PrivateKey privateKey = certificate.getPrivateKey();
- Document signedXML = XMLSigner.signXML(xml, "Project OpenUBL", x509Certificate, privateKey);
-
- // Return
- byte[] bytesFromDocument = XmlSignatureHelper.getBytesFromDocument(signedXML);
- return new String(bytesFromDocument, StandardCharsets.ISO_8859_1);
- }
-
- private Invoice createInvoice(String clientName) {
- return Invoice.builder()
- .serie("F001")
- .numero(1)
- .proveedor(Proveedor.builder()
- .ruc("12345678912")
- .razonSocial("Softgreen S.A.C.")
- .build()
- )
- .cliente(Cliente.builder()
- .nombre(clientName)
- .numeroDocumentoIdentidad("12121212121")
- .tipoDocumentoIdentidad(Catalog6.RUC.toString())
- .build()
- )
- .detalle(DocumentoVentaDetalle.builder()
- .descripcion("Item1")
- .cantidad(new BigDecimal("10"))
- .precio(new BigDecimal("100"))
- .unidadMedida("KGM")
- .build()
- )
- .detalle(DocumentoVentaDetalle.builder()
- .descripcion("Item2")
- .cantidad(new BigDecimal("10"))
- .precio(new BigDecimal("100"))
- .unidadMedida("KGM")
- .build()
- )
- .build();
- }
+ Defaults defaults = Defaults.builder()
+ .icbTasa(new BigDecimal("0.2"))
+ .igvTasa(new BigDecimal("0.18"))
+ .build();
+
+ DateProvider dateProvider = LocalDate::now;
+
+ @RequestMapping(method = RequestMethod.POST, value = "/api/create-xml/invoice", produces = "text/plain")
+ public String createInvoiceXML(@RequestBody String clientName) throws Exception {
+ Invoice input = createInvoice(clientName);
+ ContentEnricher enricher = new ContentEnricher(defaults, dateProvider);
+ enricher.enrich(input);
+ String xml = TemplateProducer.getInstance().getInvoice().data(input).render();
+ return signAndRender(xml);
+ }
+
+ @RequestMapping(method = RequestMethod.POST, value = "/api/create-xml/credit-note", produces = "text/plain")
+ public String createCreditNoteXML(@RequestBody String clientName) throws Exception {
+ CreditNote input = createCreditNote(clientName);
+ ContentEnricher enricher = new ContentEnricher(defaults, dateProvider);
+ enricher.enrich(input);
+ String xml = TemplateProducer.getInstance().getCreditNote().data(input).render();
+ return signAndRender(xml);
+ }
+
+ @RequestMapping(method = RequestMethod.POST, value = "/api/create-xml/debit-note", produces = "text/plain")
+ public String createDebitNoteXML(@RequestBody String clientName) throws Exception {
+ DebitNote input = createDebitNote(clientName);
+ ContentEnricher enricher = new ContentEnricher(defaults, dateProvider);
+ enricher.enrich(input);
+ String xml = TemplateProducer.getInstance().getDebitNote().data(input).render();
+ return signAndRender(xml);
+ }
+
+ @RequestMapping(method = RequestMethod.POST, value = "/api/create-xml/voided-documents", produces = "text/plain")
+ public String createVoidedDocumentsXML(@RequestBody String clientName) throws Exception {
+ VoidedDocuments input = createVoidedDocuments(clientName);
+ ContentEnricher enricher = new ContentEnricher(defaults, dateProvider);
+ enricher.enrich(input);
+ String xml = TemplateProducer.getInstance().getVoidedDocument().data(input).render();
+ return signAndRender(xml);
+ }
+
+ @RequestMapping(method = RequestMethod.POST, value = "/api/create-xml/summary-documents", produces = "text/plain")
+ public String createSummaryDocumentsXML(@RequestBody String clientName) throws Exception {
+ SummaryDocuments input = createSummaryDocuments(clientName);
+ ContentEnricher enricher = new ContentEnricher(defaults, dateProvider);
+ enricher.enrich(input);
+ String xml = TemplateProducer.getInstance().getSummaryDocuments().data(input).render();
+ return signAndRender(xml);
+ }
+
+ @RequestMapping(method = RequestMethod.POST, value = "/api/create-xml/perception", produces = "text/plain")
+ public String createPerceptionXML(@RequestBody String clientName) throws Exception {
+ Perception input = createPerception(clientName);
+ ContentEnricher enricher = new ContentEnricher(defaults, dateProvider);
+ enricher.enrich(input);
+ String xml = TemplateProducer.getInstance().getPerception().data(input).render();
+ return signAndRender(xml);
+ }
+
+ @RequestMapping(method = RequestMethod.POST, value = "/api/create-xml/retention", produces = "text/plain")
+ public String createRetentionXML(@RequestBody String clientName) throws Exception {
+ Retention input = createRetention(clientName);
+ ContentEnricher enricher = new ContentEnricher(defaults, dateProvider);
+ enricher.enrich(input);
+ String xml = TemplateProducer.getInstance().getRetention().data(input).render();
+ return signAndRender(xml);
+ }
+
+ @RequestMapping(method = RequestMethod.POST, value = "/api/create-xml/despatch-advice", produces = "text/plain")
+ public String createDespatchAdviceXML(@RequestBody String clientName) throws Exception {
+ DespatchAdvice input = createDespatchAdvice(clientName);
+ ContentEnricher enricher = new ContentEnricher(defaults, dateProvider);
+ enricher.enrich(input);
+ String xml = TemplateProducer.getInstance().getDespatchAdvice().data(input).render();
+ return signAndRender(xml);
+ }
+
+ @RequestMapping(method = RequestMethod.POST, value = "/api/create-xml/reversion", produces = "text/plain")
+ public String createReversionXML(@RequestBody String clientName) throws Exception {
+ Reversion input = createReversion(clientName);
+ ContentEnricher enricher = new ContentEnricher(defaults, dateProvider);
+ enricher.enrich(input);
+ String xml = TemplateProducer.getInstance().getReversion().data(input).render();
+ return signAndRender(xml);
+ }
+
+ private String signAndRender(String xml) throws Exception {
+ // Sign XML
+ InputStream ksInputStream = Thread.currentThread().getContextClassLoader()
+ .getResourceAsStream("LLAMA-PE-CERTIFICADO-DEMO-12345678912.pfx");
+ CertificateDetails certificate = CertificateDetailsFactory.create(ksInputStream, "password");
+
+ X509Certificate x509Certificate = certificate.getX509Certificate();
+ PrivateKey privateKey = certificate.getPrivateKey();
+ Document signedXML = XMLSigner.signXML(xml, "Project OpenUBL", x509Certificate, privateKey);
+
+ // Return
+ byte[] bytesFromDocument = XmlSignatureHelper.getBytesFromDocument(signedXML);
+ return new String(bytesFromDocument, StandardCharsets.ISO_8859_1);
+ }
+
+ private Invoice createInvoice(String clientName) {
+ return Invoice.builder()
+ .serie("F001")
+ .numero(1)
+ .proveedor(Proveedor.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
+ .cliente(Cliente.builder()
+ .nombre(clientName)
+ .numeroDocumentoIdentidad("12121212121")
+ .tipoDocumentoIdentidad(Catalog6.RUC.toString())
+ .build())
+ .detalle(DocumentoVentaDetalle.builder()
+ .descripcion("Item1")
+ .cantidad(new BigDecimal("10"))
+ .precio(new BigDecimal("100"))
+ .unidadMedida("KGM")
+ .build())
+ .detalle(DocumentoVentaDetalle.builder()
+ .descripcion("Item2")
+ .cantidad(new BigDecimal("10"))
+ .precio(new BigDecimal("100"))
+ .unidadMedida("KGM")
+ .build())
+ .build();
+ }
+
+ private CreditNote createCreditNote(String clientName) {
+ return CreditNote.builder()
+ .serie("FC01")
+ .numero(1)
+ .comprobanteAfectadoSerieNumero("F001-1")
+ .sustentoDescripcion("mi sustento")
+ .proveedor(Proveedor.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
+ .cliente(Cliente.builder()
+ .nombre(clientName)
+ .numeroDocumentoIdentidad("12121212121")
+ .tipoDocumentoIdentidad(Catalog6.RUC.toString())
+ .build())
+ .detalle(DocumentoVentaDetalle.builder()
+ .descripcion("Item1")
+ .cantidad(new BigDecimal("10"))
+ .precio(new BigDecimal("100"))
+ .build())
+ .build();
+ }
+
+ private DebitNote createDebitNote(String clientName) {
+ return DebitNote.builder()
+ .serie("FD01")
+ .numero(1)
+ .comprobanteAfectadoSerieNumero("F001-1")
+ .sustentoDescripcion("mi sustento")
+ .proveedor(Proveedor.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
+ .cliente(Cliente.builder()
+ .nombre(clientName)
+ .numeroDocumentoIdentidad("12121212121")
+ .tipoDocumentoIdentidad(Catalog6.RUC.toString())
+ .build())
+ .detalle(DocumentoVentaDetalle.builder()
+ .descripcion("Item1")
+ .cantidad(new BigDecimal("10"))
+ .precio(new BigDecimal("100"))
+ .build())
+ .build();
+ }
+
+ private VoidedDocuments createVoidedDocuments(String clientName) {
+ return VoidedDocuments.builder()
+ .numero(1)
+ .fechaEmision(LocalDate.of(2022, 01, 31))
+ .fechaEmisionComprobantes(LocalDate.of(2022, 01, 29))
+ .proveedor(Proveedor.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
+ .comprobante(VoidedDocumentsItem.builder()
+ .serie("F001")
+ .numero(1)
+ .tipoComprobante(Catalog1_Invoice.FACTURA.getCode())
+ .descripcionSustento("Mi sustento1")
+ .build())
+ .comprobante(VoidedDocumentsItem.builder()
+ .serie("F001")
+ .numero(2)
+ .tipoComprobante(Catalog1_Invoice.FACTURA.getCode())
+ .descripcionSustento("Mi sustento2")
+ .build())
+ .build();
+ }
+
+ private SummaryDocuments createSummaryDocuments(String clientName) {
+ return SummaryDocuments.builder()
+ .numero(1)
+ .fechaEmisionComprobantes(dateProvider.now().minusDays(2))
+ .proveedor(Proveedor.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
+ .comprobante(SummaryDocumentsItem.builder()
+ .tipoOperacion(Catalog19.ADICIONAR.toString())
+ .comprobante(Comprobante.builder()
+ .tipoComprobante(Catalog1_Invoice.BOLETA.getCode())//
+ .serieNumero("B001-1")
+ .cliente(Cliente.builder()
+ .nombre(clientName)
+ .numeroDocumentoIdentidad("12345678")
+ .tipoDocumentoIdentidad(
+ Catalog6.DNI.getCode())
+ .build())
+ .impuestos(ComprobanteImpuestos.builder()
+ .igv(new BigDecimal("18"))
+ .icb(new BigDecimal(2))
+ .build())
+ .valorVenta(ComprobanteValorVenta.builder()
+ .importeTotal(new BigDecimal("120"))
+ .gravado(new BigDecimal("120"))
+ .build())
+ .build())
+ .build())
+ .build();
+ }
+
+ private Perception createPerception(String clientName) {
+ return Perception.builder()
+ .serie("P001")
+ .numero(1)
+ .fechaEmision(LocalDate.of(2022, 01, 31))
+ .proveedor(Proveedor.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
+ .cliente(Cliente.builder()
+ .nombre(clientName)
+ .numeroDocumentoIdentidad("12121212121")
+ .tipoDocumentoIdentidad(Catalog6.RUC.getCode())
+ .build())
+ .importeTotalPercibido(new BigDecimal("10"))
+ .importeTotalCobrado(new BigDecimal("210"))
+ .tipoRegimen(Catalog22.VENTA_INTERNA.getCode())
+ .tipoRegimenPorcentaje(Catalog22.VENTA_INTERNA.getPercent()) //
+ .operacion(PercepcionRetencionOperacion.builder()
+ .numeroOperacion(1)
+ .fechaOperacion(LocalDate.of(2022, 01, 31))
+ .importeOperacion(new BigDecimal("100"))
+ .comprobante(io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.ComprobanteAfectado
+ .builder()
+ .tipoComprobante(Catalog1.FACTURA.getCode())
+ .serieNumero("F001-1")
+ .fechaEmision(LocalDate.of(2022, 01, 31))
+ .importeTotal(new BigDecimal("200"))
+ .moneda("PEN")
+ .build())
+ .build())
+ .build();
+ }
+
+ private Retention createRetention(String clientName) {
+ return Retention.builder()
+ .serie("R001")
+ .numero(1)
+ .fechaEmision(LocalDate.of(2022, 01, 31))
+ .proveedor(Proveedor.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
+ .cliente(Cliente.builder()
+ .nombre(clientName)
+ .numeroDocumentoIdentidad("12121212121")
+ .tipoDocumentoIdentidad(Catalog6.RUC.getCode())
+ .build())
+ .importeTotalRetenido(new BigDecimal("10"))
+ .importeTotalPagado(new BigDecimal("200"))
+ .tipoRegimen(Catalog23.TASA_TRES.getCode())
+ .tipoRegimenPorcentaje(Catalog23.TASA_TRES.getPercent()) //
+ .operacion(PercepcionRetencionOperacion.builder()
+ .numeroOperacion(1)
+ .fechaOperacion(LocalDate.of(2022, 01, 31))
+ .importeOperacion(new BigDecimal("100"))
+ .comprobante(io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.ComprobanteAfectado
+ .builder()
+ .tipoComprobante(Catalog1.FACTURA.getCode())
+ .serieNumero("F001-1")
+ .fechaEmision(LocalDate.of(2022, 01, 31))
+ .importeTotal(new BigDecimal("210"))
+ .moneda("PEN")
+ .build())
+ .build())
+ .build();
+ }
+
+ private DespatchAdvice createDespatchAdvice(String clientName) {
+ return DespatchAdvice.builder()
+ .serie("T001")
+ .numero(1)
+ .tipoComprobante(Catalog1.GUIA_REMISION_REMITENTE.getCode())
+ .remitente(Remitente.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
+ .destinatario(Destinatario.builder()
+ .tipoDocumentoIdentidad(Catalog6.DNI.getCode())
+ .numeroDocumentoIdentidad("12345678")
+ .nombre(clientName)
+ .build())
+ .envio(Envio.builder()
+ .tipoTraslado(Catalog20.TRASLADO_EMISOR_ITINERANTE_CP.getCode())
+ .pesoTotal(BigDecimal.ONE)
+ .pesoTotalUnidadMedida("KG")
+ .tipoModalidadTraslado(Catalog18.TRANSPORTE_PRIVADO.getCode())
+ .fechaTraslado(dateProvider.now())
+ .partida(Partida.builder()
+ .direccion("DireccionOrigen")
+ .ubigeo("010101")
+ .build())
+ .destino(Destino.builder()
+ .direccion("DireccionDestino")
+ .ubigeo("020202")
+ .build())
+ .build())
+ .detalle(DespatchAdviceItem.builder()
+ .cantidad(new BigDecimal("0.5"))
+ .unidadMedida("KG")
+ .codigo("123456")
+ .build())
+ .build();
+ }
+
+ private Reversion createReversion(String clientName) {
+ return Reversion.builder()
+ .numero(1)
+ .fechaEmision(LocalDate.now())
+ .fechaEmisionComprobantes(LocalDate.now().minusDays(1))
+ .proveedor(Proveedor.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
+ .comprobante(VoidedDocumentsItem.builder()
+ .serie("P001")
+ .numero(1)
+ .tipoComprobante(Catalog1.PERCEPCION.getCode())
+ .descripcionSustento("Anulacion de percepcion por error en emision")
+ .build())
+ .comprobante(VoidedDocumentsItem.builder()
+ .serie("R001")
+ .numero(1)
+ .tipoComprobante(Catalog1.RETENCION.getCode())
+ .descripcionSustento("Anulacion de retencion por duplicado")
+ .build())
+ .build();
+ }
}
diff --git a/examples/tomcat/pom.xml b/examples/tomcat/pom.xml
index 70835dd4..c0141dce 100644
--- a/examples/tomcat/pom.xml
+++ b/examples/tomcat/pom.xml
@@ -6,7 +6,7 @@
io.github.project-openubl
examples-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
../pom.xml
diff --git a/examples/wildfly/pom.xml b/examples/wildfly/pom.xml
index 78111db5..67ca03bd 100644
--- a/examples/wildfly/pom.xml
+++ b/examples/wildfly/pom.xml
@@ -7,7 +7,7 @@
io.github.project-openubl
examples-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
../pom.xml
diff --git a/examples/xbuilder/pom.xml b/examples/xbuilder/pom.xml
index a0a32a4b..5cae1e85 100644
--- a/examples/xbuilder/pom.xml
+++ b/examples/xbuilder/pom.xml
@@ -6,7 +6,7 @@
io.github.project-openubl
examples-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
../pom.xml
diff --git a/examples/xsender/pom.xml b/examples/xsender/pom.xml
index e67936a8..cf78146c 100644
--- a/examples/xsender/pom.xml
+++ b/examples/xsender/pom.xml
@@ -6,7 +6,7 @@
io.github.project-openubl
examples-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
../pom.xml
diff --git a/pom.xml b/pom.xml
index 57b9e058..a12d9ae7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
io.github.project-openubl
xhandler-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
XHandler - Parent
Java library for Creating, Sending XML files to SUNAT
diff --git a/xbuilder/core/pom.xml b/xbuilder/core/pom.xml
index 63645eef..02a4d321 100644
--- a/xbuilder/core/pom.xml
+++ b/xbuilder/core/pom.xml
@@ -6,7 +6,7 @@
io.github.project-openubl
xbuilder-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
../pom.xml
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/mappers/DespatchAdviceMapper.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/mappers/DespatchAdviceMapper.java
index 05f18fcf..d9c2d070 100644
--- a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/mappers/DespatchAdviceMapper.java
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/mappers/DespatchAdviceMapper.java
@@ -1,6 +1,7 @@
package io.github.project.openubl.xbuilder.content.jaxb.mappers;
import io.github.project.openubl.xbuilder.content.jaxb.mappers.common.FirmanteMapper;
+import java.util.List;
import io.github.project.openubl.xbuilder.content.jaxb.mappers.common.Numero2Translator;
import io.github.project.openubl.xbuilder.content.jaxb.mappers.common.SerieNumeroMapper;
import io.github.project.openubl.xbuilder.content.jaxb.mappers.common.SerieNumeroTranslator;
@@ -10,14 +11,21 @@
import io.github.project.openubl.xbuilder.content.models.common.Proveedor;
import io.github.project.openubl.xbuilder.content.models.standard.guia.DespatchAdvice;
import io.github.project.openubl.xbuilder.content.models.standard.guia.DespatchAdviceItem;
+import io.github.project.openubl.xbuilder.content.models.standard.guia.Comprador;
+import io.github.project.openubl.xbuilder.content.models.standard.guia.Tercero;
import io.github.project.openubl.xbuilder.content.models.standard.guia.Destinatario;
import io.github.project.openubl.xbuilder.content.models.standard.guia.Destino;
import io.github.project.openubl.xbuilder.content.models.standard.guia.DocumentoBaja;
import io.github.project.openubl.xbuilder.content.models.standard.guia.DocumentoRelacionado;
+import io.github.project.openubl.xbuilder.content.models.standard.guia.DocumentoAdicional;
import io.github.project.openubl.xbuilder.content.models.standard.guia.Envio;
import io.github.project.openubl.xbuilder.content.models.standard.guia.Partida;
import io.github.project.openubl.xbuilder.content.models.standard.guia.Remitente;
import io.github.project.openubl.xbuilder.content.models.standard.guia.Transportista;
+import io.github.project.openubl.xbuilder.content.models.standard.guia.Driver;
+import io.github.project.openubl.xbuilder.content.models.standard.guia.GuiaItemAttribute;
+import io.github.project.openubl.xbuilder.content.models.standard.guia.Puerto;
+import io.github.project.openubl.xbuilder.content.models.standard.guia.Vehicle;
import org.mapstruct.Condition;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
@@ -26,23 +34,31 @@
@Mapper(uses = {
SerieNumeroMapper.class,
FirmanteMapper.class
-})
+}, nullValuePropertyMappingStrategy = org.mapstruct.NullValuePropertyMappingStrategy.SET_TO_DEFAULT)
public interface DespatchAdviceMapper {
- @Mapping(target = "serie", source = "documentId", qualifiedBy = {SerieNumeroTranslator.class, SerieTranslator.class})
- @Mapping(target = "numero", source = "documentId", qualifiedBy = {SerieNumeroTranslator.class, Numero2Translator.class})
+ @Mapping(target = "serie", source = "documentId", qualifiedBy = { SerieNumeroTranslator.class,
+ SerieTranslator.class })
+ @Mapping(target = "numero", source = "documentId", qualifiedBy = { SerieNumeroTranslator.class,
+ Numero2Translator.class })
+ @Mapping(target = "version", source = "customizationId")
@Mapping(target = "fechaEmision", source = "issueDate")
@Mapping(target = "horaEmision", source = "issueTime")
@Mapping(target = "tipoComprobante", source = "despatchAdviceTypeCode")
@Mapping(target = "observaciones", source = "note")
@Mapping(target = "documentoBaja", source = "orderReference")
- @Mapping(target = "documentoRelacionado", source = "additionalDocumentReference")
+ @Mapping(target = "documentoRelacionado", ignore = true)
@Mapping(target = "firmante", source = "signature")
@Mapping(target = "remitente", source = "despatchSupplierParty")
@Mapping(target = "destinatario", source = "deliveryCustomerParty")
- @Mapping(target = "proveedor", source = "sellerSupplierParty")
+ @Mapping(target = "proveedor", source = "sellerSupplierParty", qualifiedByName = "mapDespatchAdviceProveedor")
+ @Mapping(target = "tercero", source = "sellerSupplierParty", qualifiedByName = "mapDespatchAdviceTercero")
@Mapping(target = "envio", source = "shipment")
@Mapping(target = "detalles", source = "lines")
+ @Mapping(target = "documentosAdicionales", source = "additionalDocumentReferences", qualifiedByName = "mapDocumentosAdicionales")
+ @Mapping(target = "comprador", source = "buyerCustomerParty")
+ @Mapping(target = "documentoAdicional", ignore = true)
+ @Mapping(target = "detalle", ignore = true)
DespatchAdvice map(XMLDespatchAdvice xml);
@Mapping(target = "tipoDocumento", source = "orderTypeCode")
@@ -55,58 +71,275 @@ public interface DespatchAdviceMapper {
@Mapping(target = "ruc", source = "party.partyIdentification.id.value")
@Mapping(target = "razonSocial", source = "party.partyLegalEntity.registrationName")
+ @Mapping(target = "numeroRegistroMTC", source = "party.partyLegalEntity.companyID")
Remitente mapRemitente(XMLDespatchAdvice.DespatchSupplierParty xml);
+ @Mapping(target = "tipo", source = "jobTitle")
+ @Mapping(target = "tipoDocumentoIdentidad", source = "id.schemeID")
+ @Mapping(target = "numeroDocumentoIdentidad", source = "id.value")
+ @Mapping(target = "nombres", source = "firstName")
+ @Mapping(target = "apellidos", source = "familyName")
+ @Mapping(target = "licencia", source = "identityDocumentReference.id")
+ Driver mapDriver(XMLDespatchAdvice.DriverPerson xml);
+
@Mapping(target = "numeroDocumentoIdentidad", source = "party.partyIdentification.id.value")
@Mapping(target = "tipoDocumentoIdentidad", source = "party.partyIdentification.id.schemeID")
@Mapping(target = "nombre", source = "party.partyLegalEntity.registrationName")
Destinatario mapDestinatario(XMLDespatchAdvice.DeliveryCustomerParty xml);
- @Mapping(target = "ruc", source = "customerAssignedAccountId")
- @Mapping(target = "nombreComercial", source = "party.partyLegalEntity.registrationName")
- Proveedor mapProveedor(XMLDespatchAdvice.SellerSupplierParty xml);
+ @Named("mapDespatchAdviceProveedor")
+ default Proveedor mapDespatchAdviceProveedor(XMLDespatchAdvice.SellerSupplierParty xml) {
+ if (xml == null || xml.getCustomerAssignedAccountId() == null) {
+ return null;
+ }
+ Proveedor.ProveedorBuilder builder = Proveedor.builder();
+ builder.ruc(xml.getCustomerAssignedAccountId());
+ if (xml.getParty() != null && xml.getParty().getPartyLegalEntity() != null) {
+ builder.razonSocial(xml.getParty().getPartyLegalEntity().getRegistrationName());
+ builder.nombreComercial(xml.getParty().getPartyLegalEntity().getRegistrationName());
+ }
+ return builder.build();
+ }
+
+ @Named("mapDespatchAdviceTercero")
+ default Tercero mapDespatchAdviceTercero(XMLDespatchAdvice.SellerSupplierParty xml) {
+ if (xml == null || xml.getParty() == null || xml.getParty().getPartyIdentification() == null) {
+ return null;
+ }
+ Tercero.TerceroBuilder builder = Tercero.builder();
+ if (xml.getParty().getPartyIdentification().getId() != null) {
+ builder.numeroDocumentoIdentidad(xml.getParty().getPartyIdentification().getId().getValue());
+ builder.tipoDocumentoIdentidad(xml.getParty().getPartyIdentification().getId().getSchemeID());
+ }
+ if (xml.getParty().getPartyLegalEntity() != null) {
+ builder.nombre(xml.getParty().getPartyLegalEntity().getRegistrationName());
+ }
+ return builder.build();
+ }
+
+ @Mapping(target = "tipoDocumentoIdentidad", source = "party.partyIdentification.id.schemeID")
+ @Mapping(target = "numeroDocumentoIdentidad", source = "party.partyIdentification.id.value")
+ @Mapping(target = "nombre", source = "party.partyLegalEntity.registrationName")
+ Comprador mapComprador(XMLDespatchAdvice.BuyerCustomerParty xml);
@Mapping(target = "tipoTraslado", source = "handlingCode")
- @Mapping(target = "motivoTraslado", source = "information")
+ @Mapping(target = "motivoTraslado", source = "handlingInstructions")
@Mapping(target = "pesoTotal", source = "grossWeightMeasure.value")
@Mapping(target = "pesoTotalUnidadMedida", source = "grossWeightMeasure.unitCode")
@Mapping(target = "numeroDeBultos", source = "totalTransportHandlingUnitQuantity")
- @Mapping(target = "transbordoProgramado", source = "splitConsignmentIndicator")
@Mapping(target = "tipoModalidadTraslado", source = "shipmentStage.transportModeCode")
@Mapping(target = "fechaTraslado", source = "shipmentStage.transitPeriod.startDate")
- @Mapping(target = "numeroDeContenedor", source = "transportHandlingUnit.transportEquipment.id")
- @Mapping(target = "codigoDePuerto", source = "firstArrivalPortLocation.id")
@Mapping(target = "transportista", source = "shipmentStage", conditionQualifiedByName = "transportistaRequirements")
@Mapping(target = "destino", source = "delivery")
- @Mapping(target = "partida", source = "originAddress")
+ @Mapping(target = "partida", source = ".", qualifiedByName = "mapPartidaFromShipment")
+ @Mapping(target = "choferes", source = "shipmentStage.driverPersons", qualifiedByName = "mapChoferes")
+ @Mapping(target = "indicadores", source = "specialInstructions", qualifiedByName = "mapIndicadores")
+ @Mapping(target = "contenedores", source = "transportHandlingUnit", qualifiedByName = "mapContenedores")
+ @Mapping(target = "pesoItems", source = "netWeightMeasure.value")
+ @Mapping(target = "sustentoPeso", source = "information")
+ @Mapping(target = "puerto", source = "firstArrivalPortLocation", qualifiedByName = "mapPuerto")
+ @Mapping(target = "aeropuerto", source = "firstArrivalPortLocation", qualifiedByName = "mapAeropuerto")
+ @Mapping(target = "vehiculo", source = "transportHandlingUnit", qualifiedByName = "mapVehiculo")
+ @Mapping(target = "chofer", ignore = true)
+ @Mapping(target = "indicador", ignore = true)
+ @Mapping(target = "contenedor", ignore = true)
Envio mapEnvio(XMLDespatchAdvice.Shipment xml);
@Condition
@Named("transportistaRequirements")
default boolean conditionTransportista(XMLDespatchAdvice.ShipmentStage xml) {
- return xml.getCarrierParty() != null && xml.getTransportMeans() != null && xml.getDriverPerson() != null;
+ return xml.getCarrierParty() != null && xml.getTransportMeans() != null && xml.getDriverPersons() != null
+ && !xml.getDriverPersons().isEmpty();
}
- @Mapping(target = "tipoDocumentoIdentidad", source = "carrierParty.partyIdentification.id.value")
- @Mapping(target = "numeroDocumentoIdentidad", source = "carrierParty.partyIdentification.id.schemeID")
- @Mapping(target = "nombre", source = "carrierParty.partyName.name")
- @Mapping(target = "placaDelVehiculo", source = "transportMeans.roadTransport.licensePlateID")
- @Mapping(target = "choferTipoDocumentoIdentidad", source = "driverPerson.id.schemeID")
- @Mapping(target = "choferNumeroDocumentoIdentidad", source = "driverPerson.id.value")
+ @Mapping(target = "tipoDocumentoIdentidad", source = "carrierParty.partyIdentification.id.schemeID")
+ @Mapping(target = "numeroDocumentoIdentidad", source = "carrierParty.partyIdentification.id.value")
+ @Mapping(target = "nombre", source = "carrierParty.partyLegalEntity.registrationName")
+ @Mapping(target = "numeroRegistroMTC", source = "carrierParty.partyLegalEntity.companyID")
Transportista mapTransportista(XMLDespatchAdvice.ShipmentStage xml);
@Mapping(target = "ubigeo", source = "deliveryAddress.id")
@Mapping(target = "direccion", source = "deliveryAddress.addressLine.line")
+ @Mapping(target = "codigoLocal", source = "deliveryAddress.addressTypeCode.value")
+ @Mapping(target = "ruc", source = "deliveryAddress.addressTypeCode.listID")
Destino mapDelivery(XMLDespatchAdvice.Delivery xml);
@Mapping(target = "ubigeo", source = "id")
@Mapping(target = "direccion", source = "streetName")
+ @Mapping(target = "codigoLocal", ignore = true)
+ @Mapping(target = "ruc", ignore = true)
Partida mapPartida(XMLDespatchAdvice.OriginAddress xml);
@Mapping(target = "unidadMedida", source = "deliveredQuantity.unitCode")
@Mapping(target = "cantidad", source = "deliveredQuantity.value")
- @Mapping(target = "descripcion", source = "item.name")
+ @Mapping(target = "descripcion", source = "item", qualifiedByName = "mapItemDescription")
@Mapping(target = "codigo", source = "item.sellersItemIdentification.id")
@Mapping(target = "codigoSunat", source = "item.commodityClassification.itemClassificationCode")
+ @Mapping(target = "atributos", source = "item.additionalItemProperties", qualifiedByName = "mapAtributos")
+ @Mapping(target = "atributo", ignore = true)
DespatchAdviceItem mapLine(XMLDespatchAdviceLine xml);
+
+ @Mapping(target = "code", source = "nameCode")
+ GuiaItemAttribute mapAttribute(XMLDespatchAdviceLine.AdditionalItemProperty xml);
+
+ @Named("mapItemDescription")
+ default String mapItemDescription(XMLDespatchAdviceLine.Item item) {
+ if (item == null) {
+ return null;
+ }
+ // Prefer description (new format) over name (old format)
+ return item.getDescription() != null ? item.getDescription() : item.getName();
+ }
+
+ @Named("mapPartidaFromShipment")
+ default Partida mapPartidaFromShipment(XMLDespatchAdvice.Shipment shipment) {
+ if (shipment == null) {
+ return null;
+ }
+
+ // Try new format first: delivery.despatch.despatchAddress
+ if (shipment.getDelivery() != null &&
+ shipment.getDelivery().getDespatch() != null &&
+ shipment.getDelivery().getDespatch().getDespatchAddress() != null) {
+ XMLDespatchAdvice.DespatchAddress addr = shipment.getDelivery().getDespatch().getDespatchAddress();
+ return Partida.builder()
+ .ubigeo(addr.getId())
+ .direccion(addr.getAddressLine() != null ? addr.getAddressLine().getLine() : null)
+ .codigoLocal(addr.getAddressTypeCode() != null ? addr.getAddressTypeCode().getValue() : null)
+ .ruc(addr.getAddressTypeCode() != null ? addr.getAddressTypeCode().getListID() : null)
+ .build();
+ }
+
+ return null;
+ }
+
+ @Named("mapPrimaryDriverTipo")
+ default String mapPrimaryDriverTipo(List drivers) {
+ if (drivers == null || drivers.isEmpty())
+ return null;
+ return drivers.get(0).getId() != null ? drivers.get(0).getId().getSchemeID() : null;
+ }
+
+ @Named("mapPrimaryDriverNum")
+ default String mapPrimaryDriverNum(List drivers) {
+ if (drivers == null || drivers.isEmpty())
+ return null;
+ return drivers.get(0).getId() != null ? drivers.get(0).getId().getValue() : null;
+ }
+
+ @Named("mapContenedores")
+ default List mapContenedores(List units) {
+ if (units == null)
+ return java.util.Collections.emptyList();
+ List result = new java.util.ArrayList<>();
+ for (XMLDespatchAdvice.TransportHandlingUnit unit : units) {
+ if (unit.getPackages() != null) {
+ unit.getPackages().stream().map(XMLDespatchAdvice.Package::getTraceID)
+ .filter(java.util.Objects::nonNull)
+ .forEach(result::add);
+ }
+ if (unit.getTransportEquipments() != null) {
+ // Only add as container if it's NOT a vehicle (simple ID, no transport means)
+ unit.getTransportEquipments().stream()
+ .filter(e -> e.getApplicableTransportMeans() == null)
+ .map(XMLDespatchAdvice.TransportEquipment::getId)
+ .filter(java.util.Objects::nonNull)
+ .forEach(result::add);
+ }
+ }
+ return result;
+ }
+
+ @Named("mapChoferes")
+ default List mapChoferes(List drivers) {
+ if (drivers == null)
+ return java.util.Collections.emptyList();
+ return drivers.stream().map(this::mapDriver).collect(java.util.stream.Collectors.toList());
+ }
+
+ @Named("mapIndicadores")
+ default List mapIndicadores(List indicators) {
+ if (indicators == null)
+ return java.util.Collections.emptyList();
+ return indicators;
+ }
+
+ @Named("mapAtributos")
+ default List mapAtributos(List attrs) {
+ if (attrs == null)
+ return java.util.Collections.emptyList();
+ return attrs.stream().map(this::mapAttribute).collect(java.util.stream.Collectors.toList());
+ }
+
+ @Named("mapDocumentosAdicionales")
+ default List mapDocumentosAdicionales(
+ List rels) {
+ if (rels == null)
+ return java.util.Collections.emptyList();
+ return rels.stream().map(this::mapDocumentoAdicional).collect(java.util.stream.Collectors.toList());
+ }
+
+ @Named("mapPuerto")
+ default Puerto mapPuerto(XMLDespatchAdvice.FirstArrivalPortLocation xml) {
+ if (xml == null || !"1".equals(xml.getLocationTypeCode()))
+ return null;
+ return Puerto.builder().codigo(xml.getId()).nombre(xml.getName()).build();
+ }
+
+ @Named("mapAeropuerto")
+ default Puerto mapAeropuerto(XMLDespatchAdvice.FirstArrivalPortLocation xml) {
+ if (xml == null || !"2".equals(xml.getLocationTypeCode()))
+ return null;
+ return Puerto.builder().codigo(xml.getId()).nombre(xml.getName()).build();
+ }
+
+ @Named("mapVehiculo")
+ default Vehicle mapVehiculo(List units) {
+ if (units == null)
+ return null;
+ // The first equipment with transport means or multiple are usually vehicles
+ return units.stream()
+ .filter(u -> u.getTransportEquipments() != null)
+ .flatMap(u -> u.getTransportEquipments().stream())
+ .filter(e -> e.getApplicableTransportMeans() != null || e.getAttachedTransportEquipments() != null)
+ .findFirst()
+ .map(this::mapDetailedVehicle)
+ .orElse(null);
+ }
+
+ default Vehicle mapDetailedVehicle(XMLDespatchAdvice.TransportEquipment xml) {
+ if (xml == null)
+ return null;
+ Vehicle.VehicleBuilder builder = Vehicle.builder().placa(xml.getId());
+ if (xml.getApplicableTransportMeans() != null) {
+ builder.numeroCirculacion(xml.getApplicableTransportMeans().getRegistrationNationalityID());
+ }
+ if (xml.getShipmentDocumentReferences() != null && !xml.getShipmentDocumentReferences().isEmpty()) {
+ XMLDespatchAdvice.ShipmentDocumentReference doc = xml.getShipmentDocumentReferences().get(0);
+ if (doc.getId() != null) {
+ builder.numeroAutorizacion(doc.getId().getValue());
+ builder.codigoEmisor(doc.getId().getSchemeID());
+ }
+ }
+ if (xml.getAttachedTransportEquipments() != null) {
+ builder.secundarios(xml.getAttachedTransportEquipments().stream()
+ .map(this::mapDetailedVehicle)
+ .collect(java.util.stream.Collectors.toList()));
+ }
+ return builder.build();
+ }
+
+ @Mapping(target = "tipoDocumento", source = "documentTypeCode")
+ @Mapping(target = "tipoDocumentoDescripcion", source = "documentType")
+ @Mapping(target = "rucEmisor", source = "issuerParty.partyIdentification.id.value")
+ @Mapping(target = "numero", source = "id")
+ DocumentoAdicional mapDocumentoAdicional(XMLDespatchAdvice.AdditionalDocumentReference xml);
+
+ @Named("mapPrimaryAdditionalDocument")
+ default DocumentoRelacionado mapPrimaryAdditionalDocument(
+ List rels) {
+ if (rels == null || rels.isEmpty())
+ return null;
+ return mapDocumentoRelacionado(rels.get(0));
+ }
}
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/mappers/SummaryDocumentsMapper.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/mappers/SummaryDocumentsMapper.java
index 6ade9936..9ecbd9de 100644
--- a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/mappers/SummaryDocumentsMapper.java
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/mappers/SummaryDocumentsMapper.java
@@ -25,90 +25,95 @@
import java.util.stream.Collectors;
@Mapper(uses = {
- SerieNumeroMapper.class,
- FirmanteMapper.class,
- ProveedorMapper.class
+ SerieNumeroMapper.class,
+ FirmanteMapper.class,
+ ProveedorMapper.class
})
public interface SummaryDocumentsMapper {
- @Mapping(target = "fechaEmision", source = "issueDate")
- @Mapping(target = "firmante", source = "signature")
- @Mapping(target = "proveedor", source = "accountingSupplierParty")
+ @Mapping(target = "fechaEmision", source = "issueDate")
+ @Mapping(target = "firmante", source = "signature")
+ @Mapping(target = "proveedor", source = "accountingSupplierParty")
- @Mapping(target = "numero", source = "documentId", qualifiedBy = {SerieNumeroTranslator.class, Numero3Translator.class})
- @Mapping(target = "fechaEmisionComprobantes", source = "referenceDate")
- @Mapping(target = "comprobantes", source = "lines")
- SummaryDocuments map(XMLSummaryDocuments xml);
+ @Mapping(target = "numero", source = "documentId", qualifiedBy = { SerieNumeroTranslator.class,
+ Numero3Translator.class })
+ @Mapping(target = "fechaEmisionComprobantes", source = "referenceDate")
+ @Mapping(target = "comprobantes", source = "lines")
+ SummaryDocuments map(XMLSummaryDocuments xml);
- @Mapping(target = "tipoOperacion", source = "status.conditionCode")
- @Mapping(target = "comprobante", source = ".")
- SummaryDocumentsItem mapLines(XMLSummaryDocumentsLine xml);
+ @Mapping(target = "tipoOperacion", source = "status.conditionCode")
+ @Mapping(target = "comprobante", source = ".")
+ SummaryDocumentsItem mapLines(XMLSummaryDocumentsLine xml);
- @Mapping(target = "moneda", source = "totalAmount.currencyID")
- @Mapping(target = "tipoComprobante", source = "documentTypeCode")
- @Mapping(target = "serieNumero", source = "documentId")
- @Mapping(target = "cliente", source = "accountingCustomerParty")
- @Mapping(target = "comprobanteAfectado.serieNumero", source = "billingReference.invoiceDocumentReference.id")
- @Mapping(target = "comprobanteAfectado.tipoComprobante", source = "billingReference.invoiceDocumentReference.documentTypeCode")
- @Mapping(target = "valorVenta", source = ".")
- @Mapping(target = "impuestos", source = ".")
- Comprobante mapLineComprobante(XMLSummaryDocumentsLine xml);
+ @Mapping(target = "moneda", source = "totalAmount.currencyID")
+ @Mapping(target = "tipoComprobante", source = "documentTypeCode")
+ @Mapping(target = "serieNumero", source = "documentId")
+ @Mapping(target = "cliente", source = "accountingCustomerParty")
+ @Mapping(target = "comprobanteAfectado.serieNumero", source = "billingReference.invoiceDocumentReference.id")
+ @Mapping(target = "comprobanteAfectado.tipoComprobante", source = "billingReference.invoiceDocumentReference.documentTypeCode")
+ @Mapping(target = "valorVenta", source = ".")
+ @Mapping(target = "impuestos", source = ".")
+ Comprobante mapLineComprobante(XMLSummaryDocumentsLine xml);
- @Mapping(target = "numeroDocumentoIdentidad", source = "customerAssignedAccountID")
- @Mapping(target = "tipoDocumentoIdentidad", source = "additionalAccountID")
- Cliente mapCliente(XMLSummaryDocumentsLine.AccountingCustomerParty xml);
+ @Mapping(target = "numeroDocumentoIdentidad", source = "customerAssignedAccountID")
+ @Mapping(target = "tipoDocumentoIdentidad", source = "additionalAccountID")
+ Cliente mapCliente(XMLSummaryDocumentsLine.AccountingCustomerParty xml);
- default ComprobanteValorVenta mapLineComprobanteValorVenta(XMLSummaryDocumentsLine xml) {
- if (xml == null) {
- return null;
- }
-
- Map billingPayments = Optional.ofNullable(xml.getBillingPayments())
- .orElse(Collections.emptyList())
- .stream()
- .collect(Collectors.toMap(
- XMLSummaryDocumentsLine.BillingPayment::getInstructionId,
- XMLSummaryDocumentsLine.BillingPayment::getPaidAmount
- ));
+ default ComprobanteValorVenta mapLineComprobanteValorVenta(XMLSummaryDocumentsLine xml) {
+ if (xml == null) {
+ return null;
+ }
- BigDecimal importeTotal = Optional.ofNullable(xml.getTotalAmount())
- .map(XMLSummaryDocumentsLine.TotalAmount::getValue)
- .orElse(null);
- BigDecimal otrosCargos = Optional.ofNullable(xml.getAllowanceCharge())
- .map(XMLSummaryDocumentsLine.AllowanceCharge::getValue)
- .orElse(null);
+ Map billingPayments = Optional.ofNullable(xml.getBillingPayments())
+ .orElse(Collections.emptyList())
+ .stream()
+ .collect(Collectors.toMap(
+ XMLSummaryDocumentsLine.BillingPayment::getInstructionId,
+ XMLSummaryDocumentsLine.BillingPayment::getPaidAmount));
- return ComprobanteValorVenta.builder()
- .importeTotal(importeTotal)
- .gravado(billingPayments.get("01"))
- .exonerado(billingPayments.get("02"))
- .inafecto(billingPayments.get("03"))
- .gratuito(billingPayments.get("05"))
- .otrosCargos(otrosCargos)
- .build();
- }
+ BigDecimal importeTotal = Optional.ofNullable(xml.getTotalAmount())
+ .map(XMLSummaryDocumentsLine.TotalAmount::getValue)
+ .orElse(null);
+ BigDecimal otrosCargos = Optional.ofNullable(xml.getAllowanceCharge())
+ .map(XMLSummaryDocumentsLine.AllowanceCharge::getValue)
+ .orElse(null);
- default ComprobanteImpuestos mapLineComprobanteImpuestos(XMLSummaryDocumentsLine xml) {
- if (xml == null) {
- return null;
+ return ComprobanteValorVenta.builder()
+ .importeTotal(importeTotal)
+ .gravado(billingPayments.get("01"))
+ .exonerado(billingPayments.get("02"))
+ .inafecto(billingPayments.get("03"))
+ .gratuito(billingPayments.get("05"))
+ .otrosCargos(otrosCargos)
+ .build();
}
- Map taxTotals = Optional.ofNullable(xml.getTaxTotals())
- .orElse(Collections.emptyList())
- .stream()
- .collect(Collectors.toMap(
- taxTotal -> Optional.ofNullable(taxTotal.getTaxSubtotals())
- .flatMap(f -> Optional.ofNullable(f.getTaxCategory()))
- .flatMap(f -> Optional.ofNullable(f.getTaxScheme()))
- .flatMap(taxScheme -> Optional.ofNullable(taxScheme.getId()))
- .flatMap(code -> Catalog.valueOfCode(Catalog5.class, code))
- .orElse(null),
- taxTotal -> Optional.ofNullable(taxTotal.getTaxAmount()).orElse(BigDecimal.ZERO)
- ));
+ default ComprobanteImpuestos mapLineComprobanteImpuestos(XMLSummaryDocumentsLine xml) {
+ if (xml == null) {
+ return null;
+ }
- return ComprobanteImpuestos.builder()
- .igv(taxTotals.get(Catalog5.IGV))
- .icb(taxTotals.get(Catalog5.ICBPER))
- .build();
- }
+ Map taxTotals = Optional.ofNullable(xml.getTaxTotals())
+ .orElse(Collections.emptyList())
+ .stream()
+ .collect(Collectors.toMap(
+ taxTotal -> Optional.ofNullable(taxTotal.getTaxSubtotals())
+ .flatMap(f -> Optional.ofNullable(f.getTaxCategory()))
+ .flatMap(f -> Optional.ofNullable(f.getTaxScheme()))
+ .flatMap(taxScheme -> Optional
+ .ofNullable(taxScheme.getId()))
+ .flatMap(code -> Catalog.valueOfCode(Catalog5.class,
+ code))
+ .orElse(null),
+ taxTotal -> Optional.ofNullable(taxTotal.getTaxAmount())
+ .orElse(BigDecimal.ZERO)));
+
+ return ComprobanteImpuestos.builder()
+ .igv(taxTotals.get(Catalog5.IGV))
+ .icb(taxTotals.get(Catalog5.ICBPER))
+ .isc(taxTotals.get(Catalog5.ISC))
+ .ivap(taxTotals.get(Catalog5.IMPUESTO_ARROZ_PILADO))
+ .otros(taxTotals.get(Catalog5.OTROS))
+ .build();
+ }
}
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLDespatchAdvice.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLDespatchAdvice.java
index b2a71c16..d010512c 100644
--- a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLDespatchAdvice.java
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLDespatchAdvice.java
@@ -23,6 +23,11 @@
@Data
@NoArgsConstructor
public class XMLDespatchAdvice {
+ @XmlElement(name = "UBLVersionID", namespace = XMLConstants.CBC)
+ private String ublVersionId;
+
+ @XmlElement(name = "CustomizationID", namespace = XMLConstants.CBC)
+ private String customizationId;
@XmlElement(name = "ID", namespace = XMLConstants.CBC)
private String documentId;
@@ -45,7 +50,7 @@ public class XMLDespatchAdvice {
private OrderReference orderReference;
@XmlElement(name = "AdditionalDocumentReference", namespace = XMLConstants.CAC)
- private AdditionalDocumentReference additionalDocumentReference;
+ private List additionalDocumentReferences;
@XmlElement(name = "Signature", namespace = XMLConstants.CAC)
private XMLSignature signature;
@@ -59,6 +64,9 @@ public class XMLDespatchAdvice {
@XmlElement(name = "SellerSupplierParty", namespace = XMLConstants.CAC)
private SellerSupplierParty sellerSupplierParty;
+ @XmlElement(name = "BuyerCustomerParty", namespace = XMLConstants.CAC)
+ private BuyerCustomerParty buyerCustomerParty;
+
@XmlElement(name = "Shipment", namespace = XMLConstants.CAC)
private Shipment shipment;
@@ -87,6 +95,21 @@ public static class AdditionalDocumentReference {
@XmlElement(name = "DocumentTypeCode", namespace = XMLConstants.CBC)
private String documentTypeCode;
+
+ @XmlElement(name = "DocumentType", namespace = XMLConstants.CBC)
+ private String documentType;
+
+ @XmlElement(name = "IssuerParty", namespace = XMLConstants.CAC)
+ private IssuerParty issuerParty;
+ }
+
+ @XmlAccessorType(XmlAccessType.NONE)
+ @XmlType(name = "DespatchAdvice.IssuerParty")
+ @Data
+ @NoArgsConstructor
+ public static class IssuerParty {
+ @XmlElement(name = "PartyIdentification", namespace = XMLConstants.CAC)
+ private PartyIdentification partyIdentification;
}
@XmlAccessorType(XmlAccessType.NONE)
@@ -138,8 +161,22 @@ public static class ID {
public static class PartyLegalEntity {
@XmlElement(name = "RegistrationName", namespace = XMLConstants.CBC)
private String registrationName;
+
+ @XmlElement(name = "CompanyID", namespace = XMLConstants.CBC)
+ private String companyID;
}
+ @XmlAccessorType(XmlAccessType.NONE)
+ @XmlType(name = "DespatchAdvice.BuyerCustomerParty")
+ @Data
+ @NoArgsConstructor
+ public static class BuyerCustomerParty {
+ @XmlElement(name = "CustomerAssignedAccountId", namespace = XMLConstants.CBC)
+ private String customerAssignedAccountId;
+
+ @XmlElement(name = "Party", namespace = XMLConstants.CAC)
+ private Party party;
+ }
@XmlAccessorType(XmlAccessType.NONE)
@XmlType(name = "DespatchAdvice.DeliveryCustomerParty")
@@ -179,8 +216,14 @@ public static class Shipment {
@XmlElement(name = "TotalTransportHandlingUnitQuantity", namespace = XMLConstants.CBC)
private Integer totalTransportHandlingUnitQuantity;
- @XmlElement(name = "SplitConsignmentIndicator", namespace = XMLConstants.CBC)
- private Boolean splitConsignmentIndicator;
+ @XmlElement(name = "HandlingInstructions", namespace = XMLConstants.CBC)
+ private String handlingInstructions;
+
+ @XmlElement(name = "SpecialInstructions", namespace = XMLConstants.CBC)
+ private List specialInstructions;
+
+ @XmlElement(name = "NetWeightMeasure", namespace = XMLConstants.CBC)
+ private GrossWeightMeasure netWeightMeasure;
@XmlElement(name = "ShipmentStage", namespace = XMLConstants.CAC)
private ShipmentStage shipmentStage;
@@ -189,10 +232,7 @@ public static class Shipment {
private Delivery delivery;
@XmlElement(name = "TransportHandlingUnit", namespace = XMLConstants.CAC)
- private TransportHandlingUnit transportHandlingUnit;
-
- @XmlElement(name = "OriginAddress", namespace = XMLConstants.CAC)
- private OriginAddress originAddress;
+ private List transportHandlingUnit;
@XmlElement(name = "FirstArrivalPortLocation", namespace = XMLConstants.CAC)
private FirstArrivalPortLocation firstArrivalPortLocation;
@@ -228,7 +268,7 @@ public static class ShipmentStage {
private TransportMeans transportMeans;
@XmlElement(name = "DriverPerson", namespace = XMLConstants.CAC)
- private DriverPerson driverPerson;
+ private List driverPersons;
}
@XmlAccessorType(XmlAccessType.NONE)
@@ -251,6 +291,9 @@ public static class CarrierParty {
@XmlElement(name = "PartyName", namespace = XMLConstants.CAC)
private PartyName partyName;
+
+ @XmlElement(name = "PartyLegalEntity", namespace = XMLConstants.CAC)
+ private PartyLegalEntity partyLegalEntity;
}
@XmlAccessorType(XmlAccessType.NONE)
@@ -287,6 +330,27 @@ public static class RoadTransport {
public static class DriverPerson {
@XmlElement(name = "ID", namespace = XMLConstants.CBC)
private ID id;
+
+ @XmlElement(name = "FirstName", namespace = XMLConstants.CBC)
+ private String firstName;
+
+ @XmlElement(name = "FamilyName", namespace = XMLConstants.CBC)
+ private String familyName;
+
+ @XmlElement(name = "JobTitle", namespace = XMLConstants.CBC)
+ private String jobTitle;
+
+ @XmlElement(name = "IdentityDocumentReference", namespace = XMLConstants.CAC)
+ private IdentityDocumentReference identityDocumentReference;
+ }
+
+ @XmlAccessorType(XmlAccessType.NONE)
+ @XmlType(name = "DespatchAdvice.IdentityDocumentReference")
+ @Data
+ @NoArgsConstructor
+ public static class IdentityDocumentReference {
+ @XmlElement(name = "ID", namespace = XMLConstants.CBC)
+ private String id;
}
@XmlAccessorType(XmlAccessType.NONE)
@@ -296,6 +360,33 @@ public static class DriverPerson {
public static class Delivery {
@XmlElement(name = "DeliveryAddress", namespace = XMLConstants.CAC)
private DeliveryAddress deliveryAddress;
+
+ @XmlElement(name = "Despatch", namespace = XMLConstants.CAC)
+ private Despatch despatch;
+ }
+
+ @XmlAccessorType(XmlAccessType.NONE)
+ @XmlType(name = "DespatchAdvice.Despatch")
+ @Data
+ @NoArgsConstructor
+ public static class Despatch {
+ @XmlElement(name = "DespatchAddress", namespace = XMLConstants.CAC)
+ private DespatchAddress despatchAddress;
+ }
+
+ @XmlAccessorType(XmlAccessType.NONE)
+ @XmlType(name = "DespatchAdvice.DespatchAddress")
+ @Data
+ @NoArgsConstructor
+ public static class DespatchAddress {
+ @XmlElement(name = "ID", namespace = XMLConstants.CBC)
+ private String id;
+
+ @XmlElement(name = "AddressTypeCode", namespace = XMLConstants.CBC)
+ private AddressTypeCode addressTypeCode;
+
+ @XmlElement(name = "AddressLine", namespace = XMLConstants.CAC)
+ private AddressLine addressLine;
}
@XmlAccessorType(XmlAccessType.NONE)
@@ -306,10 +397,25 @@ public static class DeliveryAddress {
@XmlElement(name = "ID", namespace = XMLConstants.CBC)
private String id;
+ @XmlElement(name = "AddressTypeCode", namespace = XMLConstants.CBC)
+ private AddressTypeCode addressTypeCode;
+
@XmlElement(name = "AddressLine", namespace = XMLConstants.CAC)
private AddressLine addressLine;
}
+ @XmlAccessorType(XmlAccessType.NONE)
+ @XmlType(name = "DespatchAdvice.AddressTypeCode")
+ @Data
+ @NoArgsConstructor
+ public static class AddressTypeCode {
+ @XmlValue
+ private String value;
+
+ @XmlAttribute(name = "listID")
+ private String listID;
+ }
+
@XmlAccessorType(XmlAccessType.NONE)
@XmlType(name = "DespatchAdvice.AddressLine")
@Data
@@ -325,7 +431,22 @@ public static class AddressLine {
@NoArgsConstructor
public static class TransportHandlingUnit {
@XmlElement(name = "TransportEquipment", namespace = XMLConstants.CAC)
- private TransportEquipment transportEquipment;
+ private List transportEquipments;
+
+ @XmlElement(name = "Package", namespace = XMLConstants.CAC)
+ private List packages;
+ }
+
+ @XmlAccessorType(XmlAccessType.NONE)
+ @XmlType(name = "DespatchAdvice.Package")
+ @Data
+ @NoArgsConstructor
+ public static class Package {
+ @XmlElement(name = "ID", namespace = XMLConstants.CBC)
+ private String id;
+
+ @XmlElement(name = "TraceID", namespace = XMLConstants.CBC)
+ private String traceID;
}
@XmlAccessorType(XmlAccessType.NONE)
@@ -335,6 +456,33 @@ public static class TransportHandlingUnit {
public static class TransportEquipment {
@XmlElement(name = "ID", namespace = XMLConstants.CBC)
private String id;
+
+ @XmlElement(name = "ApplicableTransportMeans", namespace = XMLConstants.CAC)
+ private ApplicableTransportMeans applicableTransportMeans;
+
+ @XmlElement(name = "AttachedTransportEquipment", namespace = XMLConstants.CAC)
+ private List attachedTransportEquipments;
+
+ @XmlElement(name = "ShipmentDocumentReference", namespace = XMLConstants.CAC)
+ private List shipmentDocumentReferences;
+ }
+
+ @XmlAccessorType(XmlAccessType.NONE)
+ @XmlType(name = "DespatchAdvice.ApplicableTransportMeans")
+ @Data
+ @NoArgsConstructor
+ public static class ApplicableTransportMeans {
+ @XmlElement(name = "RegistrationNationalityID", namespace = XMLConstants.CBC)
+ private String registrationNationalityID;
+ }
+
+ @XmlAccessorType(XmlAccessType.NONE)
+ @XmlType(name = "DespatchAdvice.ShipmentDocumentReference")
+ @Data
+ @NoArgsConstructor
+ public static class ShipmentDocumentReference {
+ @XmlElement(name = "ID", namespace = XMLConstants.CBC)
+ private ID id;
}
@XmlAccessorType(XmlAccessType.NONE)
@@ -356,5 +504,11 @@ public static class OriginAddress {
public static class FirstArrivalPortLocation {
@XmlElement(name = "ID", namespace = XMLConstants.CBC)
private String id;
+
+ @XmlElement(name = "LocationTypeCode", namespace = XMLConstants.CBC)
+ private String locationTypeCode;
+
+ @XmlElement(name = "Name", namespace = XMLConstants.CBC)
+ private String name;
}
}
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLDespatchAdviceLine.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLDespatchAdviceLine.java
index 5a5505ba..791e3409 100644
--- a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLDespatchAdviceLine.java
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLDespatchAdviceLine.java
@@ -3,6 +3,8 @@
import lombok.Data;
import lombok.NoArgsConstructor;
+import java.util.List;
+
import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlAttribute;
@@ -42,11 +44,32 @@ public static class Item {
@XmlElement(name = "Name", namespace = XMLConstants.CBC)
private String name;
+ @XmlElement(name = "Description", namespace = XMLConstants.CBC)
+ private String description;
+
@XmlElement(name = "SellersItemIdentification", namespace = XMLConstants.CAC)
private SellersItemIdentification sellersItemIdentification;
@XmlElement(name = "CommodityClassification", namespace = XMLConstants.CAC)
private CommodityClassification commodityClassification;
+
+ @XmlElement(name = "AdditionalItemProperty", namespace = XMLConstants.CAC)
+ private List additionalItemProperties;
+ }
+
+ @XmlAccessorType(XmlAccessType.NONE)
+ @XmlType(name = "DespatchAdviceLine.AdditionalItemProperty")
+ @Data
+ @NoArgsConstructor
+ public static class AdditionalItemProperty {
+ @XmlElement(name = "Name", namespace = XMLConstants.CBC)
+ private String name;
+
+ @XmlElement(name = "NameCode", namespace = XMLConstants.CBC)
+ private String nameCode;
+
+ @XmlElement(name = "Value", namespace = XMLConstants.CBC)
+ private String value;
}
@XmlAccessorType(XmlAccessType.NONE)
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/general/EmbededDespatch.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/general/EmbededDespatch.java
new file mode 100644
index 00000000..e1910c63
--- /dev/null
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/general/EmbededDespatch.java
@@ -0,0 +1,49 @@
+package io.github.project.openubl.xbuilder.content.models.standard.general;
+
+import io.github.project.openubl.xbuilder.content.models.common.Cliente;
+import io.github.project.openubl.xbuilder.content.models.common.Direccion;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class EmbededDespatch {
+
+ @Schema(description = "Punto de llegada")
+ private Direccion llegada;
+
+ @Schema(description = "Punto de partida")
+ private Direccion partida;
+
+ @Schema(description = "Datos del transportista")
+ private Cliente transportista;
+
+ @Schema(description = "Numero de licencia de conducir")
+ private String nroLicencia;
+
+ @Schema(description = "Placa del vehiculo")
+ private String transpPlaca;
+
+ @Schema(description = "Codigo de autorizacion del transporte")
+ private String transpCodeAuth;
+
+ @Schema(description = "Marca del vehiculo")
+ private String transpMarca;
+
+ @Schema(description = "Modalidad de traslado. Catalog 18")
+ private String modTraslado;
+
+ @Schema(description = "Peso bruto total")
+ private BigDecimal pesoBruto;
+
+ @Schema(description = "Unidad de medida del peso bruto")
+ private String undPesoBruto;
+
+}
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/general/Invoice.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/general/Invoice.java
index 248d59da..63257183 100644
--- a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/general/Invoice.java
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/general/Invoice.java
@@ -45,6 +45,11 @@ public class Invoice extends SalesDocument {
private Detraccion detraccion;
private Percepcion percepcion;
+ /**
+ * Guia de remision embebida (Factura Guia)
+ */
+ private EmbededDespatch guiaEmbebida;
+
/**
* Anticipos asociados al comprobante
*/
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/general/SalesDocument.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/general/SalesDocument.java
index 6a45f35c..3d2d6581 100644
--- a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/general/SalesDocument.java
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/general/SalesDocument.java
@@ -99,4 +99,10 @@ public abstract class SalesDocument extends Document {
@Singular
@ArraySchema
private List documentosRelacionados;
+
+ /**
+ * Cargos globales del documento
+ */
+ @Singular
+ private List cargos;
}
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Comprador.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Comprador.java
new file mode 100644
index 00000000..47c0f2e7
--- /dev/null
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Comprador.java
@@ -0,0 +1,36 @@
+package io.github.project.openubl.xbuilder.content.models.standard.guia;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Modelo para el comprador en la guía de remisión.
+ * Representa al adquiriente de los bienes cuando aplica.
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class Comprador {
+
+ /**
+ * Tipo de documento de identidad (Catálogo 06)
+ */
+ @Schema(description = "Catalogo 06", requiredMode = Schema.RequiredMode.REQUIRED)
+ private String tipoDocumentoIdentidad;
+
+ /**
+ * Número de documento de identidad
+ */
+ @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
+ private String numeroDocumentoIdentidad;
+
+ /**
+ * Razón social o nombre
+ */
+ @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
+ private String nombre;
+}
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DespatchAdvice.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DespatchAdvice.java
index 4b9e7be5..9337c08a 100644
--- a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DespatchAdvice.java
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DespatchAdvice.java
@@ -21,6 +21,11 @@
@NoArgsConstructor
@AllArgsConstructor
public class DespatchAdvice {
+ /**
+ * Versión del formato de la guía de remisión (ejemplo: 2.0)
+ */
+ private String version;
+
/**
* Serie del comprobante
*/
@@ -56,6 +61,13 @@ public class DespatchAdvice {
@Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private DocumentoRelacionado documentoRelacionado;
+ /**
+ * Documentos adicionales relacionados al transporte (Catálogo 61)
+ */
+ @Singular("documentoAdicional")
+ @Schema(description = "Documentos adicionales relacionados al transporte")
+ private List documentosAdicionales;
+
@Schema(description = "Persona que firma electrónicamente el comprobante. Si NULL los datos del proveedor son usados.")
private Firmante firmante;
@@ -68,6 +80,18 @@ public class DespatchAdvice {
@Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private Proveedor proveedor;
+ /**
+ * Datos del tercero (vendedor de los bienes cuando aplica)
+ */
+ @Schema(description = "Tercero/Vendedor de los bienes")
+ private Tercero tercero;
+
+ /**
+ * Datos del comprador (adquiriente de los bienes)
+ */
+ @Schema(description = "Comprador/Adquiriente de los bienes")
+ private Comprador comprador;
+
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
private Envio envio;
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DespatchAdviceItem.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DespatchAdviceItem.java
index d8ca3ae5..6184d717 100644
--- a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DespatchAdviceItem.java
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DespatchAdviceItem.java
@@ -4,9 +4,11 @@
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
+import lombok.Singular;
import lombok.extern.jackson.Jacksonized;
import java.math.BigDecimal;
+import java.util.List;
@Jacksonized
@Data
@@ -20,4 +22,7 @@ public class DespatchAdviceItem {
private String descripcion;
private String codigo;
private String codigoSunat;
+
+ @Singular
+ private List atributos;
}
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Destino.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Destino.java
index 93d531de..1093c9d0 100644
--- a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Destino.java
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Destino.java
@@ -1,5 +1,6 @@
package io.github.project.openubl.xbuilder.content.models.standard.guia;
+import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@@ -10,6 +11,22 @@
@NoArgsConstructor
@AllArgsConstructor
public class Destino {
+
+ @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
private String ubigeo;
+
+ @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
private String direccion;
+
+ /**
+ * Código de establecimiento del punto de llegada
+ */
+ @Schema(description = "Código de local anexo de llegada")
+ private String codigoLocal;
+
+ /**
+ * RUC asociado al punto de llegada
+ */
+ @Schema(description = "RUC asociado al punto de llegada")
+ private String ruc;
}
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DocumentoAdicional.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DocumentoAdicional.java
new file mode 100644
index 00000000..310cd139
--- /dev/null
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DocumentoAdicional.java
@@ -0,0 +1,43 @@
+package io.github.project.openubl.xbuilder.content.models.standard.guia;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Modelo para documentos adicionales relacionados al transporte.
+ * Catálogo 61 de SUNAT.
+ * Basado en el modelo AdditionalDoc de greenter.
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class DocumentoAdicional {
+
+ /**
+ * Código del tipo de documento (Catálogo 61)
+ */
+ @Schema(description = "Catalogo 61", requiredMode = Schema.RequiredMode.REQUIRED)
+ private String tipoDocumento;
+
+ /**
+ * Descripción del tipo de documento
+ */
+ @Schema(description = "Descripción del tipo de documento")
+ private String tipoDocumentoDescripcion;
+
+ /**
+ * Número del documento
+ */
+ @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
+ private String numero;
+
+ /**
+ * RUC del emisor del documento
+ */
+ @Schema(description = "RUC del emisor del documento")
+ private String rucEmisor;
+}
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Driver.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Driver.java
new file mode 100644
index 00000000..83e5902e
--- /dev/null
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Driver.java
@@ -0,0 +1,54 @@
+package io.github.project.openubl.xbuilder.content.models.standard.guia;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Modelo para conductor/chofer de la guía de remisión.
+ * Basado en el modelo Driver de greenter.
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class Driver {
+
+ /**
+ * Tipo de conductor: "Principal" o "Secundario"
+ */
+ @Schema(description = "Tipo de conductor: Principal o Secundario")
+ private String tipo;
+
+ /**
+ * Tipo de documento de identidad del chofer (Catálogo 06)
+ */
+ @Schema(description = "Catalogo 06", requiredMode = Schema.RequiredMode.REQUIRED)
+ private String tipoDocumentoIdentidad;
+
+ /**
+ * Número de documento de identidad del chofer
+ */
+ @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
+ private String numeroDocumentoIdentidad;
+
+ /**
+ * Nombres del conductor
+ */
+ @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
+ private String nombres;
+
+ /**
+ * Apellidos del conductor
+ */
+ @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
+ private String apellidos;
+
+ /**
+ * Número de licencia de conducir
+ */
+ @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
+ private String licencia;
+}
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Envio.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Envio.java
index 49c1a724..5dcf868b 100644
--- a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Envio.java
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Envio.java
@@ -5,9 +5,11 @@
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
+import lombok.Singular;
import java.math.BigDecimal;
import java.time.LocalDate;
+import java.util.List;
@Data
@Builder
@@ -17,6 +19,7 @@ public class Envio {
@Schema(description = "Catalog 20", requiredMode = Schema.RequiredMode.REQUIRED)
private String tipoTraslado;
+
private String motivoTraslado;
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
@@ -25,8 +28,19 @@ public class Envio {
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
private String pesoTotalUnidadMedida;
+ /**
+ * Peso de los ítems seleccionados (en KGM)
+ */
+ @Schema(description = "Peso bruto de los items seleccionados")
+ private BigDecimal pesoItems;
+
+ /**
+ * Sustento de la diferencia del peso bruto total respecto al peso de los ítems
+ */
+ @Schema(description = "Sustento de diferencia de peso")
+ private String sustentoPeso;
+
private Integer numeroDeBultos;
- private boolean transbordoProgramado;
@Schema(description = "Catalog 18", requiredMode = Schema.RequiredMode.REQUIRED)
private String tipoModalidadTraslado;
@@ -34,12 +48,48 @@ public class Envio {
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDate fechaTraslado;
- private String numeroDeContenedor;
- private String codigoDePuerto;
+ /**
+ * Lista de contenedores/precintos
+ */
+ @Singular("contenedor")
+ @Schema(description = "Lista de contenedores o precintos")
+ private List contenedores;
+
+ /**
+ * Puerto de embarque/desembarque
+ */
+ @Schema(description = "Puerto de embarque/desembarque (Catalogo 63)")
+ private Puerto puerto;
+
+ /**
+ * Aeropuerto de embarque/desembarque
+ */
+ @Schema(description = "Aeropuerto de embarque/desembarque (Catalogo 64)")
+ private Puerto aeropuerto;
@Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private Transportista transportista;
+ /**
+ * Lista de conductores (principal y secundarios)
+ */
+ @Singular("chofer")
+ @Schema(description = "Lista de conductores")
+ private List choferes;
+
+ /**
+ * Vehículo principal con posibles vehículos secundarios
+ */
+ @Schema(description = "Vehículo de transporte")
+ private Vehicle vehiculo;
+
+ /**
+ * Indicadores especiales de transporte (SUNAT_Envio_*)
+ */
+ @Singular("indicador")
+ @Schema(description = "Indicadores especiales de transporte")
+ private List indicadores;
+
@Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private Partida partida;
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/GuiaItemAttribute.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/GuiaItemAttribute.java
new file mode 100644
index 00000000..d107dbee
--- /dev/null
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/GuiaItemAttribute.java
@@ -0,0 +1,18 @@
+package io.github.project.openubl.xbuilder.content.models.standard.guia;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.extern.jackson.Jacksonized;
+
+@Jacksonized
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class GuiaItemAttribute {
+ private String code;
+ private String name;
+ private String value;
+}
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Partida.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Partida.java
index 623ed9f1..fbff322b 100644
--- a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Partida.java
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Partida.java
@@ -1,5 +1,6 @@
package io.github.project.openubl.xbuilder.content.models.standard.guia;
+import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@@ -10,6 +11,22 @@
@NoArgsConstructor
@AllArgsConstructor
public class Partida {
+
+ @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
private String ubigeo;
+
+ @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
private String direccion;
+
+ /**
+ * Código de establecimiento del punto de partida
+ */
+ @Schema(description = "Código de local anexo de partida")
+ private String codigoLocal;
+
+ /**
+ * RUC asociado al punto de partida
+ */
+ @Schema(description = "RUC asociado al punto de partida")
+ private String ruc;
}
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Puerto.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Puerto.java
new file mode 100644
index 00000000..cb4e26ca
--- /dev/null
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Puerto.java
@@ -0,0 +1,30 @@
+package io.github.project.openubl.xbuilder.content.models.standard.guia;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Modelo para puerto o aeropuerto de embarque/desembarque.
+ * Basado en el modelo Puerto de greenter.
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class Puerto {
+
+ /**
+ * Código del puerto (Catálogo 63) o aeropuerto (Catálogo 64)
+ */
+ @Schema(description = "Código del puerto (Cat. 63) o aeropuerto (Cat. 64)", requiredMode = Schema.RequiredMode.REQUIRED)
+ private String codigo;
+
+ /**
+ * Nombre del puerto o aeropuerto
+ */
+ @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
+ private String nombre;
+}
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Remitente.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Remitente.java
index a2705777..dd2fc4c5 100644
--- a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Remitente.java
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Remitente.java
@@ -17,4 +17,7 @@ public class Remitente {
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
private String razonSocial;
+
+ @Schema(description = "Número de registro del Ministerio de Transportes y Comunicaciones")
+ private String numeroRegistroMTC;
}
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Tercero.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Tercero.java
new file mode 100644
index 00000000..8c75d6a6
--- /dev/null
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Tercero.java
@@ -0,0 +1,36 @@
+package io.github.project.openubl.xbuilder.content.models.standard.guia;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Modelo para tercero/proveedor en la guía de remisión.
+ * Representa al vendedor de los bienes cuando aplica.
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class Tercero {
+
+ /**
+ * Tipo de documento de identidad (Catálogo 06)
+ */
+ @Schema(description = "Catalogo 06", requiredMode = Schema.RequiredMode.REQUIRED)
+ private String tipoDocumentoIdentidad;
+
+ /**
+ * Número de documento de identidad
+ */
+ @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
+ private String numeroDocumentoIdentidad;
+
+ /**
+ * Razón social o nombre
+ */
+ @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
+ private String nombre;
+}
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Transportista.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Transportista.java
index fe02e9c7..4413f90a 100644
--- a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Transportista.java
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Transportista.java
@@ -21,13 +21,10 @@ public class Transportista {
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
private String nombre;
- @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
- private String placaDelVehiculo;
-
- @Schema(description = "Catalogo 06", requiredMode = Schema.RequiredMode.REQUIRED)
- private String choferTipoDocumentoIdentidad;
-
- @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
- private String choferNumeroDocumentoIdentidad;
+ /**
+ * Número de registro del Ministerio de Transportes y Comunicaciones
+ */
+ @Schema(description = "Número de registro MTC")
+ private String numeroRegistroMTC;
}
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Vehicle.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Vehicle.java
new file mode 100644
index 00000000..f1c381eb
--- /dev/null
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Vehicle.java
@@ -0,0 +1,53 @@
+package io.github.project.openubl.xbuilder.content.models.standard.guia;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.Singular;
+
+import java.util.List;
+
+/**
+ * Modelo para vehículo de transporte de la guía de remisión.
+ * Soporta vehículo principal y vehículos secundarios (carreta, etc.).
+ * Basado en el modelo Vehicle de greenter.
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class Vehicle {
+
+ /**
+ * Número de placa del vehículo
+ */
+ @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
+ private String placa;
+
+ /**
+ * Número de tarjeta de circulación (TUC)
+ */
+ @Schema(description = "Número de tarjeta única de circulación")
+ private String numeroCirculacion;
+
+ /**
+ * Número de autorización o certificado de habilitación vehicular
+ */
+ @Schema(description = "Número de autorización o certificado de habilitación")
+ private String numeroAutorizacion;
+
+ /**
+ * Código de la entidad emisora de la autorización
+ */
+ @Schema(description = "Código de entidad autorizadora")
+ private String codigoEmisor;
+
+ /**
+ * Lista de vehículos secundarios (carretas, semirremolques, etc.)
+ */
+ @Singular
+ @Schema(description = "Vehículos secundarios adjuntos")
+ private List secundarios;
+}
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/baja/Reversion.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/baja/Reversion.java
new file mode 100644
index 00000000..57fa796c
--- /dev/null
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/baja/Reversion.java
@@ -0,0 +1,17 @@
+package io.github.project.openubl.xbuilder.content.models.sunat.baja;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+import lombok.experimental.SuperBuilder;
+import lombok.extern.jackson.Jacksonized;
+
+@Jacksonized
+@Data
+@SuperBuilder
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class Reversion extends VoidedDocuments {
+}
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/resumen/Comprobante.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/resumen/Comprobante.java
index ab66d667..42f828a2 100644
--- a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/resumen/Comprobante.java
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/resumen/Comprobante.java
@@ -15,7 +15,7 @@ public class Comprobante {
@Schema(requiredMode = Schema.RequiredMode.AUTO, description = "Moneda del comprobante declarado")
private String moneda;
-
+
@Schema(requiredMode = Schema.RequiredMode.REQUIRED, description = "Catalogo 01")
private String tipoComprobante;
@@ -31,5 +31,7 @@ public class Comprobante {
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
private ComprobanteImpuestos impuestos;
+ private SummaryPerception percepcion;
+
private ComprobanteAfectado comprobanteAfectado;
}
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/resumen/ComprobanteImpuestos.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/resumen/ComprobanteImpuestos.java
index 80fe384e..49772424 100644
--- a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/resumen/ComprobanteImpuestos.java
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/resumen/ComprobanteImpuestos.java
@@ -19,4 +19,13 @@ public class ComprobanteImpuestos {
@Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED, description = "ICB del comprobante")
private BigDecimal icb;
+
+ @Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED, description = "ISC del comprobante")
+ private BigDecimal isc;
+
+ @Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED, description = "IVAP del comprobante")
+ private BigDecimal ivap;
+
+ @Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED, description = "Otros tributos del comprobante")
+ private BigDecimal otros;
}
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/resumen/SummaryPerception.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/resumen/SummaryPerception.java
new file mode 100644
index 00000000..c8fafc33
--- /dev/null
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/resumen/SummaryPerception.java
@@ -0,0 +1,31 @@
+package io.github.project.openubl.xbuilder.content.models.sunat.resumen;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SummaryPerception {
+
+ @Schema(description = "Codigo de regimen de percepcion. Catalogo 22")
+ private String codReg;
+
+ @Schema(description = "Tasa de percepcion")
+ private BigDecimal tasa;
+
+ @Schema(description = "Monto base de percepcion")
+ private BigDecimal mtoBase;
+
+ @Schema(description = "Monto de percepcion")
+ private BigDecimal mto;
+
+ @Schema(description = "Monto total de percepcion")
+ private BigDecimal mtoTotal;
+}
diff --git a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/renderer/TemplateProducer.java b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/renderer/TemplateProducer.java
index 05c38ff9..38ab3e91 100644
--- a/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/renderer/TemplateProducer.java
+++ b/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/renderer/TemplateProducer.java
@@ -36,6 +36,10 @@ public Template getDespatchAdvice() {
return EngineProducer.getInstance().getEngine().getTemplate("Renderer/despatchAdvice.xml");
}
+ public Template getReversion() {
+ return EngineProducer.getInstance().getEngine().getTemplate("Renderer/reversion.xml");
+ }
+
private static class TemplateProducerHolder {
private static final TemplateProducer INSTANCE = new TemplateProducer();
diff --git a/xbuilder/core/src/main/resources/templates/Renderer/despatchAdvice.xml b/xbuilder/core/src/main/resources/templates/Renderer/despatchAdvice.xml
index 476a8283..7a89706d 100644
--- a/xbuilder/core/src/main/resources/templates/Renderer/despatchAdvice.xml
+++ b/xbuilder/core/src/main/resources/templates/Renderer/despatchAdvice.xml
@@ -7,7 +7,7 @@
>
{#include ubl/standard/include/ubl-extensions.xml /}
{#include ubl/standard/include/general-data.xml item=this /}
- {tipoComprobante}
+ {tipoComprobante}
{#if observaciones}
{/if}
@@ -23,6 +23,22 @@
{documentoRelacionado.tipoDocumento}
{/if}
+ {#each documentosAdicionales.orEmpty}
+
+ {it.numero}
+ {it.tipoDocumento}
+ {#if it.tipoDocumentoDescripcion}
+ {it.tipoDocumentoDescripcion}
+ {/if}
+ {#if it.rucEmisor}
+
+
+ {it.rucEmisor}
+
+
+ {/if}
+
+ {/each}
{#include ubl/common/signature.xml firmante=this.firmante /}
{remitente.ruc}
@@ -32,6 +48,9 @@
+ {#if remitente.numeroRegistroMTC}
+ {remitente.numeroRegistroMTC}
+ {/if}
@@ -45,7 +64,30 @@
- {#if proveedor}
+ {#if comprador}
+
+
+
+ {comprador.numeroDocumentoIdentidad}
+
+
+
+
+
+
+ {/if}
+ {#if tercero}
+
+
+
+ {tercero.numeroDocumentoIdentidad}
+
+
+
+
+
+
+ {#else if proveedor}
{proveedor.ruc}
@@ -56,16 +98,24 @@
{/if}
- 1
+ SUNAT_Envio
{envio.tipoTraslado}
{#if envio.motivoTraslado}
- {envio.motivoTraslado}
+ {envio.motivoTraslado}
+ {/if}
+ {#if envio.sustentoPeso}
+ {envio.sustentoPeso}
{/if}
{envio.pesoTotal.scale(3)}
+ {#if envio.pesoItems}
+ {envio.pesoItems.scale(3)}
+ {/if}
{#if envio.numeroDeBultos}
{envio.numeroDeBultos}
{/if}
- {envio.transbordoProgramado}
+ {#each envio.indicadores.orEmpty}
+ {it}
+ {/each}
{envio.tipoModalidadTraslado}
@@ -76,42 +126,111 @@
{envio.transportista.numeroDocumentoIdentidad}
-
-
-
+
+
+ {#if envio.transportista.numeroRegistroMTC}
+ {envio.transportista.numeroRegistroMTC}
+ {/if}
+
-
-
- {envio.transportista.placaDelVehiculo}
-
-
+ {/if}
+ {#each envio.choferes.orEmpty}
- {envio.transportista.choferNumeroDocumentoIdentidad}
+ {it.numeroDocumentoIdentidad}
+ {#if it.nombres}
+ {it.nombres}
+ {/if}
+ {#if it.apellidos}
+ {it.apellidos}
+ {/if}
+ {#if it.tipo}
+ {it.tipo}
+ {/if}
+ {#if it.licencia}
+
+ {it.licencia}
+
+ {/if}
- {/if}
+ {/each}
+ {#if envio.destino}
{envio.destino.ubigeo}
+ {#if envio.destino.codigoLocal}
+ {envio.destino.codigoLocal}
+ {/if}
{envio.destino.direccion}
+ {/if}
+ {#if envio.partida}
+
+
+ {envio.partida.ubigeo}
+ {#if envio.partida.codigoLocal}
+ {envio.partida.codigoLocal}
+ {/if}
+
+ {envio.partida.direccion}
+
+
+
+ {/if}
- {#if envio.numeroDeContenedor}
+ {#each envio.contenedores.orEmpty}
+
+
+ {it_index.add(1)}
+ {it}
+
+
+ {/each}
+ {#if envio.vehiculo}
- {envio.numeroDeContenedor}
+ {envio.vehiculo.placa}
+ {#if envio.vehiculo.numeroCirculacion}
+
+ {envio.vehiculo.numeroCirculacion}
+
+ {/if}
+ {#each envio.vehiculo.secundarios.orEmpty}
+
+ {it.placa}
+ {#if it.numeroCirculacion}
+
+ {it.numeroCirculacion}
+
+ {/if}
+ {#if it.numeroAutorizacion}
+
+ {it.numeroAutorizacion}
+
+ {/if}
+
+ {/each}
+ {#if envio.vehiculo.numeroAutorizacion}
+
+ {envio.vehiculo.numeroAutorizacion}
+
+ {/if}
{/if}
-
- {envio.partida.ubigeo}
- {envio.partida.direccion}
-
- {#if envio.codigoDePuerto}
+ {#if envio.puerto}
+
+ {envio.puerto.codigo}
+ 1
+ {envio.puerto.nombre}
+
+ {#else if envio.aeropuerto}
- {{ envio.codigoDePuerto }}
+ {envio.aeropuerto.codigo}
+ 2
+ {envio.aeropuerto.nombre}
{/if}
@@ -124,7 +243,7 @@
{#if it.descripcion}
-
+
{/if}
{it.codigo}
@@ -134,6 +253,15 @@
{it.codigoSunat}
{/if}
+ {#each it.atributos.orEmpty}
+
+ {it.name}
+ {it.code}
+ {#if it.value}
+ {it.value}
+ {/if}
+
+ {/each}
{/each}
diff --git a/xbuilder/core/src/main/resources/templates/Renderer/invoice.xml b/xbuilder/core/src/main/resources/templates/Renderer/invoice.xml
index 7ad5e75e..5c8a16a6 100644
--- a/xbuilder/core/src/main/resources/templates/Renderer/invoice.xml
+++ b/xbuilder/core/src/main/resources/templates/Renderer/invoice.xml
@@ -48,6 +48,74 @@
{/if}
+ {#if guiaEmbebida}
+
+
+
+ {guiaEmbebida.llegada.ubigueo}
+ {guiaEmbebida.llegada.direccion}
+ {#if guiaEmbebida.llegada.urbanizacion}
+ {guiaEmbebida.llegada.urbanizacion}
+ {/if}
+ {guiaEmbebida.llegada.provincia}
+ {guiaEmbebida.llegada.departamento}
+ {guiaEmbebida.llegada.distrito}
+
+ {guiaEmbebida.llegada.codigoPais}
+
+
+
+
+
+ {guiaEmbebida.partida.ubigueo}
+ {guiaEmbebida.partida.direccion}
+ {#if guiaEmbebida.partida.urbanizacion}
+ {guiaEmbebida.partida.urbanizacion}
+ {/if}
+ {guiaEmbebida.partida.provincia}
+ {guiaEmbebida.partida.departamento}
+ {guiaEmbebida.partida.distrito}
+
+ {guiaEmbebida.partida.codigoPais}
+
+
+
+
+ {guiaEmbebida.pesoBruto}
+
+ {guiaEmbebida.modTraslado}
+
+ {fechaEmision}
+
+
+
+ {guiaEmbebida.transportista.numeroDocumentoIdentidad}
+
+
+
+
+
+
+ {guiaEmbebida.nroLicencia}
+
+
+
+
+ {guiaEmbebida.llegada.ubigueo}
+ {guiaEmbebida.llegada.direccion}
+
+ {guiaEmbebida.llegada.codigoPais}
+
+
+
+
+
+ {guiaEmbebida.transpPlaca}
+
+
+
+
+ {/if}
{#if detraccion}
Detraccion
@@ -85,6 +153,15 @@
{it.monto}
{/each}
+ {#each cargos.orEmpty}
+
+ true
+ {it.tipo}
+ {it.porcentaje.scale(2)}
+ {it.monto.scale(2)}
+ {it.monto.scale(2)}
+
+ {/each}
{#each descuentos.orEmpty}
false
diff --git a/xbuilder/core/src/main/resources/templates/Renderer/reversion.xml b/xbuilder/core/src/main/resources/templates/Renderer/reversion.xml
new file mode 100644
index 00000000..a9c62caa
--- /dev/null
+++ b/xbuilder/core/src/main/resources/templates/Renderer/reversion.xml
@@ -0,0 +1,26 @@
+
+
+ {#include ubl/standard/include/ubl-extensions.xml /}
+ 2.0
+ 1.0
+ RR-{fechaEmision.format('yyyyMMdd')}-{numero}
+ {fechaEmisionComprobantes}
+ {fechaEmision}
+ {#include ubl/common/signature.xml firmante=this.firmante /}
+ {#include ubl/sunat/include/supplier.xml proveedor=this.proveedor /}
+ {#each comprobantes.orEmpty}
+
+ {it_index.add(1)}
+ {it.tipoComprobante}
+ {it.serie}
+ {it.numero}
+ {it.descripcionSustento}
+
+ {/each}
+
diff --git a/xbuilder/core/src/main/resources/templates/Renderer/summaryDocuments.xml b/xbuilder/core/src/main/resources/templates/Renderer/summaryDocuments.xml
index 7f1b4a10..979271a2 100644
--- a/xbuilder/core/src/main/resources/templates/Renderer/summaryDocuments.xml
+++ b/xbuilder/core/src/main/resources/templates/Renderer/summaryDocuments.xml
@@ -38,6 +38,15 @@
{/if}
+ {#if it.comprobante.percepcion}
+
+ {it.comprobante.percepcion.codReg}
+ {it.comprobante.percepcion.tasa.scale(2)}
+ {it.comprobante.percepcion.mto.scale(2)}
+ {it.comprobante.percepcion.mtoTotal.scale(2)}
+ {it.comprobante.percepcion.mtoBase.scale(2)}
+
+ {/if}
{it.tipoOperacion}
@@ -100,6 +109,51 @@
{/if}
+ {#if it.comprobante.impuestos.isc}
+
+ {it.comprobante.impuestos.isc}
+
+ {it.comprobante.impuestos.isc}
+
+
+ 2000
+ ISC
+ EXC
+
+
+
+
+ {/if}
+ {#if it.comprobante.impuestos.ivap}
+
+ {it.comprobante.impuestos.ivap}
+
+ {it.comprobante.impuestos.ivap}
+
+
+ 1016
+ IVAP
+ VAT
+
+
+
+
+ {/if}
+ {#if it.comprobante.impuestos.otros}
+
+ {it.comprobante.impuestos.otros}
+
+ {it.comprobante.impuestos.otros}
+
+
+ 9999
+ OTROS
+ OTH
+
+
+
+
+ {/if}
{/each}
diff --git a/xbuilder/core/src/main/resources/templates/ubl/standard/include/general-data.xml b/xbuilder/core/src/main/resources/templates/ubl/standard/include/general-data.xml
index 3ab314c0..99ff4825 100644
--- a/xbuilder/core/src/main/resources/templates/ubl/standard/include/general-data.xml
+++ b/xbuilder/core/src/main/resources/templates/ubl/standard/include/general-data.xml
@@ -1,5 +1,5 @@
2.1
- 2.0
+ {item.version ?: '2.0'}
{item.serie}-{item.numero}
{item.fechaEmision}
{#if item.horaEmision}
diff --git a/xbuilder/core/src/test/java/e2e/AbstractTest.java b/xbuilder/core/src/test/java/e2e/AbstractTest.java
index ec62ade5..47e613d5 100644
--- a/xbuilder/core/src/test/java/e2e/AbstractTest.java
+++ b/xbuilder/core/src/test/java/e2e/AbstractTest.java
@@ -28,6 +28,7 @@
import io.github.project.openubl.xbuilder.content.models.standard.general.Invoice;
import io.github.project.openubl.xbuilder.content.models.standard.guia.DespatchAdvice;
import io.github.project.openubl.xbuilder.content.models.sunat.baja.VoidedDocuments;
+import io.github.project.openubl.xbuilder.content.models.sunat.baja.Reversion;
import io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.Perception;
import io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.Retention;
import io.github.project.openubl.xbuilder.content.models.sunat.resumen.SummaryDocuments;
@@ -56,7 +57,8 @@ public class AbstractTest {
private static final CreditNoteMapper creditNoteMapper = Mappers.getMapper(CreditNoteMapper.class);
private static final DebitNoteMapper debitNoteMapper = Mappers.getMapper(DebitNoteMapper.class);
private static final VoidedDocumentsMapper voidedDocumentsMapper = Mappers.getMapper(VoidedDocumentsMapper.class);
- private static final SummaryDocumentsMapper summaryDocumentsMapper = Mappers.getMapper(SummaryDocumentsMapper.class);
+ private static final SummaryDocumentsMapper summaryDocumentsMapper = Mappers
+ .getMapper(SummaryDocumentsMapper.class);
private static final PerceptionMapper perceptionMapper = Mappers.getMapper(PerceptionMapper.class);
private static final RetentionMapper retentionMapper = Mappers.getMapper(RetentionMapper.class);
private static final DespatchAdviceMapper despatchAdviceMapper = Mappers.getMapper(DespatchAdviceMapper.class);
@@ -81,7 +83,8 @@ public YAMLMapper getYamlMapper() {
public void writeYaml(String kind, Object input, String snapshotFilename) throws URISyntaxException, IOException {
String rootDir = getClass().getName().replaceAll("\\.", "/");
- String snapshotFileContent = Files.readString(Paths.get(getClass().getClassLoader().getResource(rootDir + "/" + snapshotFilename).toURI()));
+ String snapshotFileContent = Files.readString(
+ Paths.get(getClass().getClassLoader().getResource(rootDir + "/" + snapshotFilename).toURI()));
Path directoryPath = Paths.get("../quarkus-extension/integration-tests/src/test/resources").resolve(rootDir);
Files.createDirectories(directoryPath);
@@ -90,8 +93,7 @@ public void writeYaml(String kind, Object input, String snapshotFilename) throws
getYamlMapper().writeValue(filePath.toFile(), Map.of(
"kind", kind,
"input", input,
- "snapshot", snapshotFileContent
- ));
+ "snapshot", snapshotFileContent));
}
protected void assertInput(Invoice input, String snapshotFilename) throws Exception {
@@ -285,4 +287,28 @@ protected void assertInput(DespatchAdvice input, String snapshotFilename) throws
writeYaml("DespatchAdvice", input, snapshotFilename);
}
+
+ protected void assertInputReversion(Reversion input, String snapshotFilename) throws Exception {
+ ContentEnricher enricher = new ContentEnricher(defaults, dateProvider);
+ enricher.enrich(input);
+
+ // When
+ Template template = TemplateProducer.getInstance().getReversion();
+ String xml = template.data(input).render();
+
+ String reconstructedXml;
+ try (StringReader reader = new StringReader(xml);) {
+ XMLVoidedDocuments xmlPojo = (XMLVoidedDocuments) JAXBContext.newInstance(XMLVoidedDocuments.class)
+ .createUnmarshaller()
+ .unmarshal(new InputSource(reader));
+ VoidedDocuments inputFromXml = voidedDocumentsMapper.map(xmlPojo);
+ reconstructedXml = TemplateProducer.getInstance().getReversion().data(inputFromXml).render();
+ }
+
+ // Then
+ XMLAssertUtils.assertSnapshot(xml, reconstructedXml, getClass(), snapshotFilename);
+ XMLAssertUtils.assertSendSunat(xml, XMLAssertUtils.VOIDED_DOCUMENTS_XSD);
+
+ writeYaml("Reversion", input, snapshotFilename);
+ }
}
diff --git a/xbuilder/core/src/test/java/e2e/renderer/despatchadvice/DespatchAdviceCarrierTest.java b/xbuilder/core/src/test/java/e2e/renderer/despatchadvice/DespatchAdviceCarrierTest.java
new file mode 100644
index 00000000..cb702470
--- /dev/null
+++ b/xbuilder/core/src/test/java/e2e/renderer/despatchadvice/DespatchAdviceCarrierTest.java
@@ -0,0 +1,75 @@
+package e2e.renderer.despatchadvice;
+
+import e2e.AbstractTest;
+import io.github.project.openubl.xbuilder.content.catalogs.Catalog1;
+import io.github.project.openubl.xbuilder.content.catalogs.Catalog6;
+import io.github.project.openubl.xbuilder.content.catalogs.Catalog18;
+import io.github.project.openubl.xbuilder.content.catalogs.Catalog20;
+import io.github.project.openubl.xbuilder.content.models.standard.guia.*;
+import org.junit.jupiter.api.Test;
+
+import java.math.BigDecimal;
+
+public class DespatchAdviceCarrierTest extends AbstractTest {
+
+ @Test
+ public void testCarrierData() throws Exception {
+ // Given
+ DespatchAdvice input = DespatchAdvice.builder()
+ .serie("V001")
+ .numero(1)
+ .version("2.1")
+ .tipoComprobante(Catalog1.GUIA_REMISION_TRANSPORTISTA.getCode()) // 31
+ .remitente(Remitente.builder() // En una 31, el remitente es el Transportista emitente
+ .ruc("20123456789")
+ .razonSocial("Transportes Veloz S.A.C.")
+ .numeroRegistroMTC("MTC-654321")
+ .build())
+ .destinatario(Destinatario.builder()
+ .tipoDocumentoIdentidad(Catalog6.RUC.getCode())
+ .numeroDocumentoIdentidad("20876543210")
+ .nombre("Cliente Final S.A.")
+ .build())
+ .tercero(Tercero.builder() // El Remitente original (el que solicita el transporte)
+ .tipoDocumentoIdentidad(Catalog6.RUC.getCode())
+ .numeroDocumentoIdentidad("20555555555")
+ .nombre("Empresa Vendedora S.A.C.")
+ .build())
+ .envio(Envio.builder()
+ .tipoTraslado(Catalog20.VENTA.getCode())
+ .pesoTotal(new BigDecimal("500.00"))
+ .pesoTotalUnidadMedida("KGM")
+ .tipoModalidadTraslado(Catalog18.TRANSPORTE_PUBLICO.getCode())
+ .fechaTraslado(dateProvider.now())
+ .chofer(Driver.builder()
+ .tipoDocumentoIdentidad(Catalog6.DNI.getCode())
+ .numeroDocumentoIdentidad("44444444")
+ .nombres("Carlos")
+ .apellidos("Guerrero")
+ .licencia("L5555555")
+ .build())
+ .vehiculo(Vehicle.builder()
+ .placa("XYZ-789")
+ .numeroCirculacion("TUC-V001")
+ .build())
+ .partida(Partida.builder()
+ .direccion("Almacen Principal")
+ .ubigeo("150101")
+ .build())
+ .destino(Destino.builder()
+ .direccion("Tienda Centro")
+ .ubigeo("150102")
+ .build())
+ .build())
+ .detalle(DespatchAdviceItem.builder()
+ .cantidad(new BigDecimal("10.00"))
+ .unidadMedida("NIU")
+ .codigo("PROD-99")
+ .descripcion("Mercaderia variada")
+ .build())
+ .build();
+
+ // When/Then
+ assertInput(input, "carrierData.xml");
+ }
+}
diff --git a/xbuilder/core/src/test/java/e2e/renderer/despatchadvice/DespatchAdviceComplexTest.java b/xbuilder/core/src/test/java/e2e/renderer/despatchadvice/DespatchAdviceComplexTest.java
new file mode 100644
index 00000000..e65ef81d
--- /dev/null
+++ b/xbuilder/core/src/test/java/e2e/renderer/despatchadvice/DespatchAdviceComplexTest.java
@@ -0,0 +1,117 @@
+package e2e.renderer.despatchadvice;
+
+import e2e.AbstractTest;
+import io.github.project.openubl.xbuilder.content.catalogs.Catalog1;
+import io.github.project.openubl.xbuilder.content.catalogs.Catalog18;
+import io.github.project.openubl.xbuilder.content.catalogs.Catalog20;
+import io.github.project.openubl.xbuilder.content.catalogs.Catalog6;
+import io.github.project.openubl.xbuilder.content.models.standard.guia.*;
+import org.junit.jupiter.api.Test;
+
+import java.math.BigDecimal;
+
+public class DespatchAdviceComplexTest extends AbstractTest {
+
+ @Test
+ public void testComplexData() throws Exception {
+ // Given
+ DespatchAdvice input = DespatchAdvice.builder()
+ .serie("T001")
+ .numero(100)
+ .version("2.1")
+ .tipoComprobante(Catalog1.GUIA_REMISION_REMITENTE.getCode())
+ .remitente(Remitente.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
+ .destinatario(Destinatario.builder()
+ .tipoDocumentoIdentidad(Catalog6.DNI.getCode())
+ .numeroDocumentoIdentidad("12345678")
+ .nombre("Mi Cliente S.A.C.")
+ .build())
+ .comprador(Comprador.builder()
+ .tipoDocumentoIdentidad(Catalog6.DNI.getCode())
+ .numeroDocumentoIdentidad("12345678")
+ .nombre("Mi Cliente S.A.C.")
+ .build())
+ .documentoAdicional(DocumentoAdicional.builder()
+ .tipoDocumento("09")
+ .numero("T001-1")
+ .rucEmisor("20100010001")
+ .tipoDocumentoDescripcion("GUIA REMISION")
+ .build())
+ .envio(Envio.builder()
+ .tipoTraslado(Catalog20.VENTA.getCode())
+ .pesoTotal(new BigDecimal("100.50"))
+ .pesoTotalUnidadMedida("KGM")
+ .pesoItems(new BigDecimal("90.00"))
+ .sustentoPeso("Empaque madera")
+ .numeroDeBultos(10)
+ .tipoModalidadTraslado(Catalog18.TRANSPORTE_PUBLICO.getCode())
+ .fechaTraslado(dateProvider.now())
+ .chofer(Driver.builder()
+ .tipoDocumentoIdentidad(Catalog6.DNI.getCode())
+ .numeroDocumentoIdentidad("11111111")
+ .nombres("Juan")
+ .apellidos("Perez")
+ .licencia("Q1234567")
+ .tipo("CONDUCTOR_PRINCIPAL")
+ .build())
+ .chofer(Driver.builder()
+ .tipoDocumentoIdentidad(Catalog6.DNI.getCode())
+ .numeroDocumentoIdentidad("22222222")
+ .nombres("Jose")
+ .apellidos("Gomez")
+ .tipo("COPILOTO")
+ .build())
+ .contenedor("CONT-001")
+ .contenedor("CONT-002")
+ .vehiculo(Vehicle.builder()
+ .placa("ABC-123")
+ .numeroCirculacion("TUC-001")
+ .numeroAutorizacion("AUTH-001")
+ .codigoEmisor("MTC")
+ .secundario(Vehicle.builder()
+ .placa("CAR-456")
+ .numeroCirculacion("TUC-SEC")
+ .build())
+ .build())
+ .puerto(Puerto.builder()
+ .codigo("CALLAO")
+ .nombre("Puerto del Callao")
+ .build())
+ .partida(Partida.builder()
+ .direccion("Av. Origen 123")
+ .ubigeo("010101")
+ .codigoLocal("0001")
+ .ruc("12345678912")
+ .build())
+ .destino(Destino.builder()
+ .direccion("Av. Destino 456")
+ .ubigeo("020202")
+ .codigoLocal("0002")
+ .ruc("87654321098")
+ .build())
+ .build())
+ .detalle(DespatchAdviceItem.builder()
+ .cantidad(new BigDecimal("5.00"))
+ .unidadMedida("NIU")
+ .codigo("ITEM-01")
+ .descripcion("Caja de herramientas")
+ .atributo(GuiaItemAttribute.builder()
+ .name("Color")
+ .code("1001")
+ .value("Rojo")
+ .build())
+ .atributo(GuiaItemAttribute.builder()
+ .name("Marca")
+ .code("1002")
+ .value("ToolMaster")
+ .build())
+ .build())
+ .build();
+
+ assertInput(input, "complexData.xml");
+ }
+
+}
diff --git a/xbuilder/core/src/test/java/e2e/renderer/despatchadvice/DespatchAdviceTest.java b/xbuilder/core/src/test/java/e2e/renderer/despatchadvice/DespatchAdviceTest.java
index 2d019efd..73cca961 100644
--- a/xbuilder/core/src/test/java/e2e/renderer/despatchadvice/DespatchAdviceTest.java
+++ b/xbuilder/core/src/test/java/e2e/renderer/despatchadvice/DespatchAdviceTest.java
@@ -18,52 +18,45 @@
public class DespatchAdviceTest extends AbstractTest {
- @Test
- public void testBasicMinData() throws Exception {
- // Given
- DespatchAdvice input = DespatchAdvice.builder()
- .serie("T001")
- .numero(1)
- .tipoComprobante(Catalog1.GUIA_REMISION_REMITENTE.getCode())
- .remitente(Remitente.builder()
- .ruc("12345678912")
- .razonSocial("Softgreen S.A.C.")
- .build()
- )
- .destinatario(Destinatario.builder()
- .tipoDocumentoIdentidad(Catalog6.DNI.getCode())
- .numeroDocumentoIdentidad("12345678")
- .nombre("mi cliente")
- .build()
- )
- .envio(Envio.builder()
- .tipoTraslado(Catalog20.TRASLADO_EMISOR_ITINERANTE_CP.getCode())
- .pesoTotal(BigDecimal.ONE)
- .pesoTotalUnidadMedida("KG")
- .transbordoProgramado(false)
- .tipoModalidadTraslado(Catalog18.TRANSPORTE_PRIVADO.getCode())
- .fechaTraslado(dateProvider.now())
- .partida(Partida.builder()
- .direccion("DireccionOrigen")
- .ubigeo("010101")
- .build()
- )
- .destino(Destino.builder()
- .direccion("DireccionDestino")
- .ubigeo("020202")
- .build()
- )
- .build()
- )
- .detalle(DespatchAdviceItem.builder()
- .cantidad(new BigDecimal("0.5"))
- .unidadMedida("KG")
- .codigo("123456")
- .build()
- )
- .build();
+ @Test
+ public void testBasicMinData() throws Exception {
+ // Given
+ DespatchAdvice input = DespatchAdvice.builder()
+ .serie("T001")
+ .numero(1)
+ .tipoComprobante(Catalog1.GUIA_REMISION_REMITENTE.getCode())
+ .remitente(Remitente.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
+ .destinatario(Destinatario.builder()
+ .tipoDocumentoIdentidad(Catalog6.DNI.getCode())
+ .numeroDocumentoIdentidad("12345678")
+ .nombre("mi cliente")
+ .build())
+ .envio(Envio.builder()
+ .tipoTraslado(Catalog20.TRASLADO_EMISOR_ITINERANTE_CP.getCode())
+ .pesoTotal(BigDecimal.ONE)
+ .pesoTotalUnidadMedida("KG")
+ .tipoModalidadTraslado(Catalog18.TRANSPORTE_PRIVADO.getCode())
+ .fechaTraslado(dateProvider.now())
+ .partida(Partida.builder()
+ .direccion("DireccionOrigen")
+ .ubigeo("010101")
+ .build())
+ .destino(Destino.builder()
+ .direccion("DireccionDestino")
+ .ubigeo("020202")
+ .build())
+ .build())
+ .detalle(DespatchAdviceItem.builder()
+ .cantidad(new BigDecimal("0.5"))
+ .unidadMedida("KG")
+ .codigo("123456")
+ .build())
+ .build();
- assertInput(input, "minData.xml");
- }
+ assertInput(input, "minData.xml");
+ }
}
diff --git a/xbuilder/core/src/test/java/e2e/renderer/reversion/ReversionTest.java b/xbuilder/core/src/test/java/e2e/renderer/reversion/ReversionTest.java
new file mode 100644
index 00000000..cadfb2a7
--- /dev/null
+++ b/xbuilder/core/src/test/java/e2e/renderer/reversion/ReversionTest.java
@@ -0,0 +1,67 @@
+package e2e.renderer.reversion;
+
+import e2e.AbstractTest;
+import io.github.project.openubl.xbuilder.content.catalogs.Catalog1;
+import io.github.project.openubl.xbuilder.content.models.common.Proveedor;
+import io.github.project.openubl.xbuilder.content.models.sunat.baja.Reversion;
+import io.github.project.openubl.xbuilder.content.models.sunat.baja.VoidedDocumentsItem;
+import org.junit.jupiter.api.Test;
+
+import java.time.LocalDate;
+
+/**
+ * Test for Reversion (Comunicacion de Baja de Retenciones/Percepciones).
+ * Reversion uses prefix "RR-" instead of "RA-" for the document ID.
+ */
+public class ReversionTest extends AbstractTest {
+
+ @Test
+ public void testReversionWithPerceptions() throws Exception {
+ // Given - Reverting perceptions (type 40)
+ Reversion input = Reversion.builder()
+ .numero(1)
+ .fechaEmision(LocalDate.of(2022, 01, 31))
+ .fechaEmisionComprobantes(LocalDate.of(2022, 01, 29))
+ .proveedor(Proveedor.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
+ .comprobante(VoidedDocumentsItem.builder()
+ .serie("P001")
+ .numero(1)
+ .tipoComprobante(Catalog1.PERCEPCION.getCode())
+ .descripcionSustento("Anulacion de percepcion por error en emision")
+ .build())
+ .comprobante(VoidedDocumentsItem.builder()
+ .serie("P001")
+ .numero(2)
+ .tipoComprobante(Catalog1.PERCEPCION.getCode())
+ .descripcionSustento("Anulacion de percepcion por duplicado")
+ .build())
+ .build();
+
+ assertInputReversion(input, "reversion.xml");
+ }
+
+ @Test
+ public void testReversionWithRetentions() throws Exception {
+ // Given - Reverting retentions (type 20)
+ Reversion input = Reversion.builder()
+ .numero(2)
+ .fechaEmision(LocalDate.of(2022, 01, 31))
+ .fechaEmisionComprobantes(LocalDate.of(2022, 01, 29))
+ .proveedor(Proveedor.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
+ .comprobante(VoidedDocumentsItem.builder()
+ .serie("R001")
+ .numero(1)
+ .tipoComprobante(Catalog1.RETENCION.getCode())
+ .descripcionSustento("Anulacion de retencion por error en calculo")
+ .build())
+ .build();
+
+ assertInputReversion(input, "reversion_retention.xml");
+ }
+}
diff --git a/xbuilder/core/src/test/resources/e2e/renderer/despatchadvice/DespatchAdviceCarrierTest/carrierData.xml b/xbuilder/core/src/test/resources/e2e/renderer/despatchadvice/DespatchAdviceCarrierTest/carrierData.xml
new file mode 100644
index 00000000..5bdcab82
--- /dev/null
+++ b/xbuilder/core/src/test/resources/e2e/renderer/despatchadvice/DespatchAdviceCarrierTest/carrierData.xml
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+ 2.1
+ 2.1
+ V001-1
+ 2019-12-24
+ 31
+
+ 20123456789
+
+
+ 20123456789
+
+
+
+
+
+
+
+ #PROJECT-OPENUBL-SIGN
+
+
+
+
+ 20123456789
+
+
+ 20123456789
+
+
+
+ MTC-654321
+
+
+
+
+
+
+ 20876543210
+
+
+
+
+
+
+
+
+
+ 20555555555
+
+
+
+
+
+
+
+ SUNAT_Envio
+ 01
+ 500.000
+
+ 01
+
+ 2019-12-24
+
+
+ 44444444
+ Carlos
+ Guerrero
+
+ L5555555
+
+
+
+
+
+ 150102
+
+ Tienda Centro
+
+
+
+
+ 150101
+
+ Almacen Principal
+
+
+
+
+
+
+ XYZ-789
+
+ TUC-V001
+
+
+
+
+
+ 1
+ 10.00
+
+ 1
+
+
+
+
+ PROD-99
+
+
+
+
diff --git a/xbuilder/core/src/test/resources/e2e/renderer/despatchadvice/DespatchAdviceComplexTest/complexData.xml b/xbuilder/core/src/test/resources/e2e/renderer/despatchadvice/DespatchAdviceComplexTest/complexData.xml
new file mode 100644
index 00000000..4bfd1add
--- /dev/null
+++ b/xbuilder/core/src/test/resources/e2e/renderer/despatchadvice/DespatchAdviceComplexTest/complexData.xml
@@ -0,0 +1,179 @@
+
+
+
+
+
+
+
+ 2.1
+ 2.1
+ T001-100
+ 2019-12-24
+ 09
+
+ T001-1
+ 09
+ GUIA REMISION
+
+
+ 20100010001
+
+
+
+
+ 12345678912
+
+
+ 12345678912
+
+
+
+
+
+
+
+ #PROJECT-OPENUBL-SIGN
+
+
+
+
+ 12345678912
+
+
+ 12345678912
+
+
+
+
+
+
+
+
+
+ 12345678
+
+
+
+
+
+
+
+
+
+ 12345678
+
+
+
+
+
+
+
+ SUNAT_Envio
+ 01
+ Empaque madera
+ 100.500
+ 90.000
+ 10
+
+ 01
+
+ 2019-12-24
+
+
+ 11111111
+ Juan
+ Perez
+ CONDUCTOR_PRINCIPAL
+
+ Q1234567
+
+
+
+ 22222222
+ Jose
+ Gomez
+ COPILOTO
+
+
+
+
+ 020202
+ 0002
+
+ Av. Destino 456
+
+
+
+
+ 010101
+ 0001
+
+ Av. Origen 123
+
+
+
+
+
+
+ 1
+ CONT-001
+
+
+
+
+ 2
+ CONT-002
+
+
+
+
+ ABC-123
+
+ TUC-001
+
+
+ CAR-456
+
+ TUC-SEC
+
+
+
+ AUTH-001
+
+
+
+
+ CALLAO
+ 1
+ Puerto del Callao
+
+
+
+ 1
+ 5.00
+
+ 1
+
+
+
+
+ ITEM-01
+
+
+ Color
+ 1001
+ Rojo
+
+
+ Marca
+ 1002
+ ToolMaster
+
+
+
+
diff --git a/xbuilder/core/src/test/resources/e2e/renderer/despatchadvice/DespatchAdviceTest/minData.xml b/xbuilder/core/src/test/resources/e2e/renderer/despatchadvice/DespatchAdviceTest/minData.xml
index 30aab7f8..e82a1f7c 100644
--- a/xbuilder/core/src/test/resources/e2e/renderer/despatchadvice/DespatchAdviceTest/minData.xml
+++ b/xbuilder/core/src/test/resources/e2e/renderer/despatchadvice/DespatchAdviceTest/minData.xml
@@ -14,7 +14,7 @@
2.0
T001-1
2019-12-24
- 09
+ 09
12345678912
@@ -53,10 +53,9 @@
- 1
+ SUNAT_Envio
18
1.000
- false
02
@@ -70,11 +69,15 @@
DireccionDestino
+
+
+ 010101
+
+ DireccionOrigen
+
+
+
-
- 010101
- DireccionOrigen
-
1
diff --git a/xbuilder/core/src/test/resources/e2e/renderer/reversion/ReversionTest/reversion.xml b/xbuilder/core/src/test/resources/e2e/renderer/reversion/ReversionTest/reversion.xml
new file mode 100644
index 00000000..65ab4987
--- /dev/null
+++ b/xbuilder/core/src/test/resources/e2e/renderer/reversion/ReversionTest/reversion.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+ 2.0
+ 1.0
+ RR-20220131-1
+ 2022-01-29
+ 2022-01-31
+
+ 12345678912
+
+
+ 12345678912
+
+
+
+
+
+
+
+ #PROJECT-OPENUBL-SIGN
+
+
+
+
+ 12345678912
+ 6
+
+
+
+
+
+
+
+ 1
+ 40
+ P001
+ 1
+ Anulacion de percepcion por error en emision
+
+
+ 2
+ 40
+ P001
+ 2
+ Anulacion de percepcion por duplicado
+
+
diff --git a/xbuilder/core/src/test/resources/e2e/renderer/reversion/ReversionTest/reversion_retention.xml b/xbuilder/core/src/test/resources/e2e/renderer/reversion/ReversionTest/reversion_retention.xml
new file mode 100644
index 00000000..0464120a
--- /dev/null
+++ b/xbuilder/core/src/test/resources/e2e/renderer/reversion/ReversionTest/reversion_retention.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+ 2.0
+ 1.0
+ RR-20220131-2
+ 2022-01-29
+ 2022-01-31
+
+ 12345678912
+
+
+ 12345678912
+
+
+
+
+
+
+
+ #PROJECT-OPENUBL-SIGN
+
+
+
+
+ 12345678912
+ 6
+
+
+
+
+
+
+
+ 1
+ 20
+ R001
+ 1
+ Anulacion de retencion por error en calculo
+
+
diff --git a/xbuilder/pom.xml b/xbuilder/pom.xml
index 25592c3f..08f6c1de 100644
--- a/xbuilder/pom.xml
+++ b/xbuilder/pom.xml
@@ -6,7 +6,7 @@
io.github.project-openubl
xhandler-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
../pom.xml
diff --git a/xbuilder/quarkus-extension/deployment/pom.xml b/xbuilder/quarkus-extension/deployment/pom.xml
index 3ab50eba..69e19aeb 100644
--- a/xbuilder/quarkus-extension/deployment/pom.xml
+++ b/xbuilder/quarkus-extension/deployment/pom.xml
@@ -6,7 +6,7 @@
io.github.project-openubl
quarkus-xbuilder-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
quarkus-xbuilder-deployment
Quarkus Xbuilder - Deployment
diff --git a/xbuilder/quarkus-extension/deployment/src/main/java/io/github/project/openubl/quarkus/xbuilder/deployment/QuarkusXbuilderProcessor.java b/xbuilder/quarkus-extension/deployment/src/main/java/io/github/project/openubl/quarkus/xbuilder/deployment/QuarkusXbuilderProcessor.java
index b8dab8fb..32efa317 100644
--- a/xbuilder/quarkus-extension/deployment/src/main/java/io/github/project/openubl/quarkus/xbuilder/deployment/QuarkusXbuilderProcessor.java
+++ b/xbuilder/quarkus-extension/deployment/src/main/java/io/github/project/openubl/quarkus/xbuilder/deployment/QuarkusXbuilderProcessor.java
@@ -69,10 +69,8 @@ void registerTemplates(BuildProducer resource) thr
"templates/ubl/sunat/include/supplier.xml",
"templates/ubl/sunat/include/agent-party.xml",
- "templates/ubl/sunat/include/receiver-party.xml"
- )
- );
- // resource.produce(new NativeImageResourceDirectoryBuildItem("templates"));
+ "templates/ubl/sunat/include/receiver-party.xml"));
+ // resource.produce(new NativeImageResourceDirectoryBuildItem("templates"));
}
@BuildStep
@@ -82,14 +80,12 @@ void registerServices(BuildProducer services) throws I
// find out all the implementation classes listed in the service files
Set implementations = ServiceUtil.classNamesNamedIn(
Thread.currentThread().getContextClassLoader(),
- service
- );
+ service);
// register every listed implementation class so they can be instantiated
// in native-image at run-time
services.produce(
- new ServiceProviderBuildItem(RuleFactory.class.getName(), implementations.toArray(new String[0]))
- );
+ new ServiceProviderBuildItem(RuleFactory.class.getName(), implementations.toArray(new String[0])));
}
@BuildStep
@@ -103,8 +99,7 @@ ReflectiveClassBuildItem reflectionModelsLombok() {
"io.github.project.openubl.xbuilder.content.models.sunat.resumen.SummaryDocuments$SummaryDocumentsBuilderImpl",
"io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.Perception$PerceptionBuilderImpl",
- "io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.Retention$RetentionBuilderImpl"
- );
+ "io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.Retention$RetentionBuilderImpl");
}
@BuildStep
@@ -215,8 +210,7 @@ ReflectiveClassBuildItem reflectionJaxbLombok() {
"io.github.project.openubl.xbuilder.content.jaxb.models.XMLSupplierSunat$Party",
"io.github.project.openubl.xbuilder.content.jaxb.models.XMLSupplierSunat$PartyLegalEntity",
- "io.github.project.openubl.xbuilder.content.jaxb.models.XMLSupplierSunat$PartyName"
- );
+ "io.github.project.openubl.xbuilder.content.jaxb.models.XMLSupplierSunat$PartyName");
}
@BuildStep
@@ -300,6 +294,18 @@ ReflectiveClassBuildItem reflectionModels() {
io.github.project.openubl.xbuilder.content.models.standard.guia.Remitente.RemitenteBuilder.class,
io.github.project.openubl.xbuilder.content.models.standard.guia.Transportista.class,
io.github.project.openubl.xbuilder.content.models.standard.guia.Transportista.TransportistaBuilder.class,
+ io.github.project.openubl.xbuilder.content.models.standard.guia.Driver.class,
+ io.github.project.openubl.xbuilder.content.models.standard.guia.Driver.DriverBuilder.class,
+ io.github.project.openubl.xbuilder.content.models.standard.guia.Vehicle.class,
+ io.github.project.openubl.xbuilder.content.models.standard.guia.Vehicle.VehicleBuilder.class,
+ io.github.project.openubl.xbuilder.content.models.standard.guia.Puerto.class,
+ io.github.project.openubl.xbuilder.content.models.standard.guia.Puerto.PuertoBuilder.class,
+ io.github.project.openubl.xbuilder.content.models.standard.guia.DocumentoAdicional.class,
+ io.github.project.openubl.xbuilder.content.models.standard.guia.DocumentoAdicional.DocumentoAdicionalBuilder.class,
+ io.github.project.openubl.xbuilder.content.models.standard.guia.Tercero.class,
+ io.github.project.openubl.xbuilder.content.models.standard.guia.Tercero.TerceroBuilder.class,
+ io.github.project.openubl.xbuilder.content.models.standard.guia.Comprador.class,
+ io.github.project.openubl.xbuilder.content.models.standard.guia.Comprador.CompradorBuilder.class,
io.github.project.openubl.xbuilder.content.catalogs.Catalog.class,
io.github.project.openubl.xbuilder.content.catalogs.CatalogContadoCredito.class,
@@ -363,8 +369,7 @@ ReflectiveClassBuildItem reflectionModels() {
io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.ComprobanteAfectado.class,
io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.ComprobanteAfectado.ComprobanteAfectadoBuilder.class,
io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.PercepcionRetencionOperacion.class,
- io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.PercepcionRetencionOperacion.PercepcionRetencionOperacionBuilder.class
- );
+ io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.PercepcionRetencionOperacion.PercepcionRetencionOperacionBuilder.class);
}
@BuildStep
@@ -425,8 +430,7 @@ ReflectiveClassBuildItem reflectionJaxb() {
io.github.project.openubl.xbuilder.content.jaxb.models.XMLSupplier.class,
io.github.project.openubl.xbuilder.content.jaxb.models.XMLSupplierSunat.class,
io.github.project.openubl.xbuilder.content.jaxb.models.XMLVoidedDocuments.class,
- io.github.project.openubl.xbuilder.content.jaxb.models.XMLVoidedDocumentsLine.class
- );
+ io.github.project.openubl.xbuilder.content.jaxb.models.XMLVoidedDocumentsLine.class);
}
@BuildStep
@@ -446,8 +450,7 @@ ReflectiveClassBuildItem mapstruct() {
"io.github.project.openubl.xbuilder.content.jaxb.mappers.PerceptionMapperImpl",
"io.github.project.openubl.xbuilder.content.jaxb.mappers.RetentionMapperImpl",
"io.github.project.openubl.xbuilder.content.jaxb.mappers.SummaryDocumentsMapperImpl",
- "io.github.project.openubl.xbuilder.content.jaxb.mappers.VoidedDocumentsMapperImpl"
- );
+ "io.github.project.openubl.xbuilder.content.jaxb.mappers.VoidedDocumentsMapperImpl");
}
@BuildStep
@@ -458,7 +461,8 @@ void jaxbRegisterClassesToBeBound(BuildProducer c
classesToBeBound.add(io.github.project.openubl.xbuilder.content.jaxb.models.XMLDebitNote.class.getName());
classesToBeBound.add(io.github.project.openubl.xbuilder.content.jaxb.models.XMLDespatchAdvice.class.getName());
classesToBeBound.add(io.github.project.openubl.xbuilder.content.jaxb.models.XMLVoidedDocuments.class.getName());
- classesToBeBound.add(io.github.project.openubl.xbuilder.content.jaxb.models.XMLSummaryDocuments.class.getName());
+ classesToBeBound
+ .add(io.github.project.openubl.xbuilder.content.jaxb.models.XMLSummaryDocuments.class.getName());
classesToBeBound.add(io.github.project.openubl.xbuilder.content.jaxb.models.XMLPercepcion.class.getName());
classesToBeBound.add(io.github.project.openubl.xbuilder.content.jaxb.models.XMLRetention.class.getName());
diff --git a/xbuilder/quarkus-extension/integration-tests/pom.xml b/xbuilder/quarkus-extension/integration-tests/pom.xml
index 7cff5e83..c2e71ebc 100644
--- a/xbuilder/quarkus-extension/integration-tests/pom.xml
+++ b/xbuilder/quarkus-extension/integration-tests/pom.xml
@@ -6,7 +6,7 @@
io.github.project-openubl
quarkus-xbuilder-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
quarkus-xbuilder-integration-tests
Quarkus Xbuilder - Integration Tests
diff --git a/xbuilder/quarkus-extension/integration-tests/src/main/java/io/github/project/openubl/quarkus/xbuilder/it/QuarkusXbuilderResource.java b/xbuilder/quarkus-extension/integration-tests/src/main/java/io/github/project/openubl/quarkus/xbuilder/it/QuarkusXbuilderResource.java
index a8a46046..7b942c05 100644
--- a/xbuilder/quarkus-extension/integration-tests/src/main/java/io/github/project/openubl/quarkus/xbuilder/it/QuarkusXbuilderResource.java
+++ b/xbuilder/quarkus-extension/integration-tests/src/main/java/io/github/project/openubl/quarkus/xbuilder/it/QuarkusXbuilderResource.java
@@ -22,6 +22,7 @@
import io.github.project.openubl.xbuilder.content.models.standard.general.Invoice;
import io.github.project.openubl.xbuilder.content.models.standard.guia.DespatchAdvice;
import io.github.project.openubl.xbuilder.content.models.sunat.baja.VoidedDocuments;
+import io.github.project.openubl.xbuilder.content.models.sunat.baja.Reversion;
import io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.Perception;
import io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.Retention;
import io.github.project.openubl.xbuilder.content.models.sunat.resumen.SummaryDocuments;
@@ -42,8 +43,6 @@
import jakarta.xml.bind.Unmarshaller;
import java.io.IOException;
import java.io.StringReader;
-import java.nio.file.Files;
-import java.nio.file.Paths;
import java.time.LocalDate;
import static io.github.project.openubl.quarkus.xbuilder.XBuilder.Type.CREDIT_NOTE;
@@ -54,6 +53,7 @@
import static io.github.project.openubl.quarkus.xbuilder.XBuilder.Type.RETENTION;
import static io.github.project.openubl.quarkus.xbuilder.XBuilder.Type.SUMMARY_DOCUMENTS;
import static io.github.project.openubl.quarkus.xbuilder.XBuilder.Type.VOIDED_DOCUMENTS;
+import static io.github.project.openubl.quarkus.xbuilder.XBuilder.Type.REVERSION;
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
@@ -71,7 +71,8 @@ public class QuarkusXbuilderResource {
private static final CreditNoteMapper creditNoteMapper = Mappers.getMapper(CreditNoteMapper.class);
private static final DebitNoteMapper debitNoteMapper = Mappers.getMapper(DebitNoteMapper.class);
private static final VoidedDocumentsMapper voidedDocumentsMapper = Mappers.getMapper(VoidedDocumentsMapper.class);
- private static final SummaryDocumentsMapper summaryDocumentsMapper = Mappers.getMapper(SummaryDocumentsMapper.class);
+ private static final SummaryDocumentsMapper summaryDocumentsMapper = Mappers
+ .getMapper(SummaryDocumentsMapper.class);
private static final PerceptionMapper perceptionMapper = Mappers.getMapper(PerceptionMapper.class);
private static final RetentionMapper retentionMapper = Mappers.getMapper(RetentionMapper.class);
private static final DespatchAdviceMapper despatchAdviceMapper = Mappers.getMapper(DespatchAdviceMapper.class);
@@ -291,4 +292,31 @@ public String createDespatchAdviceXml(String xml) {
throw new RuntimeException(e);
}
}
+
+ @POST
+ @Path("Reversion/from-json")
+ public String createReversion(JsonObject json) {
+ Reversion reversion = json.mapTo(Reversion.class);
+
+ ContentEnricher enricher = new ContentEnricher(xBuilder.getDefaults(), () -> LocalDate.of(2022, 1, 25));
+ enricher.enrich(reversion);
+
+ Template template = xBuilder.getTemplate(REVERSION);
+ return template.data(reversion).render();
+ }
+
+ @POST
+ @Consumes(MediaType.TEXT_PLAIN)
+ @Path("Reversion/from-xml")
+ public String createReversionXml(String xml) {
+ Template template = xBuilder.getTemplate(REVERSION);
+
+ try (StringReader reader = new StringReader(xml)) {
+ XMLVoidedDocuments xmlPojo = (XMLVoidedDocuments) unmarshaller.unmarshal(new InputSource(reader));
+ VoidedDocuments inputFromXml = voidedDocumentsMapper.map(xmlPojo);
+ return template.data(inputFromXml).render();
+ } catch (JAXBException e) {
+ throw new RuntimeException(e);
+ }
+ }
}
diff --git a/xbuilder/quarkus-extension/integration-tests/src/test/java/io/github/project/openubl/quarkus/xbuilder/it/QuarkusXbuilderResourceTest.java b/xbuilder/quarkus-extension/integration-tests/src/test/java/io/github/project/openubl/quarkus/xbuilder/it/QuarkusXbuilderResourceTest.java
index 8f71fc6c..6c251524 100644
--- a/xbuilder/quarkus-extension/integration-tests/src/test/java/io/github/project/openubl/quarkus/xbuilder/it/QuarkusXbuilderResourceTest.java
+++ b/xbuilder/quarkus-extension/integration-tests/src/test/java/io/github/project/openubl/quarkus/xbuilder/it/QuarkusXbuilderResourceTest.java
@@ -58,1218 +58,1547 @@
@QuarkusTest
public class QuarkusXbuilderResourceTest {
- public YAMLMapper getYamlMapper() {
- YAMLMapper mapper = new YAMLMapper(new YAMLFactory());
- mapper.registerModule(new JavaTimeModule());
- mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
- mapper.configure(YAMLGenerator.Feature.LITERAL_BLOCK_STYLE, true);
- mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
- return mapper;
- }
+ public YAMLMapper getYamlMapper() {
+ YAMLMapper mapper = new YAMLMapper(new YAMLFactory());
+ mapper.registerModule(new JavaTimeModule());
+ mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+ mapper.configure(YAMLGenerator.Feature.LITERAL_BLOCK_STYLE, true);
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ return mapper;
+ }
- @Test
- public void testAllYamlFilesFromSnapshot() throws URISyntaxException, IOException {
- YAMLMapper yamlMapper = getYamlMapper();
+ @Test
+ public void testAllYamlFilesFromSnapshot() throws URISyntaxException, IOException {
+ YAMLMapper yamlMapper = getYamlMapper();
- URL url = getClass().getClassLoader().getResource("e2e");
- Path path = Paths.get(url.toURI());
- Files.walk(path, 5)
- .filter(p -> !p.toFile().isDirectory())
- .forEach(p -> {
- try {
- Map jsonObject = yamlMapper.readValue(p.toFile(), Map.class);
- String kind = (String) jsonObject.get("kind");
- String snapshot = (String) jsonObject.get("snapshot");
- Map input = (Map) jsonObject.get("input");
+ URL url = getClass().getClassLoader().getResource("e2e");
+ Path path = Paths.get(url.toURI());
+ Files.walk(path, 5)
+ .filter(p -> !p.toFile().isDirectory())
+ .forEach(p -> {
+ try {
+ Map jsonObject = yamlMapper.readValue(p.toFile(),
+ Map.class);
+ String kind = (String) jsonObject.get("kind");
+ String snapshot = (String) jsonObject.get("snapshot");
+ Map input = (Map) jsonObject
+ .get("input");
- given()
+ given()
+ .when()
+ .contentType(ContentType.JSON)
+ .body(input)
+ .post("/quarkus-xbuilder/" + kind + "/from-json")
+ .then()
+ .statusCode(200)
+ .body(is(snapshot));
+
+ given()
+ .when()
+ .contentType(ContentType.TEXT)
+ .body(snapshot)
+ .post("/quarkus-xbuilder/" + kind + "/from-xml")
+ .then()
+ .statusCode(200)
+ .body(is(snapshot));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ }
+
+ @Test
+ public void testInvoice() {
+ Invoice invoice = Invoice.builder()
+ .serie("F001")
+ .numero(1)
+ .proveedor(Proveedor.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
+ .cliente(Cliente.builder()
+ .nombre("Carlos Feria")
+ .numeroDocumentoIdentidad("12121212121")
+ .tipoDocumentoIdentidad(Catalog6.RUC.toString())
+ .build())
+ .detalle(DocumentoVentaDetalle.builder()
+ .descripcion("Item1")
+ .cantidad(new BigDecimal("10"))
+ .precio(new BigDecimal("100"))
+ .build())
+ .build();
+
+ given()
.when()
.contentType(ContentType.JSON)
- .body(input)
- .post("/quarkus-xbuilder/" + kind + "/from-json")
+ .body(invoice)
+ .post("/quarkus-xbuilder/Invoice/from-json")
.then()
.statusCode(200)
- .body(is(snapshot));
+ .body(is(
+ "\n" +
+ "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 2.1\n" +
+ " 2.0\n" +
+ " F001-1\n" +
+ " 2022-01-25\n" +
+ " 01\n"
+ +
+ " PEN\n"
+ +
+ " \n" +
+ " 12345678912\n" +
+ " \n" +
+ " \n" +
+ " 12345678912\n" +
+ " \n" +
+ " \n" +
+ " \n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " #PROJECT-OPENUBL-SIGN\n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 12345678912\n"
+ +
+ " \n" +
+ " \n" +
+ " \n"
+ +
+ " \n" +
+ " 0000\n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 12121212121\n"
+ +
+ " \n" +
+ " \n" +
+ " \n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " FormaPago\n" +
+ " Contado\n"
+ +
+ " \n" +
+ " \n" +
+ " 200.00\n"
+ +
+ " \n" +
+ " 1000.00\n"
+ +
+ " 200.00\n"
+ +
+ " \n" +
+ " S\n"
+ +
+ " \n" +
+ " 1000\n"
+ +
+ " IGV\n" +
+ " VAT\n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 1000.00\n"
+ +
+ " 1200.00\n"
+ +
+ " 0\n"
+ +
+ " 0\n"
+ +
+ " 1200.00\n"
+ +
+ " \n" +
+ " \n" +
+ " 1\n" +
+ " 10\n"
+ +
+ " 1000.00\n"
+ +
+ " \n" +
+ " \n" +
+ " 120.00\n"
+ +
+ " 01\n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 200.00\n"
+ +
+ " \n" +
+ " 1000.00\n"
+ +
+ " 200.00\n"
+ +
+ " \n" +
+ " S\n"
+ +
+ " 20.00\n"
+ +
+ " 10\n"
+ +
+ " \n" +
+ " 1000\n"
+ +
+ " IGV\n" +
+ " VAT\n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n"
+ +
+ " \n" +
+ " \n" +
+ " 100.00\n"
+ +
+ " \n" +
+ " \n" +
+ "\n"));
+ }
+
+ @Test
+ public void testCreditNote() {
+ CreditNote creditNote = CreditNote.builder()
+ .serie("FC01")
+ .numero(1)
+ .comprobanteAfectadoSerieNumero("F001-1")
+ .sustentoDescripcion("mi sustento")
+ .proveedor(Proveedor.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
+ .cliente(Cliente.builder()
+ .nombre("Carlos Feria")
+ .numeroDocumentoIdentidad("12121212121")
+ .tipoDocumentoIdentidad(Catalog6.RUC.toString())
+ .build())
+ .detalle(DocumentoVentaDetalle.builder()
+ .descripcion("Item1")
+ .cantidad(new BigDecimal("10"))
+ .precio(new BigDecimal("100"))
+ .build())
+ .build();
- given()
+ given()
.when()
- .contentType(ContentType.TEXT)
- .body(snapshot)
- .post("/quarkus-xbuilder/" + kind + "/from-xml")
+ .contentType(ContentType.JSON)
+ .body(creditNote)
+ .post("/quarkus-xbuilder/CreditNote/from-json")
.then()
.statusCode(200)
- .body(is(snapshot));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- });
- }
-
- @Test
- public void testInvoice() {
- Invoice invoice = Invoice.builder()
- .serie("F001")
- .numero(1)
- .proveedor(Proveedor.builder()
- .ruc("12345678912")
- .razonSocial("Softgreen S.A.C.")
- .build()
- )
- .cliente(Cliente.builder()
- .nombre("Carlos Feria")
- .numeroDocumentoIdentidad("12121212121")
- .tipoDocumentoIdentidad(Catalog6.RUC.toString())
- .build()
- )
- .detalle(DocumentoVentaDetalle.builder()
- .descripcion("Item1")
- .cantidad(new BigDecimal("10"))
- .precio(new BigDecimal("100"))
- .build()
- )
- .build();
-
- given()
- .when()
- .contentType(ContentType.JSON)
- .body(invoice)
- .post("/quarkus-xbuilder/Invoice/from-json")
- .then()
- .statusCode(200)
- .body(is(
- "\n" +
- "\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 2.1\n" +
- " 2.0\n" +
- " F001-1\n" +
- " 2022-01-25\n" +
- " 01\n" +
- " PEN\n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " #PROJECT-OPENUBL-SIGN\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 0000\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 12121212121\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " FormaPago\n" +
- " Contado\n" +
- " \n" +
- " \n" +
- " 200.00\n" +
- " \n" +
- " 1000.00\n" +
- " 200.00\n" +
- " \n" +
- " S\n" +
- " \n" +
- " 1000\n" +
- " IGV\n" +
- " VAT\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 1000.00\n" +
- " 1200.00\n" +
- " 0\n" +
- " 0\n" +
- " 1200.00\n" +
- " \n" +
- " \n" +
- " 1\n" +
- " 10\n" +
- " 1000.00\n" +
- " \n" +
- " \n" +
- " 120.00\n" +
- " 01\n" +
- " \n" +
- " \n" +
- " \n" +
- " 200.00\n" +
- " \n" +
- " 1000.00\n" +
- " 200.00\n" +
- " \n" +
- " S\n" +
- " 20.00\n" +
- " 10\n" +
- " \n" +
- " 1000\n" +
- " IGV\n" +
- " VAT\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 100.00\n" +
- " \n" +
- " \n" +
- "\n"
- )
- );
- }
+ .body(is(
+ "\n" +
+ "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 2.1\n" +
+ " 2.0\n" +
+ " FC01-1\n" +
+ " 2022-01-25\n" +
+ " PEN\n"
+ +
+ " \n" +
+ " F001-1\n" +
+ " 01\n" +
+ " \n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " F001-1\n" +
+ " 01\n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 12345678912\n" +
+ " \n" +
+ " \n" +
+ " 12345678912\n" +
+ " \n" +
+ " \n" +
+ " \n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " #PROJECT-OPENUBL-SIGN\n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 12345678912\n"
+ +
+ " \n" +
+ " \n" +
+ " \n"
+ +
+ " \n" +
+ " 0000\n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 12121212121\n"
+ +
+ " \n" +
+ " \n" +
+ " \n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 200.00\n"
+ +
+ " \n" +
+ " 1000.00\n"
+ +
+ " 200.00\n"
+ +
+ " \n" +
+ " S\n"
+ +
+ " \n" +
+ " 1000\n"
+ +
+ " IGV\n" +
+ " VAT\n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 1000.00\n"
+ +
+ " 1200.00\n"
+ +
+ " 1200.00\n"
+ +
+ " \n" +
+ " \n" +
+ " 1\n" +
+ " 10\n"
+ +
+ " 1000.00\n"
+ +
+ " \n" +
+ " \n" +
+ " 120.00\n"
+ +
+ " 01\n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 200.00\n"
+ +
+ " \n" +
+ " 1000.00\n"
+ +
+ " 200.00\n"
+ +
+ " \n" +
+ " S\n"
+ +
+ " 20.00\n"
+ +
+ " 10\n"
+ +
+ " \n" +
+ " 1000\n"
+ +
+ " IGV\n" +
+ " VAT\n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n"
+ +
+ " \n" +
+ " \n" +
+ " 100.00\n"
+ +
+ " \n" +
+ " \n" +
+ "\n"));
+ }
- @Test
- public void testCreditNote() {
- CreditNote creditNote = CreditNote.builder()
- .serie("FC01")
- .numero(1)
- .comprobanteAfectadoSerieNumero("F001-1")
- .sustentoDescripcion("mi sustento")
- .proveedor(Proveedor.builder()
- .ruc("12345678912")
- .razonSocial("Softgreen S.A.C.")
- .build()
- )
- .cliente(Cliente.builder()
- .nombre("Carlos Feria")
- .numeroDocumentoIdentidad("12121212121")
- .tipoDocumentoIdentidad(Catalog6.RUC.toString())
- .build()
- )
- .detalle(DocumentoVentaDetalle.builder()
- .descripcion("Item1")
- .cantidad(new BigDecimal("10"))
- .precio(new BigDecimal("100"))
- .build()
- )
- .build();
+ @Test
+ public void testDebitNote() {
+ DebitNote debitNote = DebitNote.builder()
+ .serie("FD01")
+ .numero(1)
+ .comprobanteAfectadoSerieNumero("F001-1")
+ .sustentoDescripcion("mi sustento")
+ .proveedor(Proveedor.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
+ .cliente(Cliente.builder()
+ .nombre("Carlos Feria")
+ .numeroDocumentoIdentidad("12121212121")
+ .tipoDocumentoIdentidad(Catalog6.RUC.toString())
+ .build())
+ .detalle(DocumentoVentaDetalle.builder()
+ .descripcion("Item1")
+ .cantidad(new BigDecimal("10"))
+ .precio(new BigDecimal("100"))
+ .build())
+ .build();
- given()
- .when()
- .contentType(ContentType.JSON)
- .body(creditNote)
- .post("/quarkus-xbuilder/CreditNote/from-json")
- .then()
- .statusCode(200)
- .body(is(
- "\n" +
- "\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 2.1\n" +
- " 2.0\n" +
- " FC01-1\n" +
- " 2022-01-25\n" +
- " PEN\n" +
- " \n" +
- " F001-1\n" +
- " 01\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " F001-1\n" +
- " 01\n" +
- " \n" +
- " \n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " #PROJECT-OPENUBL-SIGN\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 0000\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 12121212121\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 200.00\n" +
- " \n" +
- " 1000.00\n" +
- " 200.00\n" +
- " \n" +
- " S\n" +
- " \n" +
- " 1000\n" +
- " IGV\n" +
- " VAT\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 1000.00\n" +
- " 1200.00\n" +
- " 1200.00\n" +
- " \n" +
- " \n" +
- " 1\n" +
- " 10\n" +
- " 1000.00\n" +
- " \n" +
- " \n" +
- " 120.00\n" +
- " 01\n" +
- " \n" +
- " \n" +
- " \n" +
- " 200.00\n" +
- " \n" +
- " 1000.00\n" +
- " 200.00\n" +
- " \n" +
- " S\n" +
- " 20.00\n" +
- " 10\n" +
- " \n" +
- " 1000\n" +
- " IGV\n" +
- " VAT\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 100.00\n" +
- " \n" +
- " \n" +
- "\n"
- )
- );
- }
+ given()
+ .when()
+ .contentType(ContentType.JSON)
+ .body(debitNote)
+ .post("/quarkus-xbuilder/DebitNote/from-json")
+ .then()
+ .statusCode(200)
+ .body(is(
+ "\n" +
+ "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 2.1\n" +
+ " 2.0\n" +
+ " FD01-1\n" +
+ " 2022-01-25\n" +
+ " PEN\n"
+ +
+ " \n" +
+ " F001-1\n" +
+ " 01\n" +
+ " \n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " F001-1\n" +
+ " 01\n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 12345678912\n" +
+ " \n" +
+ " \n" +
+ " 12345678912\n" +
+ " \n" +
+ " \n" +
+ " \n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " #PROJECT-OPENUBL-SIGN\n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 12345678912\n"
+ +
+ " \n" +
+ " \n" +
+ " \n"
+ +
+ " \n" +
+ " 0000\n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 12121212121\n"
+ +
+ " \n" +
+ " \n" +
+ " \n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 200.00\n"
+ +
+ " \n" +
+ " 1000.00\n"
+ +
+ " 200.00\n"
+ +
+ " \n" +
+ " S\n"
+ +
+ " \n" +
+ " 1000\n"
+ +
+ " IGV\n" +
+ " VAT\n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 1000.00\n"
+ +
+ " 1200.00\n"
+ +
+ " 1200.00\n"
+ +
+ " \n" +
+ " \n" +
+ " 1\n" +
+ " 10\n"
+ +
+ " 1000.00\n"
+ +
+ " \n" +
+ " \n" +
+ " 120.00\n"
+ +
+ " 01\n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 200.00\n"
+ +
+ " \n" +
+ " 1000.00\n"
+ +
+ " 200.00\n"
+ +
+ " \n" +
+ " S\n"
+ +
+ " 20.00\n"
+ +
+ " 10\n"
+ +
+ " \n" +
+ " 1000\n"
+ +
+ " IGV\n" +
+ " VAT\n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n"
+ +
+ " \n" +
+ " \n" +
+ " 100.00\n"
+ +
+ " \n" +
+ " \n" +
+ "\n"));
+ }
- @Test
- public void testDebitNote() {
- DebitNote debitNote = DebitNote.builder()
- .serie("FD01")
- .numero(1)
- .comprobanteAfectadoSerieNumero("F001-1")
- .sustentoDescripcion("mi sustento")
- .proveedor(Proveedor.builder()
- .ruc("12345678912")
- .razonSocial("Softgreen S.A.C.")
- .build()
- )
- .cliente(Cliente.builder()
- .nombre("Carlos Feria")
- .numeroDocumentoIdentidad("12121212121")
- .tipoDocumentoIdentidad(Catalog6.RUC.toString())
- .build()
- )
- .detalle(DocumentoVentaDetalle.builder()
- .descripcion("Item1")
- .cantidad(new BigDecimal("10"))
- .precio(new BigDecimal("100"))
- .build()
- )
- .build();
+ @Test
+ public void testVoidedDocuments() {
+ VoidedDocuments voidedDocuments = VoidedDocuments.builder()
+ .numero(1)
+ .fechaEmision(LocalDate.of(2022, 01, 31))
+ .fechaEmisionComprobantes(LocalDate.of(2022, 01, 29))
+ .proveedor(Proveedor.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
+ .comprobante(VoidedDocumentsItem.builder()
+ .serie("F001")
+ .numero(1)
+ .tipoComprobante(Catalog1_Invoice.FACTURA.getCode())
+ .descripcionSustento("Mi sustento1")
+ .build())
+ .comprobante(VoidedDocumentsItem.builder()
+ .serie("F001")
+ .numero(2)
+ .tipoComprobante(Catalog1_Invoice.FACTURA.getCode())
+ .descripcionSustento("Mi sustento2")
+ .build())
+ .build();
- given()
- .when()
- .contentType(ContentType.JSON)
- .body(debitNote)
- .post("/quarkus-xbuilder/DebitNote/from-json")
- .then()
- .statusCode(200)
- .body(is(
- "\n" +
- "\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 2.1\n" +
- " 2.0\n" +
- " FD01-1\n" +
- " 2022-01-25\n" +
- " PEN\n" +
- " \n" +
- " F001-1\n" +
- " 01\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " F001-1\n" +
- " 01\n" +
- " \n" +
- " \n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " #PROJECT-OPENUBL-SIGN\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 0000\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 12121212121\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 200.00\n" +
- " \n" +
- " 1000.00\n" +
- " 200.00\n" +
- " \n" +
- " S\n" +
- " \n" +
- " 1000\n" +
- " IGV\n" +
- " VAT\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 1000.00\n" +
- " 1200.00\n" +
- " 1200.00\n" +
- " \n" +
- " \n" +
- " 1\n" +
- " 10\n" +
- " 1000.00\n" +
- " \n" +
- " \n" +
- " 120.00\n" +
- " 01\n" +
- " \n" +
- " \n" +
- " \n" +
- " 200.00\n" +
- " \n" +
- " 1000.00\n" +
- " 200.00\n" +
- " \n" +
- " S\n" +
- " 20.00\n" +
- " 10\n" +
- " \n" +
- " 1000\n" +
- " IGV\n" +
- " VAT\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 100.00\n" +
- " \n" +
- " \n" +
- "\n"
- )
- );
- }
+ given()
+ .when()
+ .contentType(ContentType.JSON)
+ .body(voidedDocuments)
+ .post("/quarkus-xbuilder/VoidedDocuments/from-json")
+ .then()
+ .statusCode(200)
+ .body(is("\n" +
+ "\n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 2.0\n" +
+ " 1.0\n" +
+ " RA-20220131-1\n" +
+ " 2022-01-29\n" +
+ " 2022-01-31\n" +
+ " \n" +
+ " 12345678912\n" +
+ " \n" +
+ " \n" +
+ " 12345678912\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " #PROJECT-OPENUBL-SIGN\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 12345678912\n"
+ +
+ " 6\n" +
+ " \n" +
+ " \n" +
+ " \n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 1\n" +
+ " 01\n" +
+ " F001\n" +
+ " 1\n" +
+ " Mi sustento1\n"
+ +
+ " \n" +
+ " \n" +
+ " 2\n" +
+ " 01\n" +
+ " F001\n" +
+ " 2\n" +
+ " Mi sustento2\n"
+ +
+ " \n" +
+ "\n"));
+ }
- @Test
- public void testVoidedDocuments() {
- VoidedDocuments voidedDocuments = VoidedDocuments.builder()
- .numero(1)
- .fechaEmision(LocalDate.of(2022, 01, 31))
- .fechaEmisionComprobantes(LocalDate.of(2022, 01, 29))
- .proveedor(Proveedor.builder()
- .ruc("12345678912")
- .razonSocial("Softgreen S.A.C.")
- .build()
- )
- .comprobante(VoidedDocumentsItem.builder()
- .serie("F001")
- .numero(1)
- .tipoComprobante(Catalog1_Invoice.FACTURA.getCode())
- .descripcionSustento("Mi sustento1")
- .build()
- )
- .comprobante(VoidedDocumentsItem.builder()
- .serie("F001")
- .numero(2)
- .tipoComprobante(Catalog1_Invoice.FACTURA.getCode())
- .descripcionSustento("Mi sustento2")
- .build()
- )
- .build();
+ @Test
+ public void testSummaryDocuments() {
+ SummaryDocuments summaryDocuments = SummaryDocuments.builder()
+ .numero(1)
+ .fechaEmision(LocalDate.of(2022, 01, 31))
+ .fechaEmisionComprobantes(LocalDate.of(2022, 01, 29))
+ .proveedor(Proveedor.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
+ .comprobante(SummaryDocumentsItem.builder()
+ .tipoOperacion(Catalog19.ADICIONAR.toString())
+ .comprobante(Comprobante.builder()
+ .tipoComprobante(Catalog1_Invoice.BOLETA.getCode())//
+ .serieNumero("B001-1")
+ .cliente(Cliente.builder()
+ .nombre("Carlos Feria")
+ .numeroDocumentoIdentidad("12345678")
+ .tipoDocumentoIdentidad(
+ Catalog6.DNI.getCode())
+ .build())
+ .impuestos(ComprobanteImpuestos.builder()
+ .igv(new BigDecimal("18"))
+ .icb(new BigDecimal(2))
+ .build())
+ .valorVenta(ComprobanteValorVenta.builder()
+ .importeTotal(new BigDecimal("120"))
+ .gravado(new BigDecimal("120"))
+ .build())
+ .build())
+ .build())
+ .comprobante(SummaryDocumentsItem.builder()
+ .tipoOperacion(Catalog19.ADICIONAR.toString())
+ .comprobante(Comprobante.builder()
+ .tipoComprobante(Catalog1.NOTA_CREDITO.getCode())
+ .serieNumero("BC02-2")
+ .comprobanteAfectado(ComprobanteAfectado.builder()
+ .serieNumero("B002-2")
+ .tipoComprobante(Catalog1.BOLETA
+ .getCode()) //
+ .build())
+ .cliente(Cliente.builder()
+ .nombre("Carlos Feria")
+ .numeroDocumentoIdentidad("12345678")
+ .tipoDocumentoIdentidad(
+ Catalog6.DNI.getCode())//
+ .build())
+ .impuestos(ComprobanteImpuestos.builder()
+ .igv(new BigDecimal("18"))
+ .build())
+ .valorVenta(ComprobanteValorVenta.builder()
+ .importeTotal(new BigDecimal("118"))
+ .gravado(new BigDecimal("118"))
+ .build())
+ .build())
+ .build())
+ .build();
- given()
- .when()
- .contentType(ContentType.JSON)
- .body(voidedDocuments)
- .post("/quarkus-xbuilder/VoidedDocuments/from-json")
- .then()
- .statusCode(200)
- .body(is("\n" +
- "\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 2.0\n" +
- " 1.0\n" +
- " RA-20220131-1\n" +
- " 2022-01-29\n" +
- " 2022-01-31\n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " #PROJECT-OPENUBL-SIGN\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 12345678912\n" +
- " 6\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 1\n" +
- " 01\n" +
- " F001\n" +
- " 1\n" +
- " Mi sustento1\n" +
- " \n" +
- " \n" +
- " 2\n" +
- " 01\n" +
- " F001\n" +
- " 2\n" +
- " Mi sustento2\n" +
- " \n" +
- "\n"));
- }
+ given()
+ .when()
+ .contentType(ContentType.JSON)
+ .body(summaryDocuments)
+ .post("/quarkus-xbuilder/SummaryDocuments/from-json")
+ .then()
+ .statusCode(200)
+ .body(is("\n" +
+ "\n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 2.0\n" +
+ " 1.1\n" +
+ " RC-20220131-1\n" +
+ " 2022-01-29\n" +
+ " 2022-01-31\n" +
+ " \n" +
+ " 12345678912\n" +
+ " \n" +
+ " \n" +
+ " 12345678912\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " #PROJECT-OPENUBL-SIGN\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 12345678912\n"
+ +
+ " 6\n" +
+ " \n" +
+ " \n" +
+ " \n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 1\n" +
+ " 03\n" +
+ " B001-1\n" +
+ " \n" +
+ " 12345678\n"
+ +
+ " 1\n" +
+ " \n" +
+ " \n" +
+ " 1\n" +
+ " \n" +
+ " 120\n" +
+ " \n" +
+ " 120\n"
+ +
+ " 01\n" +
+ " \n" +
+ " \n" +
+ " 18\n" +
+ " \n" +
+ " 18\n"
+ +
+ " \n" +
+ " \n" +
+ " 1000\n" +
+ " IGV\n" +
+ " VAT\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 2\n" +
+ " \n" +
+ " 2\n"
+ +
+ " \n" +
+ " \n" +
+ " 7152\n" +
+ " ICBPER\n" +
+ " OTH\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 2\n" +
+ " 07\n" +
+ " BC02-2\n" +
+ " \n" +
+ " 12345678\n"
+ +
+ " 1\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " B002-2\n" +
+ " 03\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 1\n" +
+ " \n" +
+ " 118\n" +
+ " \n" +
+ " 118\n"
+ +
+ " 01\n" +
+ " \n" +
+ " \n" +
+ " 18\n" +
+ " \n" +
+ " 18\n"
+ +
+ " \n" +
+ " \n" +
+ " 1000\n" +
+ " IGV\n" +
+ " VAT\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "\n"));
+ }
- @Test
- public void testSummaryDocuments() {
- SummaryDocuments summaryDocuments = SummaryDocuments.builder()
- .numero(1)
- .fechaEmision(LocalDate.of(2022, 01, 31))
- .fechaEmisionComprobantes(LocalDate.of(2022, 01, 29))
- .proveedor(Proveedor.builder()
- .ruc("12345678912")
- .razonSocial("Softgreen S.A.C.")
- .build()
- )
- .comprobante(SummaryDocumentsItem.builder()
- .tipoOperacion(Catalog19.ADICIONAR.toString())
- .comprobante(Comprobante.builder()
- .tipoComprobante(Catalog1_Invoice.BOLETA.getCode())//
- .serieNumero("B001-1")
- .cliente(Cliente.builder()
- .nombre("Carlos Feria")
- .numeroDocumentoIdentidad("12345678")
- .tipoDocumentoIdentidad(Catalog6.DNI.getCode())
- .build()
- )
- .impuestos(ComprobanteImpuestos.builder()
- .igv(new BigDecimal("18"))
- .icb(new BigDecimal(2))
- .build()
- )
- .valorVenta(ComprobanteValorVenta.builder()
- .importeTotal(new BigDecimal("120"))
- .gravado(new BigDecimal("120"))
- .build()
- )
- .build()
- )
- .build()
- )
- .comprobante(SummaryDocumentsItem.builder()
- .tipoOperacion(Catalog19.ADICIONAR.toString())
- .comprobante(Comprobante.builder()
- .tipoComprobante(Catalog1.NOTA_CREDITO.getCode())
- .serieNumero("BC02-2")
- .comprobanteAfectado(ComprobanteAfectado.builder()
- .serieNumero("B002-2")
- .tipoComprobante(Catalog1.BOLETA.getCode()) //
- .build()
- )
+ @Test
+ public void testPerception() {
+ Perception perception = Perception.builder()
+ .serie("P001")
+ .numero(1)
+ .fechaEmision(LocalDate.of(2022, 01, 31))
+ .proveedor(Proveedor.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
.cliente(Cliente.builder()
- .nombre("Carlos Feria")
- .numeroDocumentoIdentidad("12345678")
- .tipoDocumentoIdentidad(Catalog6.DNI.getCode())//
- .build()
- )
- .impuestos(ComprobanteImpuestos.builder()
- .igv(new BigDecimal("18"))
- .build()
- )
- .valorVenta(ComprobanteValorVenta.builder()
- .importeTotal(new BigDecimal("118"))
- .gravado(new BigDecimal("118"))
- .build()
- )
- .build()
- )
- .build()
- )
- .build();
+ .nombre("Carlos Feria")
+ .numeroDocumentoIdentidad("12121212121")
+ .tipoDocumentoIdentidad(Catalog6.RUC.getCode())
+ .build())
+ .importeTotalPercibido(new BigDecimal("10"))
+ .importeTotalCobrado(new BigDecimal("210"))
+ .tipoRegimen(Catalog22.VENTA_INTERNA.getCode())
+ .tipoRegimenPorcentaje(Catalog22.VENTA_INTERNA.getPercent()) //
+ .operacion(PercepcionRetencionOperacion.builder()
+ .numeroOperacion(1)
+ .fechaOperacion(LocalDate.of(2022, 01, 31))
+ .importeOperacion(new BigDecimal("100"))
+ .comprobante(
+ io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.ComprobanteAfectado
+ .builder()
+ .tipoComprobante(Catalog1.FACTURA
+ .getCode())
+ .serieNumero("F001-1")
+ .fechaEmision(LocalDate.of(2022, 01,
+ 31))
+ .importeTotal(new BigDecimal("200"))
+ .moneda("PEN")
+ .build())
+ .build())
+ .build();
- given()
- .when()
- .contentType(ContentType.JSON)
- .body(summaryDocuments)
- .post("/quarkus-xbuilder/SummaryDocuments/from-json")
- .then()
- .statusCode(200)
- .body(is("\n" +
- "\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 2.0\n" +
- " 1.1\n" +
- " RC-20220131-1\n" +
- " 2022-01-29\n" +
- " 2022-01-31\n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " #PROJECT-OPENUBL-SIGN\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 12345678912\n" +
- " 6\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 1\n" +
- " 03\n" +
- " B001-1\n" +
- " \n" +
- " 12345678\n" +
- " 1\n" +
- " \n" +
- " \n" +
- " 1\n" +
- " \n" +
- " 120\n" +
- " \n" +
- " 120\n" +
- " 01\n" +
- " \n" +
- " \n" +
- " 18\n" +
- " \n" +
- " 18\n" +
- " \n" +
- " \n" +
- " 1000\n" +
- " IGV\n" +
- " VAT\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 2\n" +
- " \n" +
- " 2\n" +
- " \n" +
- " \n" +
- " 7152\n" +
- " ICBPER\n" +
- " OTH\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 2\n" +
- " 07\n" +
- " BC02-2\n" +
- " \n" +
- " 12345678\n" +
- " 1\n" +
- " \n" +
- " \n" +
- " \n" +
- " B002-2\n" +
- " 03\n" +
- " \n" +
- " \n" +
- " \n" +
- " 1\n" +
- " \n" +
- " 118\n" +
- " \n" +
- " 118\n" +
- " 01\n" +
- " \n" +
- " \n" +
- " 18\n" +
- " \n" +
- " 18\n" +
- " \n" +
- " \n" +
- " 1000\n" +
- " IGV\n" +
- " VAT\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- "\n"));
- }
+ given()
+ .when()
+ .contentType(ContentType.JSON)
+ .body(perception)
+ .post("/quarkus-xbuilder/Perception/from-json")
+ .then()
+ .statusCode(200)
+ .body(is("\n" +
+ "\n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 2.0\n" +
+ " 1.0\n" +
+ " \n" +
+ " 12345678912\n" +
+ " \n" +
+ " \n" +
+ " 12345678912\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " #PROJECT-OPENUBL-SIGN\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " P001-1\n" +
+ " 2022-01-31\n" +
+ " \n" +
+ " \n" +
+ " 12345678912\n" +
+ " \n" +
+ " \n" +
+ " \n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 12121212121\n" +
+ " \n" +
+ " \n" +
+ " \n"
+ +
+ " \n" +
+ " \n" +
+ " 01\n"
+ +
+ " 2\n" +
+ " 10\n"
+ +
+ " 210\n"
+ +
+ " \n" +
+ " F001-1\n" +
+ " 2022-01-31\n" +
+ " 200\n"
+ +
+ " \n" +
+ " 1\n" +
+ " 100\n"
+ +
+ " 2022-01-31\n" +
+ " \n" +
+ " \n" +
+ " 10\n"
+ +
+ " 2022-01-31\n"
+ +
+ " 210\n"
+ +
+ " \n" +
+ " \n" +
+ "\n"));
+ }
- @Test
- public void testPerception() {
- Perception perception = Perception.builder()
- .serie("P001")
- .numero(1)
- .fechaEmision(LocalDate.of(2022, 01, 31))
- .proveedor(Proveedor.builder()
- .ruc("12345678912")
- .razonSocial("Softgreen S.A.C.")
- .build()
- )
- .cliente(Cliente.builder()
- .nombre("Carlos Feria")
- .numeroDocumentoIdentidad("12121212121")
- .tipoDocumentoIdentidad(Catalog6.RUC.getCode())
- .build()
- )
- .importeTotalPercibido(new BigDecimal("10"))
- .importeTotalCobrado(new BigDecimal("210"))
- .tipoRegimen(Catalog22.VENTA_INTERNA.getCode())
- .tipoRegimenPorcentaje(Catalog22.VENTA_INTERNA.getPercent()) //
- .operacion(PercepcionRetencionOperacion.builder()
- .numeroOperacion(1)
- .fechaOperacion(LocalDate.of(2022, 01, 31))
- .importeOperacion(new BigDecimal("100"))
- .comprobante(io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.ComprobanteAfectado.builder()
- .tipoComprobante(Catalog1.FACTURA.getCode())
- .serieNumero("F001-1")
+ @Test
+ public void testRetention() {
+ Retention retention = Retention.builder()
+ .serie("R001")
+ .numero(1)
.fechaEmision(LocalDate.of(2022, 01, 31))
- .importeTotal(new BigDecimal("200"))
- .moneda("PEN")
- .build()
- )
- .build()
- )
- .build();
+ .proveedor(Proveedor.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
+ .cliente(Cliente.builder()
+ .nombre("Carlos Feria")
+ .numeroDocumentoIdentidad("12121212121")
+ .tipoDocumentoIdentidad(Catalog6.RUC.getCode())
+ .build())
+ .importeTotalRetenido(new BigDecimal("10"))
+ .importeTotalPagado(new BigDecimal("200"))
+ .tipoRegimen(Catalog23.TASA_TRES.getCode())
+ .tipoRegimenPorcentaje(Catalog23.TASA_TRES.getPercent()) //
+ .operacion(PercepcionRetencionOperacion.builder()
+ .numeroOperacion(1)
+ .fechaOperacion(LocalDate.of(2022, 01, 31))
+ .importeOperacion(new BigDecimal("100"))
+ .comprobante(
+ io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.ComprobanteAfectado
+ .builder()
+ .tipoComprobante(Catalog1.FACTURA
+ .getCode())
+ .serieNumero("F001-1")
+ .fechaEmision(LocalDate.of(2022, 01,
+ 31))
+ .importeTotal(new BigDecimal("210"))
+ .moneda("PEN")
+ .build())
+ .build())
+ .build();
- given()
- .when()
- .contentType(ContentType.JSON)
- .body(perception)
- .post("/quarkus-xbuilder/Perception/from-json")
- .then()
- .statusCode(200)
- .body(is("\n" +
- "\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 2.0\n" +
- " 1.0\n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " #PROJECT-OPENUBL-SIGN\n" +
- " \n" +
- " \n" +
- " \n" +
- " P001-1\n" +
- " 2022-01-31\n" +
- " \n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 12121212121\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 01\n" +
- " 2\n" +
- " 10\n" +
- " 210\n" +
- " \n" +
- " F001-1\n" +
- " 2022-01-31\n" +
- " 200\n" +
- " \n" +
- " 1\n" +
- " 100\n" +
- " 2022-01-31\n" +
- " \n" +
- " \n" +
- " 10\n" +
- " 2022-01-31\n" +
- " 210\n" +
- " \n" +
- " \n" +
- "\n"));
- }
+ given()
+ .when()
+ .contentType(ContentType.JSON)
+ .body(retention)
+ .post("/quarkus-xbuilder/Retention/from-json")
+ .then()
+ .statusCode(200)
+ .body(is("\n" +
+ "\n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 2.0\n" +
+ " 1.0\n" +
+ " \n" +
+ " 12345678912\n" +
+ " \n" +
+ " \n" +
+ " 12345678912\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " #PROJECT-OPENUBL-SIGN\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " R001-1\n" +
+ " 2022-01-31\n" +
+ " \n" +
+ " \n" +
+ " 12345678912\n" +
+ " \n" +
+ " \n" +
+ " \n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 12121212121\n" +
+ " \n" +
+ " \n" +
+ " \n"
+ +
+ " \n" +
+ " \n" +
+ " 01\n"
+ +
+ " 3\n" +
+ " 10\n"
+ +
+ " 200\n"
+ +
+ " \n" +
+ " F001-1\n" +
+ " 2022-01-31\n" +
+ " 210\n"
+ +
+ " \n" +
+ " 1\n" +
+ " 100\n"
+ +
+ " 2022-01-31\n" +
+ " \n" +
+ " \n" +
+ " 10\n"
+ +
+ " 2022-01-31\n"
+ +
+ " 200\n"
+ +
+ " \n" +
+ " \n" +
+ "\n"));
+ }
- @Test
- public void testRetention() {
- Retention retention = Retention.builder()
- .serie("R001")
- .numero(1)
- .fechaEmision(LocalDate.of(2022, 01, 31))
- .proveedor(Proveedor.builder()
- .ruc("12345678912")
- .razonSocial("Softgreen S.A.C.")
- .build()
- )
- .cliente(Cliente.builder()
- .nombre("Carlos Feria")
- .numeroDocumentoIdentidad("12121212121")
- .tipoDocumentoIdentidad(Catalog6.RUC.getCode())
- .build()
- )
- .importeTotalRetenido(new BigDecimal("10"))
- .importeTotalPagado(new BigDecimal("200"))
- .tipoRegimen(Catalog23.TASA_TRES.getCode())
- .tipoRegimenPorcentaje(Catalog23.TASA_TRES.getPercent()) //
- .operacion(PercepcionRetencionOperacion.builder()
- .numeroOperacion(1)
- .fechaOperacion(LocalDate.of(2022, 01, 31))
- .importeOperacion(new BigDecimal("100"))
- .comprobante(io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.ComprobanteAfectado.builder()
- .tipoComprobante(Catalog1.FACTURA.getCode())
- .serieNumero("F001-1")
- .fechaEmision(LocalDate.of(2022, 01, 31))
- .importeTotal(new BigDecimal("210"))
- .moneda("PEN")
- .build()
- )
- .build()
- )
- .build();
+ @Test
+ public void testDespatchAdvice() {
+ DespatchAdvice despatchAdvice = DespatchAdvice.builder()
+ .serie("T001")
+ .numero(1)
+ .tipoComprobante(Catalog1.GUIA_REMISION_REMITENTE.getCode())
+ .remitente(Remitente.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
+ .destinatario(Destinatario.builder()
+ .tipoDocumentoIdentidad(Catalog6.DNI.getCode())
+ .numeroDocumentoIdentidad("12345678")
+ .nombre("mi cliente")
+ .build())
+ .envio(Envio.builder()
+ .tipoTraslado(Catalog20.TRASLADO_EMISOR_ITINERANTE_CP.getCode())
+ .pesoTotal(BigDecimal.ONE)
+ .pesoTotalUnidadMedida("KG")
+ .tipoModalidadTraslado(Catalog18.TRANSPORTE_PRIVADO.getCode())
+ .fechaTraslado(LocalDate.of(2022, 1, 25))
+ .partida(Partida.builder()
+ .direccion("DireccionOrigen")
+ .ubigeo("010101")
+ .build())
+ .destino(Destino.builder()
+ .direccion("DireccionDestino")
+ .ubigeo("020202")
+ .build())
+ .build())
+ .detalle(DespatchAdviceItem.builder()
+ .cantidad(new BigDecimal("0.5"))
+ .unidadMedida("KG")
+ .codigo("123456")
+ .build())
+ .build();
- given()
- .when()
- .contentType(ContentType.JSON)
- .body(retention)
- .post("/quarkus-xbuilder/Retention/from-json")
- .then()
- .statusCode(200)
- .body(is("\n" +
- "\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 2.0\n" +
- " 1.0\n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " #PROJECT-OPENUBL-SIGN\n" +
- " \n" +
- " \n" +
- " \n" +
- " R001-1\n" +
- " 2022-01-31\n" +
- " \n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 12121212121\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 01\n" +
- " 3\n" +
- " 10\n" +
- " 200\n" +
- " \n" +
- " F001-1\n" +
- " 2022-01-31\n" +
- " 210\n" +
- " \n" +
- " 1\n" +
- " 100\n" +
- " 2022-01-31\n" +
- " \n" +
- " \n" +
- " 10\n" +
- " 2022-01-31\n" +
- " 200\n" +
- " \n" +
- " \n" +
- "\n"));
- }
+ given()
+ .when()
+ .contentType(ContentType.JSON)
+ .body(despatchAdvice)
+ .post("/quarkus-xbuilder/DespatchAdvice/from-json")
+ .then()
+ .statusCode(200)
+ .body(is("\n" +
+ "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 2.1\n" +
+ " 2.0\n" +
+ " T001-1\n" +
+ " 2022-01-25\n" +
+ " 09\n"
+ +
+ " \n" +
+ " 12345678912\n" +
+ " \n" +
+ " \n" +
+ " 12345678912\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " #PROJECT-OPENUBL-SIGN\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 12345678912\n"
+ +
+ " \n" +
+ " \n" +
+ " 12345678912\n"
+ +
+ " \n" +
+ " \n" +
+ " \n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 12345678\n"
+ +
+ " \n" +
+ " \n" +
+ " \n"
+ +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " SUNAT_Envio\n" +
+ " 18\n"
+ +
+ " 1.000\n"
+ +
+ " \n" +
+ " 02\n"
+ +
+ " \n" +
+ " 2022-01-25\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 020202\n"
+ +
+ " \n" +
+ " DireccionDestino\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 010101\n"
+ +
+ " \n" +
+ " DireccionOrigen\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 1\n" +
+ " 0.5\n"
+ +
+ " \n" +
+ " 1\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 123456\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "\n"));
+ }
- @Test
- public void testDespatchAdvice() {
- DespatchAdvice despatchAdvice = DespatchAdvice.builder()
- .serie("T001")
- .numero(1)
- .tipoComprobante(Catalog1.GUIA_REMISION_REMITENTE.getCode())
- .remitente(Remitente.builder()
- .ruc("12345678912")
- .razonSocial("Softgreen S.A.C.")
- .build()
- )
- .destinatario(Destinatario.builder()
- .tipoDocumentoIdentidad(Catalog6.DNI.getCode())
- .numeroDocumentoIdentidad("12345678")
- .nombre("mi cliente")
- .build()
- )
- .envio(Envio.builder()
- .tipoTraslado(Catalog20.TRASLADO_EMISOR_ITINERANTE_CP.getCode())
- .pesoTotal(BigDecimal.ONE)
- .pesoTotalUnidadMedida("KG")
- .transbordoProgramado(false)
- .tipoModalidadTraslado(Catalog18.TRANSPORTE_PRIVADO.getCode())
- .fechaTraslado(LocalDate.of(2022, 1, 25))
- .partida(Partida.builder()
- .direccion("DireccionOrigen")
- .ubigeo("010101")
- .build()
- )
- .destino(Destino.builder()
- .direccion("DireccionDestino")
- .ubigeo("020202")
- .build()
- )
- .build()
- )
- .detalle(DespatchAdviceItem.builder()
- .cantidad(new BigDecimal("0.5"))
- .unidadMedida("KG")
- .codigo("123456")
- .build()
- )
- .build();
+ @Test
+ public void testDespatchAdvice2() {
+ DespatchAdvice despatchAdvice = DespatchAdvice.builder()
+ .serie("T001")
+ .numero(1)
+ .tipoComprobante(Catalog1.GUIA_REMISION_REMITENTE.getCode())
+ .remitente(Remitente.builder()
+ .ruc("12345678912")
+ .razonSocial("Softgreen S.A.C.")
+ .build())
+ .destinatario(Destinatario.builder()
+ .tipoDocumentoIdentidad(Catalog6.DNI.getCode())
+ .numeroDocumentoIdentidad("12345678")
+ .nombre("mi cliente")
+ .build())
+ .envio(Envio.builder()
+ .tipoTraslado(Catalog20.TRASLADO_EMISOR_ITINERANTE_CP.getCode())
+ .pesoTotal(BigDecimal.ONE)
+ .pesoTotalUnidadMedida("KG")
+ .tipoModalidadTraslado(Catalog18.TRANSPORTE_PRIVADO.getCode())
+ .fechaTraslado(LocalDate.of(2022, 1, 25))
+ .partida(Partida.builder()
+ .direccion("DireccionOrigen")
+ .ubigeo("010101")
+ .build())
+ .destino(Destino.builder()
+ .direccion("DireccionDestino")
+ .ubigeo("020202")
+ .build())
+ .build())
+ .detalle(DespatchAdviceItem.builder()
+ .cantidad(new BigDecimal("0.5"))
+ .unidadMedida("KG")
+ .codigo("123456")
+ .build())
+ .build();
- given()
- .when()
- .contentType(ContentType.JSON)
- .body(despatchAdvice)
- .post("/quarkus-xbuilder/DespatchAdvice/from-json")
- .then()
- .statusCode(200)
- .body(is("\n" +
- "\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 2.1\n" +
- " 2.0\n" +
- " T001-1\n" +
- " 2022-01-25\n" +
- " 09\n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " #PROJECT-OPENUBL-SIGN\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " 12345678912\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 12345678\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 1\n" +
- " 18\n" +
- " 1.000\n" +
- " false\n" +
- " \n" +
- " 02\n" +
- " \n" +
- " 2022-01-25\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 020202\n" +
- " \n" +
- " DireccionDestino\n" +
- " \n" +
- " \n" +
- " \n" +
- " \n" +
- " 010101\n" +
- " DireccionOrigen\n" +
- " \n" +
- " \n" +
- " \n" +
- " 1\n" +
- " 0.5\n" +
- " \n" +
- " 1\n" +
- " \n" +
- " \n" +
- " \n" +
- " 123456\n" +
- " \n" +
- " \n" +
- " \n" +
- "\n"));
- }
+ given()
+ .when()
+ .contentType(ContentType.JSON)
+ .body(despatchAdvice)
+ .post("/quarkus-xbuilder/DespatchAdvice/from-json")
+ .then()
+ .statusCode(200)
+ .body(is(
+ """
+
+
+
+
+
+
+
+ 2.1
+ 2.0
+ T001-1
+ 2022-01-25
+ 09
+
+ 12345678912
+
+
+ 12345678912
+
+
+
+
+
+
+
+ #PROJECT-OPENUBL-SIGN
+
+
+
+
+ 12345678912
+
+
+ 12345678912
+
+
+
+
+
+
+
+
+
+ 12345678
+
+
+
+
+
+
+
+ SUNAT_Envio
+ 18
+ 1.000
+
+ 02
+
+ 2022-01-25
+
+
+
+
+ 020202
+
+ DireccionDestino
+
+
+
+
+ 010101
+
+ DireccionOrigen
+
+
+
+
+
+
+ 1
+ 0.5
+
+ 1
+
+
+
+ 123456
+
+
+
+
+ """));
+ }
}
diff --git a/xbuilder/quarkus-extension/pom.xml b/xbuilder/quarkus-extension/pom.xml
index d7c7def2..d685aa92 100644
--- a/xbuilder/quarkus-extension/pom.xml
+++ b/xbuilder/quarkus-extension/pom.xml
@@ -7,7 +7,7 @@
io.github.project-openubl
xbuilder-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
../pom.xml
diff --git a/xbuilder/quarkus-extension/runtime/pom.xml b/xbuilder/quarkus-extension/runtime/pom.xml
index 97fc9b28..8319dcf1 100644
--- a/xbuilder/quarkus-extension/runtime/pom.xml
+++ b/xbuilder/quarkus-extension/runtime/pom.xml
@@ -6,7 +6,7 @@
io.github.project-openubl
quarkus-xbuilder-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
quarkus-xbuilder
Quarkus Xbuilder - Runtime
diff --git a/xbuilder/quarkus-extension/runtime/src/main/java/io/github/project/openubl/quarkus/xbuilder/XBuilder.java b/xbuilder/quarkus-extension/runtime/src/main/java/io/github/project/openubl/quarkus/xbuilder/XBuilder.java
index 4db2edb6..e16ab53b 100644
--- a/xbuilder/quarkus-extension/runtime/src/main/java/io/github/project/openubl/quarkus/xbuilder/XBuilder.java
+++ b/xbuilder/quarkus-extension/runtime/src/main/java/io/github/project/openubl/quarkus/xbuilder/XBuilder.java
@@ -16,7 +16,8 @@ enum Type {
SUMMARY_DOCUMENTS("summaryDocuments.xml"),
PERCEPTION("perception.xml"),
RETENTION("retention.xml"),
- DESPATCH_ADVICE("despatchAdvice.xml");
+ DESPATCH_ADVICE("despatchAdvice.xml"),
+ REVERSION("reversion.xml");
private final String templatePath;
diff --git a/xsender/core/pom.xml b/xsender/core/pom.xml
index 2d912e48..fe93d097 100644
--- a/xsender/core/pom.xml
+++ b/xsender/core/pom.xml
@@ -6,7 +6,7 @@
io.github.project-openubl
xsender-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
../pom.xml
diff --git a/xsender/pom.xml b/xsender/pom.xml
index 80ba4b5f..2cd668a7 100644
--- a/xsender/pom.xml
+++ b/xsender/pom.xml
@@ -6,7 +6,7 @@
io.github.project-openubl
xhandler-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
../pom.xml
diff --git a/xsender/quarkus-extension/deployment/pom.xml b/xsender/quarkus-extension/deployment/pom.xml
index fc37dbd5..cc3414e4 100644
--- a/xsender/quarkus-extension/deployment/pom.xml
+++ b/xsender/quarkus-extension/deployment/pom.xml
@@ -6,7 +6,7 @@
io.github.project-openubl
quarkus-xsender-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
quarkus-xsender-deployment
Quarkus XSender - Deployment
diff --git a/xsender/quarkus-extension/deployment/src/main/java/io/github/project/openubl/quarkus/xsender/deployment/QuarkusXsenderProcessor.java b/xsender/quarkus-extension/deployment/src/main/java/io/github/project/openubl/quarkus/xsender/deployment/QuarkusXsenderProcessor.java
index 205a325b..67f4db39 100644
--- a/xsender/quarkus-extension/deployment/src/main/java/io/github/project/openubl/quarkus/xsender/deployment/QuarkusXsenderProcessor.java
+++ b/xsender/quarkus-extension/deployment/src/main/java/io/github/project/openubl/quarkus/xsender/deployment/QuarkusXsenderProcessor.java
@@ -1,7 +1,33 @@
package io.github.project.openubl.quarkus.xsender.deployment;
import io.github.project.openubl.quarkus.xsender.XSender;
-import io.github.project.openubl.xsender.camel.routes.SunatRouteBuilder;
+import io.github.project.openubl.xsender.Constants;
+import io.github.project.openubl.xsender.camel.routes.*;
+import io.github.project.openubl.xsender.camel.utils.CamelData;
+import io.github.project.openubl.xsender.camel.utils.CamelUtils;
+import io.github.project.openubl.xsender.company.CompanyCredentials;
+import io.github.project.openubl.xsender.company.CompanyURLs;
+import io.github.project.openubl.xsender.files.BillServiceFileAnalyzer;
+import io.github.project.openubl.xsender.files.BillServiceXMLFileAnalyzer;
+import io.github.project.openubl.xsender.files.ZipFile;
+import io.github.project.openubl.xsender.files.exceptions.UnsupportedXMLFileException;
+import io.github.project.openubl.xsender.files.xml.DocumentType;
+import io.github.project.openubl.xsender.files.xml.XmlContent;
+import io.github.project.openubl.xsender.files.xml.XmlContentProvider;
+import io.github.project.openubl.xsender.files.xml.XmlHandler;
+import io.github.project.openubl.xsender.models.Metadata;
+import io.github.project.openubl.xsender.models.Status;
+import io.github.project.openubl.xsender.models.Sunat;
+import io.github.project.openubl.xsender.models.SunatResponse;
+import io.github.project.openubl.xsender.models.rest.PayloadDocumentDto;
+import io.github.project.openubl.xsender.models.rest.ResponseAccessTokenSuccessDto;
+import io.github.project.openubl.xsender.models.rest.ResponseDocumentErrorDto;
+import io.github.project.openubl.xsender.models.rest.ResponseDocumentSuccessDto;
+import io.github.project.openubl.xsender.sunat.BillConsultServiceDestination;
+import io.github.project.openubl.xsender.sunat.BillServiceDestination;
+import io.github.project.openubl.xsender.sunat.catalog.Catalog1;
+import io.github.project.openubl.xsender.utils.ByteUtils;
+import io.github.project.openubl.xsender.utils.CdrReader;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.processor.DotNames;
import io.quarkus.deployment.annotations.BuildProducer;
@@ -9,6 +35,9 @@
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
+import org.apache.camel.http.base.HttpOperationFailedException;
+import org.apache.cxf.binding.soap.SoapFault;
+import org.apache.cxf.transport.http.HTTPException;
import java.net.URISyntaxException;
@@ -33,107 +62,87 @@ AdditionalBeanBuildItem additionalBeans() {
@BuildStep
void registerTemplates(BuildProducer resource) throws URISyntaxException {
- resource.produce(
- new NativeImageResourceBuildItem(
- "wsdl/billService.wsdl",
- "wsdl/billConsultService.wsdl",
- "wsdl/billValidService.wsdl"
- )
- );
+ resource.produce(new NativeImageResourceBuildItem(
+ "wsdl/billService.wsdl",
+ "wsdl/billConsultService.wsdl",
+ "wsdl/billValidService.wsdl"));
}
@BuildStep
ReflectiveClassBuildItem projectReflection() {
- return new ReflectiveClassBuildItem(
- true,
- false,
- io.github.project.openubl.xsender.Constants.class,
- io.github.project.openubl.xsender.camel.routes.CxfEndpointConfiguration.class,
- io.github.project.openubl.xsender.camel.routes.RestSunatErrorResponseProcessor.class,
- io.github.project.openubl.xsender.camel.routes.RestSunatResponseProcessor.class,
- io.github.project.openubl.xsender.camel.routes.SunatRouteBuilder.class,
- io.github.project.openubl.xsender.camel.routes.SoapSunatErrorResponseProcessor.class,
- io.github.project.openubl.xsender.camel.routes.SoapSunatResponseProcessor.class,
- io.github.project.openubl.xsender.camel.routes.TicketResponseType.class,
-
- io.github.project.openubl.xsender.camel.utils.CamelData.class,
- io.github.project.openubl.xsender.camel.utils.CamelData.CamelDataBuilder.class,
- io.github.project.openubl.xsender.camel.utils.CamelUtils.class,
-
- io.github.project.openubl.xsender.company.CompanyCredentials.class,
- io.github.project.openubl.xsender.company.CompanyCredentials.CompanyCredentialsBuilder.class,
- io.github.project.openubl.xsender.company.CompanyURLs.class,
- io.github.project.openubl.xsender.company.CompanyURLs.CompanyURLsBuilder.class,
-
- io.github.project.openubl.xsender.files.BillServiceFileAnalyzer.class,
- io.github.project.openubl.xsender.files.BillServiceXMLFileAnalyzer.class,
- io.github.project.openubl.xsender.files.ZipFile.class,
- io.github.project.openubl.xsender.files.ZipFile.ZipFileBuilder.class,
- io.github.project.openubl.xsender.files.exceptions.UnsupportedXMLFileException.class,
- io.github.project.openubl.xsender.files.xml.DocumentType.class,
- io.github.project.openubl.xsender.files.xml.XmlContent.class,
- io.github.project.openubl.xsender.files.xml.XmlContentProvider.class,
- io.github.project.openubl.xsender.files.xml.XmlHandler.class,
-
- io.github.project.openubl.xsender.models.rest.PayloadDocumentDto.class,
- io.github.project.openubl.xsender.models.rest.PayloadDocumentDto.PayloadDocumentDtoBuilder.class,
- io.github.project.openubl.xsender.models.rest.PayloadDocumentDto.Archivo.class,
- io.github.project.openubl.xsender.models.rest.PayloadDocumentDto.Archivo.ArchivoBuilder.class,
- io.github.project.openubl.xsender.models.rest.ResponseAccessTokenSuccessDto.class,
- io.github.project.openubl.xsender.models.rest.ResponseAccessTokenSuccessDto.ResponseAccessTokenSuccessDtoBuilder.class,
- io.github.project.openubl.xsender.models.rest.ResponseDocumentErrorDto.class,
- io.github.project.openubl.xsender.models.rest.ResponseDocumentErrorDto.ResponseDocumentErrorDtoBuilder.class,
- io.github.project.openubl.xsender.models.rest.ResponseDocumentErrorDto.Error.class,
- io.github.project.openubl.xsender.models.rest.ResponseDocumentErrorDto.Error.ErrorBuilder.class,
- io.github.project.openubl.xsender.models.rest.ResponseDocumentSuccessDto.class,
- io.github.project.openubl.xsender.models.rest.ResponseDocumentSuccessDto.ResponseDocumentSuccessDtoBuilder.class,
- io.github.project.openubl.xsender.models.rest.ResponseDocumentSuccessDto.Error.class,
- io.github.project.openubl.xsender.models.rest.ResponseDocumentSuccessDto.Error.ErrorBuilder.class,
- io.github.project.openubl.xsender.models.Metadata.class,
- io.github.project.openubl.xsender.models.Metadata.MetadataBuilder.class,
- io.github.project.openubl.xsender.models.Status.class,
- io.github.project.openubl.xsender.models.Sunat.class,
- io.github.project.openubl.xsender.models.Sunat.SunatBuilder.class,
- io.github.project.openubl.xsender.models.SunatResponse.class,
- io.github.project.openubl.xsender.models.SunatResponse.SunatResponseBuilder.class,
-
- io.github.project.openubl.xsender.sunat.BillServiceDestination.class,
- io.github.project.openubl.xsender.sunat.BillServiceDestination.BillServiceDestinationBuilder.class,
- io.github.project.openubl.xsender.sunat.BillServiceDestination.SoapOperation.class,
- io.github.project.openubl.xsender.sunat.BillServiceDestination.RestOperation.class,
- io.github.project.openubl.xsender.sunat.BillConsultServiceDestination.class,
- io.github.project.openubl.xsender.sunat.BillConsultServiceDestination.BillConsultServiceDestinationBuilder.class,
- io.github.project.openubl.xsender.sunat.BillConsultServiceDestination.Operation.class,
- io.github.project.openubl.xsender.sunat.catalog.Catalog1.class,
- io.github.project.openubl.xsender.utils.ByteUtils.class,
- io.github.project.openubl.xsender.utils.CdrReader.class
- );
+ return ReflectiveClassBuildItem.builder(
+ Constants.class,
+ CxfEndpointConfiguration.class,
+ RestSunatErrorResponseProcessor.class,
+ RestSunatResponseProcessor.class,
+ SunatRouteBuilder.class,
+ SoapSunatErrorResponseProcessor.class,
+ SoapSunatResponseProcessor.class,
+ TicketResponseType.class,
+ CamelData.class,
+ CamelData.CamelDataBuilder.class,
+ CamelUtils.class,
+ CompanyCredentials.class,
+ CompanyCredentials.CompanyCredentialsBuilder.class,
+ CompanyURLs.class,
+ CompanyURLs.CompanyURLsBuilder.class,
+ BillServiceFileAnalyzer.class,
+ BillServiceXMLFileAnalyzer.class,
+ ZipFile.class,
+ ZipFile.ZipFileBuilder.class,
+ UnsupportedXMLFileException.class,
+ DocumentType.class,
+ XmlContent.class,
+ XmlContentProvider.class,
+ XmlHandler.class,
+ PayloadDocumentDto.class,
+ PayloadDocumentDto.PayloadDocumentDtoBuilder.class,
+ PayloadDocumentDto.Archivo.class,
+ PayloadDocumentDto.Archivo.ArchivoBuilder.class,
+ ResponseAccessTokenSuccessDto.class,
+ ResponseAccessTokenSuccessDto.ResponseAccessTokenSuccessDtoBuilder.class,
+ ResponseDocumentErrorDto.class,
+ ResponseDocumentErrorDto.ResponseDocumentErrorDtoBuilder.class,
+ ResponseDocumentErrorDto.Error.class,
+ ResponseDocumentErrorDto.Error.ErrorBuilder.class,
+ ResponseDocumentSuccessDto.class,
+ ResponseDocumentSuccessDto.ResponseDocumentSuccessDtoBuilder.class,
+ ResponseDocumentSuccessDto.Error.class,
+ ResponseDocumentSuccessDto.Error.ErrorBuilder.class,
+ Metadata.class,
+ Metadata.MetadataBuilder.class,
+ Status.class,
+ Sunat.class,
+ Sunat.SunatBuilder.class,
+ SunatResponse.class,
+ SunatResponse.SunatResponseBuilder.class,
+ BillServiceDestination.class,
+ BillServiceDestination.BillServiceDestinationBuilder.class,
+ BillServiceDestination.SoapOperation.class,
+ BillServiceDestination.RestOperation.class,
+ BillConsultServiceDestination.class,
+ BillConsultServiceDestination.BillConsultServiceDestinationBuilder.class,
+ BillConsultServiceDestination.Operation.class,
+ Catalog1.class,
+ ByteUtils.class,
+ CdrReader.class).methods().build();
}
@BuildStep
ReflectiveClassBuildItem soapReflection() {
- return new ReflectiveClassBuildItem(
- true,
- false,
- org.apache.cxf.binding.soap.SoapFault.class,
- org.apache.cxf.transport.http.HTTPException.class
- );
+ return ReflectiveClassBuildItem.builder(SoapFault.class, HTTPException.class)
+ .methods().build();
}
@BuildStep
ReflectiveClassBuildItem restReflection() {
- return new ReflectiveClassBuildItem(
- true,
- false,
- org.apache.camel.http.base.HttpOperationFailedException.class
- );
+ return ReflectiveClassBuildItem.builder(HttpOperationFailedException.class)
+ .methods().build();
}
@BuildStep
ReflectiveClassBuildItem sunatReflection() {
- return new ReflectiveClassBuildItem(
- true,
- true,
+ return ReflectiveClassBuildItem.builder(
service.sunat.gob.pe.billservice.BillService.class,
service.sunat.gob.pe.billservice.StatusResponse.class,
service.sunat.gob.pe.billservice.GetStatus.class,
@@ -145,7 +154,6 @@ ReflectiveClassBuildItem sunatReflection() {
service.sunat.gob.pe.billservice.SendSummary.class,
service.sunat.gob.pe.billservice.SendSummaryResponse.class,
service.sunat.gob.pe.billservice.ObjectFactory.class,
-
service.sunat.gob.pe.billconsultservice.BillService.class,
service.sunat.gob.pe.billconsultservice.StatusResponse.class,
service.sunat.gob.pe.billconsultservice.GetStatus.class,
@@ -153,14 +161,12 @@ ReflectiveClassBuildItem sunatReflection() {
service.sunat.gob.pe.billconsultservice.GetStatusCdr.class,
service.sunat.gob.pe.billconsultservice.GetStatusCdrResponse.class,
service.sunat.gob.pe.billconsultservice.ObjectFactory.class,
-
service.sunat.gob.pe.billvalidservice.BillValidService.class,
service.sunat.gob.pe.billvalidservice.StatusResponse.class,
service.sunat.gob.pe.billvalidservice.ValidaCDPcriterios.class,
service.sunat.gob.pe.billvalidservice.ValidaCDPcriteriosResponse.class,
service.sunat.gob.pe.billvalidservice.VerificaCPEarchivo.class,
service.sunat.gob.pe.billvalidservice.VerificaCPEarchivoResponse.class,
- service.sunat.gob.pe.billvalidservice.ObjectFactory.class
- );
+ service.sunat.gob.pe.billvalidservice.ObjectFactory.class).methods().fields().build();
}
}
diff --git a/xsender/quarkus-extension/integration-tests/pom.xml b/xsender/quarkus-extension/integration-tests/pom.xml
index 42f0d9b8..f4b7f04e 100644
--- a/xsender/quarkus-extension/integration-tests/pom.xml
+++ b/xsender/quarkus-extension/integration-tests/pom.xml
@@ -6,7 +6,7 @@
io.github.project-openubl
quarkus-xsender-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
quarkus-xsender-integration-tests
Quarkus XSender - Integration Tests
diff --git a/xsender/quarkus-extension/integration-tests/src/main/java/io/github/project/openubl/quarkus/xsender/it/QuarkusXSenderResource.java b/xsender/quarkus-extension/integration-tests/src/main/java/io/github/project/openubl/quarkus/xsender/it/QuarkusXSenderResource.java
index d757914f..c73e75b9 100644
--- a/xsender/quarkus-extension/integration-tests/src/main/java/io/github/project/openubl/quarkus/xsender/it/QuarkusXSenderResource.java
+++ b/xsender/quarkus-extension/integration-tests/src/main/java/io/github/project/openubl/quarkus/xsender/it/QuarkusXSenderResource.java
@@ -27,200 +27,207 @@
@ApplicationScoped
public class QuarkusXSenderResource {
- @Inject
- ProducerTemplate producerTemplate;
-
- CompanyURLs companyURLs = CompanyURLs
- .builder()
- .invoice("https://e-beta.sunat.gob.pe/ol-ti-itcpfegem-beta/billService")
- .perceptionRetention("https://e-beta.sunat.gob.pe/ol-ti-itemision-guia-gem-beta/billService")
- .despatch("https://api-cpe.sunat.gob.pe/v1/contribuyente/gem")
- .build();
-
- CompanyCredentials credentials = CompanyCredentials
- .builder()
- .username("12345678959MODDATOS")
- .password("MODDATOS")
- .token("myToken")
- .build();
-
- @POST
- @Path("bill-service/send-invoice")
- public String sendInvoice() throws Exception {
- InputStream is = Thread
- .currentThread()
- .getContextClassLoader()
- .getResourceAsStream("xmls/12345678912-01-F001-1.xml");
-
- BillServiceXMLFileAnalyzer fileAnalyzer = new BillServiceXMLFileAnalyzer(is, companyURLs);
-
- ZipFile zipFile = fileAnalyzer.getZipFile();
- BillServiceDestination destination = fileAnalyzer.getSendFileDestination();
- CamelData camelData = CamelUtils.getBillServiceCamelData(zipFile, destination, credentials);
-
- SunatResponse sunatResponse = producerTemplate
- .requestBodyAndHeaders(Constants.XSENDER_BILL_SERVICE_URI, camelData.getBody(), camelData.getHeaders(), SunatResponse.class);
-
- return sunatResponse.getStatus().toString();
- }
-
- @POST
- @Path("bill-service/send-voided-document")
- public String sendVoidedDocument() throws Exception {
- InputStream is = Thread
- .currentThread()
- .getContextClassLoader()
- .getResourceAsStream("xmls/12345678912-RA-20200328-1.xml");
-
- BillServiceXMLFileAnalyzer fileAnalyzer = new BillServiceXMLFileAnalyzer(is, companyURLs);
-
- ZipFile zipFile = fileAnalyzer.getZipFile();
- BillServiceDestination destination = fileAnalyzer.getSendFileDestination();
- CamelData camelData = CamelUtils.getBillServiceCamelData(zipFile, destination, credentials);
-
- SunatResponse sunatResponse = producerTemplate
- .requestBodyAndHeaders(Constants.XSENDER_BILL_SERVICE_URI, camelData.getBody(), camelData.getHeaders(), SunatResponse.class);
-
- return sunatResponse.getSunat().getTicket();
- }
-
- @POST
- @Path("consult-service/get-status")
- public String consultService_getStatus() throws Exception {
- BillConsultServiceDestination destination = BillConsultServiceDestination.builder()
- .url("https://e-factura.sunat.gob.pe/ol-it-wsconscpegem/billConsultService")
- .operation(BillConsultServiceDestination.Operation.GET_STATUS)
- .build();
-
- CamelData camelData = getBillConsultService(
- "20494918910",
- "01",
- "F001",
- 102,
- destination,
- credentials
- );
-
- try {
- service.sunat.gob.pe.billconsultservice.StatusResponse sunatResponse = producerTemplate
- .requestBodyAndHeaders(Constants.XSENDER_BILL_CONSULT_SERVICE_URI, camelData.getBody(), camelData.getHeaders(), service.sunat.gob.pe.billconsultservice.StatusResponse.class);
- } catch (CamelExecutionException e) {
- return e.getCause().getMessage();
+ @Inject
+ ProducerTemplate producerTemplate;
+
+ CompanyURLs companyURLs = CompanyURLs
+ .builder()
+ .invoice("https://e-beta.sunat.gob.pe/ol-ti-itcpfegem-beta/billService")
+ .perceptionRetention("https://e-beta.sunat.gob.pe/ol-ti-itemision-guia-gem-beta/billService")
+ .despatch("https://api-cpe.sunat.gob.pe/v1/contribuyente/gem")
+ .build();
+
+ CompanyCredentials credentials = CompanyCredentials
+ .builder()
+ .username("12345678959MODDATOS")
+ .password("MODDATOS")
+ .token("myToken")
+ .build();
+
+ @POST
+ @Path("bill-service/send-invoice")
+ public String sendInvoice() throws Exception {
+ InputStream is = Thread
+ .currentThread()
+ .getContextClassLoader()
+ .getResourceAsStream("xmls/12345678912-01-F001-1.xml");
+
+ BillServiceXMLFileAnalyzer fileAnalyzer = new BillServiceXMLFileAnalyzer(is, companyURLs);
+
+ ZipFile zipFile = fileAnalyzer.getZipFile();
+ BillServiceDestination destination = fileAnalyzer.getSendFileDestination();
+ CamelData camelData = CamelUtils.getBillServiceCamelData(zipFile, destination, credentials);
+
+ SunatResponse sunatResponse = producerTemplate
+ .requestBodyAndHeaders(Constants.XSENDER_BILL_SERVICE_URI, camelData.getBody(),
+ camelData.getHeaders(), SunatResponse.class);
+
+ return sunatResponse.getStatus().toString();
}
- throw new IllegalStateException("Excepcion no atrapada");
- }
-
- @POST
- @Path("consult-service/get-status-cdr")
- public String consultService_getStatusCdr() throws Exception {
- BillConsultServiceDestination destination = BillConsultServiceDestination.builder()
- .url("https://e-factura.sunat.gob.pe/ol-it-wsconscpegem/billConsultService")
- .operation(BillConsultServiceDestination.Operation.GET_STATUS_CDR)
- .build();
-
- CamelData camelData = getBillConsultService(
- "20494918910",
- "01",
- "F001",
- 102,
- destination,
- credentials
- );
-
- try {
- service.sunat.gob.pe.billconsultservice.StatusResponse sunatResponse = producerTemplate
- .requestBodyAndHeaders(Constants.XSENDER_BILL_CONSULT_SERVICE_URI, camelData.getBody(), camelData.getHeaders(), service.sunat.gob.pe.billconsultservice.StatusResponse.class);
- } catch (CamelExecutionException e) {
- return e.getCause().getMessage();
- }
+ @POST
+ @Path("bill-service/send-voided-document")
+ public String sendVoidedDocument() throws Exception {
+ InputStream is = Thread
+ .currentThread()
+ .getContextClassLoader()
+ .getResourceAsStream("xmls/12345678912-RA-20200328-1.xml");
- throw new IllegalStateException("Excepcion no atrapada");
- }
+ BillServiceXMLFileAnalyzer fileAnalyzer = new BillServiceXMLFileAnalyzer(is, companyURLs);
- @POST
- @Path("bill-service/send-despatch-advice")
- public String sendDespatchAdvice() throws Exception {
- InputStream is = Thread
- .currentThread()
- .getContextClassLoader()
- .getResourceAsStream("xmls/20000000001-31-VVV1-1.xml");
+ ZipFile zipFile = fileAnalyzer.getZipFile();
+ BillServiceDestination destination = fileAnalyzer.getSendFileDestination();
+ CamelData camelData = CamelUtils.getBillServiceCamelData(zipFile, destination, credentials);
- BillServiceXMLFileAnalyzer fileAnalyzer = new BillServiceXMLFileAnalyzer(is, companyURLs);
+ SunatResponse sunatResponse = producerTemplate
+ .requestBodyAndHeaders(Constants.XSENDER_BILL_SERVICE_URI, camelData.getBody(),
+ camelData.getHeaders(), SunatResponse.class);
- ZipFile zipFile = fileAnalyzer.getZipFile();
- BillServiceDestination destination = fileAnalyzer.getSendFileDestination();
- CamelData camelData = CamelUtils.getBillServiceCamelData(zipFile, destination, credentials);
+ return sunatResponse.getSunat().getTicket();
+ }
- try {
- SunatResponse sunatResponse = producerTemplate
- .requestBodyAndHeaders(Constants.XSENDER_BILL_SERVICE_URI, camelData.getBody(), camelData.getHeaders(), SunatResponse.class);
- } catch (CamelExecutionException e) {
- return e.getCause().getMessage();
+ @POST
+ @Path("consult-service/get-status")
+ public String consultService_getStatus() throws Exception {
+ BillConsultServiceDestination destination = BillConsultServiceDestination.builder()
+ .url("https://e-factura.sunat.gob.pe/ol-it-wsconscpegem/billConsultService")
+ .operation(BillConsultServiceDestination.Operation.GET_STATUS)
+ .build();
+
+ CamelData camelData = getBillConsultService(
+ "20494918910",
+ "01",
+ "F001",
+ 102,
+ destination,
+ credentials);
+
+ try {
+ service.sunat.gob.pe.billconsultservice.StatusResponse sunatResponse = producerTemplate
+ .requestBodyAndHeaders(Constants.XSENDER_BILL_CONSULT_SERVICE_URI,
+ camelData.getBody(), camelData.getHeaders(),
+ service.sunat.gob.pe.billconsultservice.StatusResponse.class);
+ } catch (CamelExecutionException e) {
+ return e.getCause().getMessage();
+ }
+
+ throw new IllegalStateException("Excepcion no atrapada");
}
- throw new IllegalStateException("Excepcion no atrapada");
- }
-
- @POST
- @Path("consult-valid-service/validate-data")
- public String consultValidService_validateData() throws Exception {
- BillValidServiceDestination destination = BillValidServiceDestination.builder()
- .url("https://e-factura.sunat.gob.pe/ol-it-wsconscpegem/billConsultService")
- .build();
-
- CamelData camelData = getBillValidService(
- "20494918910",
- "01",
- "F001",
- "102",
- "06",
- "12345678",
- "01-12-2022",
- 120.5,
- "",
- destination,
- credentials
- );
-
- try {
- service.sunat.gob.pe.billvalidservice.StatusResponse sunatResponse = producerTemplate
- .requestBodyAndHeaders(Constants.XSENDER_BILL_VALID_SERVICE_URI, camelData.getBody(), camelData.getHeaders(), service.sunat.gob.pe.billvalidservice.StatusResponse.class);
- } catch (CamelExecutionException e) {
- return e.getCause().getMessage();
+ @POST
+ @Path("consult-service/get-status-cdr")
+ public String consultService_getStatusCdr() throws Exception {
+ BillConsultServiceDestination destination = BillConsultServiceDestination.builder()
+ .url("https://e-factura.sunat.gob.pe/ol-it-wsconscpegem/billConsultService")
+ .operation(BillConsultServiceDestination.Operation.GET_STATUS_CDR)
+ .build();
+
+ CamelData camelData = getBillConsultService(
+ "20494918910",
+ "01",
+ "F001",
+ 102,
+ destination,
+ credentials);
+
+ try {
+ service.sunat.gob.pe.billconsultservice.StatusResponse sunatResponse = producerTemplate
+ .requestBodyAndHeaders(Constants.XSENDER_BILL_CONSULT_SERVICE_URI,
+ camelData.getBody(), camelData.getHeaders(),
+ service.sunat.gob.pe.billconsultservice.StatusResponse.class);
+ } catch (CamelExecutionException e) {
+ return e.getCause().getMessage();
+ }
+
+ throw new IllegalStateException("Excepcion no atrapada");
}
- throw new IllegalStateException("Excepcion no atrapada");
- }
-
- @POST
- @Path("consult-valid-service/validate-file")
- public String consultValidService_validateFile() throws Exception {
- String fileName = "12345678912-01-F001-1.xml";
- byte[] fileContent = Thread
- .currentThread()
- .getContextClassLoader()
- .getResourceAsStream("xmls/" + fileName)
- .readAllBytes();
-
- BillValidServiceDestination destination = BillValidServiceDestination.builder()
- .url("https://e-factura.sunat.gob.pe/ol-it-wsconscpegem/billConsultService")
- .build();
-
- CamelData camelData = getBillValidService(
- fileName,
- fileContent,
- destination,
- credentials
- );
-
- try {
- service.sunat.gob.pe.billvalidservice.StatusResponse sunatResponse = producerTemplate
- .requestBodyAndHeaders(Constants.XSENDER_BILL_VALID_SERVICE_URI, camelData.getBody(), camelData.getHeaders(), service.sunat.gob.pe.billvalidservice.StatusResponse.class);
- } catch (CamelExecutionException e) {
- return e.getCause().getMessage();
+ @POST
+ @Path("bill-service/send-despatch-advice")
+ public String sendDespatchAdvice() throws Exception {
+ InputStream is = Thread
+ .currentThread()
+ .getContextClassLoader()
+ .getResourceAsStream("xmls/20000000001-31-VVV1-1.xml");
+
+ BillServiceXMLFileAnalyzer fileAnalyzer = new BillServiceXMLFileAnalyzer(is, companyURLs);
+
+ ZipFile zipFile = fileAnalyzer.getZipFile();
+ BillServiceDestination destination = fileAnalyzer.getSendFileDestination();
+ CamelData camelData = CamelUtils.getBillServiceCamelData(zipFile, destination, credentials);
+
+ try {
+ SunatResponse sunatResponse = producerTemplate
+ .requestBodyAndHeaders(Constants.XSENDER_BILL_SERVICE_URI, camelData.getBody(),
+ camelData.getHeaders(), SunatResponse.class);
+ } catch (CamelExecutionException e) {
+ return e.getCause().getMessage();
+ }
+
+ throw new IllegalStateException("Excepcion no atrapada");
}
- throw new IllegalStateException("Excepcion no atrapada");
- }
+ @POST
+ @Path("consult-valid-service/validate-data")
+ public String consultValidService_validateData() throws Exception {
+ BillValidServiceDestination destination = BillValidServiceDestination.builder()
+ .url("https://e-factura.sunat.gob.pe/ol-it-wsconscpegem/billConsultService")
+ .build();
+
+ CamelData camelData = getBillValidService(
+ "20494918910",
+ "01",
+ "F001",
+ "102",
+ "06",
+ "12345678",
+ "01-12-2022",
+ 120.5,
+ "",
+ destination,
+ credentials);
+
+ try {
+ service.sunat.gob.pe.billvalidservice.StatusResponse sunatResponse = producerTemplate
+ .requestBodyAndHeaders(Constants.XSENDER_BILL_VALID_SERVICE_URI,
+ camelData.getBody(), camelData.getHeaders(),
+ service.sunat.gob.pe.billvalidservice.StatusResponse.class);
+ } catch (CamelExecutionException e) {
+ return e.getCause().getMessage();
+ }
+
+ throw new IllegalStateException("Excepcion no atrapada");
+ }
+
+ @POST
+ @Path("consult-valid-service/validate-file")
+ public String consultValidService_validateFile() throws Exception {
+ String fileName = "12345678912-01-F001-1.xml";
+ byte[] fileContent = Thread
+ .currentThread()
+ .getContextClassLoader()
+ .getResourceAsStream("xmls/" + fileName)
+ .readAllBytes();
+
+ BillValidServiceDestination destination = BillValidServiceDestination.builder()
+ .url("https://e-factura.sunat.gob.pe/ol-it-wsconscpegem/billConsultService")
+ .build();
+
+ CamelData camelData = getBillValidService(
+ fileName,
+ fileContent,
+ destination,
+ credentials);
+
+ try {
+ service.sunat.gob.pe.billvalidservice.StatusResponse sunatResponse = producerTemplate
+ .requestBodyAndHeaders(Constants.XSENDER_BILL_VALID_SERVICE_URI,
+ camelData.getBody(), camelData.getHeaders(),
+ service.sunat.gob.pe.billvalidservice.StatusResponse.class);
+ } catch (CamelExecutionException e) {
+ return e.getCause().getMessage();
+ }
+
+ throw new IllegalStateException("Excepcion no atrapada");
+ }
}
diff --git a/xsender/quarkus-extension/pom.xml b/xsender/quarkus-extension/pom.xml
index 2d0e9329..ca897455 100644
--- a/xsender/quarkus-extension/pom.xml
+++ b/xsender/quarkus-extension/pom.xml
@@ -7,7 +7,7 @@
io.github.project-openubl
xsender-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
../pom.xml
diff --git a/xsender/quarkus-extension/runtime/pom.xml b/xsender/quarkus-extension/runtime/pom.xml
index b9a41bfd..13b626d1 100644
--- a/xsender/quarkus-extension/runtime/pom.xml
+++ b/xsender/quarkus-extension/runtime/pom.xml
@@ -6,7 +6,7 @@
io.github.project-openubl
quarkus-xsender-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
quarkus-xsender
Quarkus XSender - Runtime
diff --git a/xsender/spring-boot-extension/integration-tests/pom.xml b/xsender/spring-boot-extension/integration-tests/pom.xml
index 9d103754..2f66fcfa 100644
--- a/xsender/spring-boot-extension/integration-tests/pom.xml
+++ b/xsender/spring-boot-extension/integration-tests/pom.xml
@@ -6,7 +6,7 @@
io.github.project-openubl
spring-boot-xsender-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
spring-boot-xsender-integration-tests
Spring Boot XSender - Integration Tests
diff --git a/xsender/spring-boot-extension/pom.xml b/xsender/spring-boot-extension/pom.xml
index efc2abfa..a9295c06 100644
--- a/xsender/spring-boot-extension/pom.xml
+++ b/xsender/spring-boot-extension/pom.xml
@@ -7,7 +7,7 @@
io.github.project-openubl
xsender-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
../pom.xml
diff --git a/xsender/spring-boot-extension/runtime/pom.xml b/xsender/spring-boot-extension/runtime/pom.xml
index 8fa93417..92aa9db4 100644
--- a/xsender/spring-boot-extension/runtime/pom.xml
+++ b/xsender/spring-boot-extension/runtime/pom.xml
@@ -6,7 +6,7 @@
io.github.project-openubl
spring-boot-xsender-parent
- 5.0.3-SNAPSHOT
+ 6.0.0-SNAPSHOT
spring-boot-xsender
Spring Boot XSender - Runtime