getFromCode(int code) {
20 | return Arrays.stream(TicketResponseType.values()).filter(f -> f.getCode() == code).findFirst();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/catalogs/Catalog12_Doc_Trib_Relacionado_BoletaFactura.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.catalogs;
2 |
3 | public enum Catalog12_Doc_Trib_Relacionado_BoletaFactura implements Catalog {
4 | TICKET_DE_SALIDA("04"),
5 | CODIGO_SCOP("05"),
6 | FACTURA_ELECTRONICA_REMITENTE("06"),
7 | GUIA_DE_REMISION_REMITENTE("07"),
8 | DECLARACION_DE_SALIDA_DEL_DEPOSITO_FRANCO("08"),
9 | DECLARACION_SIMPLIFICADA_DE_IMPORTACION("09"),
10 | OTROS("99");
11 |
12 | private final String code;
13 |
14 | Catalog12_Doc_Trib_Relacionado_BoletaFactura(String code) {
15 | this.code = code;
16 | }
17 |
18 | @Override
19 | public String getCode() {
20 | return code;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/resumen/ComprobanteImpuestos.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.sunat.resumen;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import java.math.BigDecimal;
10 |
11 | @Data
12 | @Builder
13 | @NoArgsConstructor
14 | @AllArgsConstructor
15 | public class ComprobanteImpuestos {
16 |
17 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, description = "IGV del comprobante")
18 | private BigDecimal igv;
19 |
20 | @Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED, description = "ICB del comprobante")
21 | private BigDecimal icb;
22 | }
23 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLContact.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.jaxb.models;
2 |
3 | import lombok.Data;
4 | import lombok.NoArgsConstructor;
5 |
6 | import jakarta.xml.bind.annotation.XmlAccessType;
7 | import jakarta.xml.bind.annotation.XmlAccessorType;
8 | import jakarta.xml.bind.annotation.XmlElement;
9 | import jakarta.xml.bind.annotation.XmlType;
10 |
11 | @XmlAccessorType(XmlAccessType.NONE)
12 | @XmlType(name = "Contact")
13 | @Data
14 | @NoArgsConstructor
15 | public class XMLContact {
16 |
17 | @XmlElement(name = "Telephone", namespace = XMLConstants.CBC)
18 | private String telephone;
19 |
20 | @XmlElement(name = "ElectronicMail", namespace = XMLConstants.CBC)
21 | private String electronicMail;
22 | }
23 |
--------------------------------------------------------------------------------
/xbuilder/core/src/test/java/e2e/homologacion/HomologacionConstants.java:
--------------------------------------------------------------------------------
1 | package e2e.homologacion;
2 |
3 | import io.github.project.openubl.xbuilder.content.catalogs.Catalog6;
4 | import io.github.project.openubl.xbuilder.content.models.common.Cliente;
5 | import io.github.project.openubl.xbuilder.content.models.common.Proveedor;
6 |
7 | public class HomologacionConstants {
8 |
9 | public static final Proveedor proveedor = Proveedor.builder()
10 | .ruc("12345678912")
11 | .razonSocial("Softgreen S.A.C.")
12 | .build();
13 | public static final Cliente cliente = Cliente.builder()
14 | .nombre("Carlos Feria")
15 | .numeroDocumentoIdentidad("12121212121")
16 | .tipoDocumentoIdentidad(Catalog6.RUC.toString())
17 | .build();
18 | }
19 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Destinatario.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.standard.guia;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | @Data
10 | @Builder
11 | @NoArgsConstructor
12 | @AllArgsConstructor
13 | public class Destinatario {
14 |
15 | @Schema(description = "Catalogo 06", requiredMode = Schema.RequiredMode.REQUIRED)
16 | private String tipoDocumentoIdentidad;
17 |
18 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
19 | private String numeroDocumentoIdentidad;
20 |
21 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
22 | private String nombre;
23 | }
24 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/resumen/ComprobanteValorVenta.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.sunat.resumen;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import java.math.BigDecimal;
10 |
11 | @Data
12 | @Builder
13 | @NoArgsConstructor
14 | @AllArgsConstructor
15 | public class ComprobanteValorVenta {
16 |
17 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
18 | private BigDecimal importeTotal;
19 | private BigDecimal otrosCargos;
20 | private BigDecimal gravado;
21 | private BigDecimal exonerado;
22 | private BigDecimal inafecto;
23 | private BigDecimal gratuito;
24 | }
25 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/catalogs/Catalog22.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.catalogs;
2 |
3 | import java.math.BigDecimal;
4 |
5 | public enum Catalog22 implements Catalog {
6 | VENTA_INTERNA("01", BigDecimal.valueOf(2)),
7 | ADQUISICION_DE_COMBUSTIBLE("02", BigDecimal.valueOf(1)),
8 | AGENTE_DE_PERCEPCION_CON_TASA_ESPECIAL("03", BigDecimal.valueOf(0.5));
9 |
10 | private final String code;
11 | private final BigDecimal percent;
12 |
13 | Catalog22(String code, BigDecimal percent) {
14 | this.code = code;
15 | this.percent = percent;
16 | }
17 |
18 | @Override
19 | public String getCode() {
20 | return code;
21 | }
22 |
23 | public BigDecimal getPercent() {
24 | return percent;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/signature/CertificateDetails.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.signature;
2 |
3 | import java.security.PrivateKey;
4 | import java.security.cert.X509Certificate;
5 |
6 | public class CertificateDetails {
7 |
8 | private PrivateKey privateKey;
9 |
10 | private X509Certificate x509Certificate;
11 |
12 | public PrivateKey getPrivateKey() {
13 | return privateKey;
14 | }
15 |
16 | public void setPrivateKey(PrivateKey privateKey) {
17 | this.privateKey = privateKey;
18 | }
19 |
20 | public X509Certificate getX509Certificate() {
21 | return x509Certificate;
22 | }
23 |
24 | public void setX509Certificate(X509Certificate x509Certificate) {
25 | this.x509Certificate = x509Certificate;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/catalogs/Catalog6.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.catalogs;
2 |
3 | public enum Catalog6 implements Catalog {
4 | DOC_TRIB_NO_DOM_SIN_RUC("0"),
5 | DNI("1"),
6 | EXTRANJERIA("4"),
7 | RUC("6"),
8 | PASAPORTE("7"),
9 | DEC_DIPLOMATICA("A"),
10 | DOC_IDENT_PAIS_RESIDENCIA_NO_D("B"),
11 | TAX_IDENTIFICATION_NUMBER_TIN_DOC_TRIB_PP_NN("C"),
12 | IDENTIFICATION_NUMBER_IN_DOC_TRIB_PP_JJ("D"),
13 | TAM_TARJETA_ANDINA_DE_MIGRACION("E"),
14 | PERMISO_TEMPORAL_DE_PERMANENCIA_PTP("F"),
15 | SALVOCONDUCTO("G");
16 |
17 | private final String code;
18 |
19 | Catalog6(String code) {
20 | this.code = code;
21 | }
22 |
23 | @Override
24 | public String getCode() {
25 | return code;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/general/Guia.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.standard.general;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | @Data
10 | @Builder
11 | @NoArgsConstructor
12 | @AllArgsConstructor
13 | public class Guia {
14 |
15 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
16 | private String serieNumero;
17 |
18 | /**
19 | * Tipo de documento Guia.
20 | *
21 | * Catalogo 01.
22 | *
23 | * Valores válidos: "09", "31"
24 | */
25 | @Schema(description = "Catalogo 01", requiredMode = Schema.RequiredMode.REQUIRED)
26 | private String tipoDocumento;
27 | }
28 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/general/TotalImporte.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.standard.general;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 | import lombok.experimental.SuperBuilder;
7 |
8 | import java.math.BigDecimal;
9 |
10 | @Data
11 | @SuperBuilder
12 | @NoArgsConstructor
13 | public abstract class TotalImporte {
14 |
15 | @Schema(minimum = "0", requiredMode = Schema.RequiredMode.REQUIRED)
16 | private BigDecimal importe;
17 |
18 | @Schema(minimum = "0", requiredMode = Schema.RequiredMode.REQUIRED)
19 | private BigDecimal importeSinImpuestos;
20 |
21 | @Schema(minimum = "0", requiredMode = Schema.RequiredMode.REQUIRED)
22 | private BigDecimal importeConImpuestos;
23 | }
24 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/common/Contacto.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.common;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | /**
10 | * Datos de contacto
11 | *
12 | * @author Carlos Feria
13 | */
14 | @Data
15 | @Builder
16 | @NoArgsConstructor
17 | @AllArgsConstructor
18 | public class Contacto {
19 |
20 | /**
21 | * Número telefónico
22 | */
23 | @Schema(description = "Número telefónico")
24 | private String telefono;
25 |
26 | /**
27 | * Correo electrónico
28 | */
29 | @Schema(description = "Correo electrónico")
30 | private String email;
31 | }
32 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.versionsBackup
2 |
3 | # Intellij
4 | ###################
5 | .idea
6 | *.iml
7 |
8 | # Eclipse #
9 | ###########
10 | .project
11 | .settings
12 | .classpath
13 | .factorypath
14 |
15 | # NetBeans #
16 | ############
17 | nbactions.xml
18 | nb-configuration.xml
19 | catalog.xml
20 | nbproject
21 |
22 | # Compiled source #
23 | ###################
24 | *.com
25 | *.class
26 | *.dll
27 | *.exe
28 | *.o
29 | *.so
30 |
31 | # Packages #
32 | ############
33 | # it's better to unpack these files and commit the raw source
34 | # git has its own built in compression methods
35 | *.7z
36 | *.dmg
37 | *.gz
38 | *.iso
39 | *.jar
40 | *.rar
41 | *.tar
42 | *.zip
43 |
44 | # Logs and databases #
45 | ######################
46 | *.log
47 |
48 | # Maven #
49 | #########
50 | target
51 |
52 | # Maven shade
53 | #############
54 | *dependency-reduced-pom.xml
55 |
56 | /lsp/
57 | bin/
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/catalogs/Catalog52.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.catalogs;
2 |
3 | public enum Catalog52 implements Catalog {
4 | MONTO_EN_LETRAS("1000", "MONTO EN LETRAS"),
5 | COMPROBANTE_DE_PERCEPCION("2000", "COMPROBANTE DE PERCEPCION"),
6 | VENTA_REALIZADA_POR_EMISOR_ITINERANTE("2005", "VENTA REALIZADA POR EMISOR ITINERANTE"),
7 | OPERACION_SUJETA_A_DETRACCION("2006", "OPERACION SUJETA A DETRACCION");
8 |
9 | private final String code;
10 | private final String label;
11 |
12 | Catalog52(String code, String label) {
13 | this.code = code;
14 | this.label = label;
15 | }
16 |
17 | @Override
18 | public String getCode() {
19 | return code;
20 | }
21 |
22 | public String getLabel() {
23 | return label;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/xbuilder/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | io.github.project-openubl
8 | xhandler-parent
9 | 5.0.3-SNAPSHOT
10 | ../pom.xml
11 |
12 |
13 | xbuilder-parent
14 | XBuilder - Parent
15 | XBuilder parent
16 | pom
17 |
18 |
19 | core
20 | quarkus-extension
21 |
22 |
23 |
--------------------------------------------------------------------------------
/examples/xsender/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | io.github.project-openubl
8 | examples-parent
9 | 5.0.3-SNAPSHOT
10 | ../pom.xml
11 |
12 |
13 | xsender-example
14 | Examples - XSender
15 |
16 |
17 |
18 | io.github.project-openubl
19 | xsender
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/examples/xbuilder/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | io.github.project-openubl
8 | examples-parent
9 | 5.0.3-SNAPSHOT
10 | ../pom.xml
11 |
12 |
13 | xbuilder-example
14 | Examples - XBuilder
15 |
16 |
17 |
18 | io.github.project-openubl
19 | xbuilder
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/general/TotalImporteInvoice.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.standard.general;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import lombok.Data;
5 | import lombok.EqualsAndHashCode;
6 | import lombok.NoArgsConstructor;
7 | import lombok.ToString;
8 | import lombok.experimental.SuperBuilder;
9 |
10 | import java.math.BigDecimal;
11 |
12 | @Data
13 | @SuperBuilder
14 | @NoArgsConstructor
15 | @EqualsAndHashCode(callSuper = true)
16 | @ToString(callSuper = true)
17 | public class TotalImporteInvoice extends TotalImporte {
18 |
19 | @Schema(minimum = "0", requiredMode = Schema.RequiredMode.REQUIRED)
20 | private BigDecimal anticipos;
21 |
22 | @Schema(minimum = "0", requiredMode = Schema.RequiredMode.REQUIRED)
23 | private BigDecimal descuentos;
24 | }
25 |
--------------------------------------------------------------------------------
/xsender/core/src/main/java/io/github/project/openubl/xsender/models/rest/ResponseDocumentErrorDto.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xsender.models.rest;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 | import lombok.Singular;
8 |
9 | import java.util.List;
10 |
11 | @Data
12 | @Builder
13 | @NoArgsConstructor
14 | @AllArgsConstructor
15 | public class ResponseDocumentErrorDto {
16 | private String cod;
17 | private String msg;
18 | private String exc;
19 |
20 | private String status;
21 | private String message;
22 |
23 | @Singular
24 | private List errors;
25 |
26 | @Data
27 | @Builder
28 | @NoArgsConstructor
29 | @AllArgsConstructor
30 | public static class Error {
31 | private String cod;
32 | private String msg;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/xsender/core/src/main/java/io/github/project/openubl/xsender/models/rest/ResponseDocumentSuccessDto.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xsender.models.rest;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.time.ZonedDateTime;
9 |
10 | @Data
11 | @Builder
12 | @NoArgsConstructor
13 | @AllArgsConstructor
14 | public class ResponseDocumentSuccessDto {
15 | private String numTicket;
16 | private ZonedDateTime fecRecepcion;
17 |
18 | private String codRespuesta;
19 | private String arcCdr;
20 | private String indCdrGenerado;
21 | private Error error;
22 |
23 | @Data
24 | @Builder
25 | @NoArgsConstructor
26 | @AllArgsConstructor
27 | public static class Error {
28 | private String numError;
29 | private String desError;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "xhandler",
3 | "image": "mcr.microsoft.com/devcontainers/java:17-bullseye",
4 | "features": {
5 | "ghcr.io/devcontainers/features/java:1": {
6 | "version": "17",
7 | "installMaven": "true",
8 | "installGradle": "false"
9 | },
10 | "ghcr.io/devcontainers/features/docker-in-docker:2": {}
11 | },
12 | "postCreateCommand": "echo \"source /usr/share/bash-completion/completions/git\" >> ~/.bashrc",
13 | "customizations": {
14 | "vscode": {
15 | "settings": {
16 | "java.compile.nullAnalysis.mode": "automatic"
17 | },
18 | "extensions": [
19 | "vscjava.vscode-java-pack",
20 | "github.vscode-github-actions",
21 | "github.vscode-pull-request-github"
22 | ]
23 | },
24 | "codespaces": {
25 | "openFiles": [
26 | "README.md"
27 | ]
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/xsender/core/src/main/java/io/github/project/openubl/xsender/models/Status.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xsender.models;
2 |
3 | public enum Status {
4 | ACEPTADO,
5 | RECHAZADO,
6 | BAJA,
7 | EXCEPCION,
8 | EN_PROCESO,
9 | UNKNOWN;
10 |
11 | public static Status fromCode(int code) {
12 | if (code == 0) {
13 | return Status.ACEPTADO;
14 | } else if (code == 98) {
15 | return Status.EN_PROCESO;
16 | } else if (code == 99) {
17 | return Status.EXCEPCION;
18 | } else if (code >= 100 && code < 2_000) {
19 | return Status.EXCEPCION;
20 | } else if (code >= 2000 && code < 4000) {
21 | return Status.RECHAZADO;
22 | } else if (code >= 4000) {
23 | return Status.ACEPTADO;
24 | } else {
25 | return Status.UNKNOWN;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/examples/tomcat/quickstart.sh:
--------------------------------------------------------------------------------
1 | # Generate .war
2 | mvn clean package
3 |
4 | # Download Tomcat
5 | rm -rf workspace/
6 | #wget https://repo1.maven.org/maven2/org/apache/tomcat/tomcat/9.0.46/tomcat-9.0.46.zip -P workspace/
7 | wget https://repo1.maven.org/maven2/org/apache/tomcat/tomcat/10.1.8/tomcat-10.1.8.zip -P workspace/
8 | #unzip workspace/tomcat-9.0.46.zip -d workspace/
9 | unzip workspace/tomcat-10.1.8.zip -d workspace/
10 | #chmod +x -R ./workspace/apache-tomcat-9.0.46/bin
11 | chmod +x -R ./workspace/apache-tomcat-10.1.8/bin
12 |
13 | # Copy .war to Tomcat
14 | #cp target/tomcat-xbuilder-xsender-0.0.1-SNAPSHOT.war workspace/apache-tomcat-9.0.46/webapps/demo.war
15 | cp target/tomcat-xbuilder-xsender-0.0.1-SNAPSHOT.war workspace/apache-tomcat-10.1.8/webapps/demo.war
16 |
17 | # Start Tomcat
18 | #./workspace/apache-tomcat-9.0.46/bin/startup.sh
19 | ./workspace/apache-tomcat-10.1.8/bin/startup.sh
20 |
21 | sleep 10s
22 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/catalogs/Catalog12.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.catalogs;
2 |
3 | public enum Catalog12 implements Catalog {
4 | FACTURA_EMITIDA_PARA_CORREGIR_ERROR_EN_EL_RUC("01"),
5 | FACTURA_EMITIDA_POR_ANTICIPOS("02"),
6 | BOLETA_DE_VENTA_EMITIDA_POR_ANTICIPOS("03"),
7 | TICKET_DE_SALIDA("04"),
8 | CODIGO_SCOP("05"),
9 | FACTURA_ELECTRONICA_REMITENTE("06"),
10 | GUIA_DE_REMISION_REMITENTE("07"),
11 | DECLARACION_DE_SALIDA_DEL_DEPOSITO_FRANCO("08"),
12 | DECLARACION_SIMPLIFICADA_DE_IMPORTACION("09"),
13 | LIQUIDACION_DE_COMPRA_EMITIDA_POR_ANTICIPOS("10"),
14 | OTROS("99");
15 |
16 | private final String code;
17 |
18 | Catalog12(String code) {
19 | this.code = code;
20 | }
21 |
22 | @Override
23 | public String getCode() {
24 | return code;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/general/Percepcion.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.standard.general;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import java.math.BigDecimal;
10 |
11 | @Data
12 | @Builder
13 | @NoArgsConstructor
14 | @AllArgsConstructor
15 | public class Percepcion {
16 |
17 | /**
18 | * Catalog53
19 | */
20 | @Schema(description = "Catalog 53", requiredMode = Schema.RequiredMode.REQUIRED)
21 | private String tipo;
22 |
23 | private BigDecimal montoBase; // importeSinImpuestos
24 | private BigDecimal porcentaje; // Establecido por el "tipo"
25 | private BigDecimal monto; // montoBase * porcentaje
26 | private BigDecimal montoTotal; // montoBase + monto
27 | }
28 |
--------------------------------------------------------------------------------
/xsender/core/src/test/java/io/github/project/openubl/xsender/sunat/catalog/Catalog1Test.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xsender.sunat.catalog;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import java.util.Optional;
6 |
7 | import static org.junit.jupiter.api.Assertions.assertEquals;
8 | import static org.junit.jupiter.api.Assertions.assertFalse;
9 | import static org.junit.jupiter.api.Assertions.assertTrue;
10 |
11 | public class Catalog1Test {
12 |
13 | @Test
14 | public void givenValidCodeShouldReturnEnumValue() {
15 | Optional result = Catalog1.valueOfCode("01");
16 |
17 | assertTrue(result.isPresent());
18 | assertEquals(Catalog1.FACTURA, result.get());
19 | }
20 |
21 | @Test
22 | public void givenInvalidCodeShouldReturnEmptyValue() {
23 | Optional result = Catalog1.valueOfCode("010");
24 |
25 | assertFalse(result.isPresent());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/xsender/core/src/main/java/io/github/project/openubl/xsender/camel/StandaloneCamel.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xsender.camel;
2 |
3 | import lombok.Synchronized;
4 | import org.apache.camel.main.Main;
5 |
6 | public final class StandaloneCamel {
7 |
8 | private static StandaloneCamel instance;
9 | private final Main mainCamel;
10 |
11 | private StandaloneCamel() throws Exception {
12 | mainCamel = new Main(StandaloneCamel.class);
13 | mainCamel.start();
14 | }
15 |
16 | @Synchronized
17 | public static StandaloneCamel getInstance() {
18 | if (instance == null) {
19 | try {
20 | instance = new StandaloneCamel();
21 | } catch (Exception e) {
22 | throw new RuntimeException(e);
23 | }
24 | }
25 | return instance;
26 | }
27 |
28 | public Main getMainCamel() {
29 | return mainCamel;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/xsender/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | io.github.project-openubl
8 | xhandler-parent
9 | 5.0.3-SNAPSHOT
10 | ../pom.xml
11 |
12 |
13 | xsender-parent
14 | XSender - Parent
15 | Java library for sending XML files to SUNAT
16 | pom
17 |
18 |
19 | core
20 | quarkus-extension
21 | spring-boot-extension
22 |
23 |
24 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/general/Descuento.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.standard.general;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import java.math.BigDecimal;
10 |
11 | @Data
12 | @Builder
13 | @NoArgsConstructor
14 | @AllArgsConstructor
15 | public class Descuento {
16 |
17 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, description = "Catalogo 53")
18 | private String tipoDescuento;
19 |
20 | @Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED)
21 | private BigDecimal factor;
22 |
23 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
24 | private BigDecimal monto;
25 |
26 | @Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED)
27 | private BigDecimal montoBase;
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/resources/templates/ubl/standard/include/namespaces.xml:
--------------------------------------------------------------------------------
1 | xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
2 | xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
3 | xmlns:ccts="urn:un:unece:uncefact:documentation:2"
4 | xmlns:cec="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
5 | xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
6 | xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
7 | xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2"
8 | xmlns:sac="urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1"
9 | xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2"
10 | xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
11 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLVoidedDocuments.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.jaxb.models;
2 |
3 | import lombok.Data;
4 | import lombok.EqualsAndHashCode;
5 | import lombok.NoArgsConstructor;
6 |
7 | import jakarta.xml.bind.annotation.XmlAccessType;
8 | import jakarta.xml.bind.annotation.XmlAccessorType;
9 | import jakarta.xml.bind.annotation.XmlElement;
10 | import jakarta.xml.bind.annotation.XmlRootElement;
11 | import java.util.List;
12 |
13 | @XmlAccessorType(XmlAccessType.NONE)
14 | @XmlRootElement(name = "VoidedDocuments", namespace = "urn:sunat:names:specification:ubl:peru:schema:xsd:VoidedDocuments-1")
15 | @EqualsAndHashCode(callSuper = true)
16 | @Data
17 | @NoArgsConstructor
18 | public class XMLVoidedDocuments extends XMLSunatDocument {
19 |
20 | @XmlElement(name = "VoidedDocumentsLine", namespace = XMLConstants.SAC)
21 | private List lines;
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLSummaryDocuments.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.jaxb.models;
2 |
3 | import lombok.Data;
4 | import lombok.EqualsAndHashCode;
5 | import lombok.NoArgsConstructor;
6 |
7 | import jakarta.xml.bind.annotation.XmlAccessType;
8 | import jakarta.xml.bind.annotation.XmlAccessorType;
9 | import jakarta.xml.bind.annotation.XmlElement;
10 | import jakarta.xml.bind.annotation.XmlRootElement;
11 | import java.util.List;
12 |
13 | @XmlAccessorType(XmlAccessType.NONE)
14 | @XmlRootElement(name = "SummaryDocuments", namespace = "urn:sunat:names:specification:ubl:peru:schema:xsd:SummaryDocuments-1")
15 | @EqualsAndHashCode(callSuper = true)
16 | @Data
17 | @NoArgsConstructor
18 | public class XMLSummaryDocuments extends XMLSunatDocument {
19 |
20 | @XmlElement(name = "SummaryDocumentsLine", namespace = XMLConstants.SAC)
21 | private List lines;
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/resources/templates/ubl/standard/include/note/invoice-reference.xml:
--------------------------------------------------------------------------------
1 |
2 | {item.comprobanteAfectadoSerieNumero}
3 | {item.comprobanteAfectadoTipo}
4 |
5 |
6 | {#if item.ordenDeCompra}
7 |
8 | {item.ordenDeCompra}
9 |
10 | {/if}
11 |
12 |
13 | {item.comprobanteAfectadoSerieNumero}
14 | {item.comprobanteAfectadoTipo}
15 |
16 |
17 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/common/Firmante.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.common;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | /**
10 | * Persona que firma electrónicamente el documento
11 | *
12 | * @author Carlos Feria
13 | */
14 | @Data
15 | @Builder
16 | @NoArgsConstructor
17 | @AllArgsConstructor
18 | public class Firmante {
19 |
20 | /**
21 | * Número de RUC de la persona
22 | */
23 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, minLength = 11, maxLength = 11, pattern = "[0-9]+")
24 | private String ruc;
25 |
26 | /**
27 | * Razón social de la persona
28 | */
29 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
30 | private String razonSocial;
31 | }
32 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/AbstractBodyRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie;
2 |
3 | import io.github.project.openubl.xbuilder.enricher.config.Defaults;
4 | import io.github.project.openubl.xbuilder.enricher.kie.ruleunits.BodyRuleContext;
5 |
6 | public abstract class AbstractBodyRule implements RuleFactory, Rule {
7 |
8 | private Defaults defaults;
9 | private BodyRuleContext ruleContext;
10 |
11 | @Override
12 | public Rule create(Defaults defaults, RuleContext ruleContext) {
13 | this.defaults = defaults;
14 | if (ruleContext instanceof BodyRuleContext) {
15 | this.ruleContext = (BodyRuleContext) ruleContext;
16 | } else {
17 | throw new IllegalStateException("HeaderRule requires HeaderContext");
18 | }
19 | return this;
20 | }
21 |
22 | public BodyRuleContext getRuleContext() {
23 | return ruleContext;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/general/FormaDePago.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.standard.general;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 | import lombok.Singular;
8 | import lombok.experimental.SuperBuilder;
9 |
10 | import java.math.BigDecimal;
11 | import java.util.List;
12 |
13 | @Data
14 | @SuperBuilder
15 | @NoArgsConstructor
16 | @AllArgsConstructor
17 | public class FormaDePago {
18 |
19 | @Schema(description = "CREDITO o CONTADO", requiredMode = Schema.RequiredMode.REQUIRED)
20 | private String tipo;
21 |
22 | @Schema(description = "Monto total de pago", requiredMode = Schema.RequiredMode.REQUIRED, minimum = "0")
23 | private BigDecimal total;
24 |
25 | @Schema(description = "Cuotas de pago")
26 | @Singular
27 | private List cuotas;
28 | }
29 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/mappers/common/ClienteMapper.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.jaxb.mappers.common;
2 |
3 | import io.github.project.openubl.xbuilder.content.jaxb.models.XMLCustomer;
4 | import io.github.project.openubl.xbuilder.content.models.common.Cliente;
5 | import org.mapstruct.Mapper;
6 | import org.mapstruct.Mapping;
7 |
8 | @Mapper(uses = {
9 | ContactoMapper.class,
10 | DireccionMapper.class
11 | })
12 | public interface ClienteMapper {
13 |
14 | @Mapping(target = "tipoDocumentoIdentidad", source = "partyIdentification.id.schemeID")
15 | @Mapping(target = "numeroDocumentoIdentidad", source = "partyIdentification.id.value")
16 | @Mapping(target = "nombre", source = "partyLegalEntity.registrationName")
17 | @Mapping(target = "direccion", source = "partyLegalEntity.address")
18 | @Mapping(target = "contacto", source = "contact")
19 | Cliente map(XMLCustomer xml);
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/.github/workflows/backport.yml:
--------------------------------------------------------------------------------
1 | on:
2 | pull_request_target:
3 | types: [ "labeled", "closed" ]
4 |
5 | jobs:
6 | backport:
7 | name: Backport PR
8 | runs-on: ubuntu-latest
9 | if: |
10 | github.event.pull_request.merged == true
11 | && contains(github.event.pull_request.labels.*.name, 'auto-backport')
12 | && (
13 | (github.event.action == 'labeled' && github.event.label.name == 'auto-backport')
14 | || (github.event.action == 'closed')
15 | )
16 | steps:
17 | - name: Backport Action
18 | uses: sqren/backport-github-action@v9.5.1
19 | with:
20 | github_token: ${{ secrets.GITHUB_TOKEN }}
21 | auto_backport_label_prefix: auto-backport-to-
22 | add_original_reviewers: true
23 |
24 | - name: Info log
25 | if: ${{ success() }}
26 | run: cat ~/.backport/backport.info.log
27 |
28 | - name: Debug log
29 | if: ${{ failure() }}
30 | run: cat ~/.backport/backport.debug.log
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/baja/VoidedDocumentsItem.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.sunat.baja;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | @Data
10 | @Builder
11 | @NoArgsConstructor
12 | @AllArgsConstructor
13 | public class VoidedDocumentsItem {
14 | /**
15 | * Serie del comprobante
16 | */
17 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
18 | private String serie;
19 |
20 | /**
21 | * Número del comprobante
22 | */
23 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, minimum = "1", maximum = "99999999")
24 | private Integer numero;
25 |
26 | @Schema(description = "Catalogo 01")
27 | private String tipoComprobante;
28 |
29 | @Schema(description = "Descripción de la razón de baja")
30 | private String descripcionSustento;
31 | }
32 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLInvoice.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.jaxb.models;
2 |
3 | import lombok.Data;
4 | import lombok.EqualsAndHashCode;
5 | import lombok.NoArgsConstructor;
6 |
7 | import jakarta.xml.bind.annotation.XmlAccessType;
8 | import jakarta.xml.bind.annotation.XmlAccessorType;
9 | import jakarta.xml.bind.annotation.XmlElement;
10 | import jakarta.xml.bind.annotation.XmlRootElement;
11 | import java.util.List;
12 |
13 | @XmlAccessorType(XmlAccessType.NONE)
14 | @XmlRootElement(name = "Invoice", namespace = "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2")
15 | @EqualsAndHashCode(callSuper = true)
16 | @Data
17 | @NoArgsConstructor
18 | public class XMLInvoice extends XMLSalesDocument {
19 | @XmlElement(name = "LegalMonetaryTotal", namespace = XMLConstants.CAC)
20 | private MonetaryTotal monetaryTotal;
21 |
22 | @XmlElement(name = "InvoiceLine", namespace = XMLConstants.CAC)
23 | private List lines;
24 | }
25 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/mappers/common/DireccionMapper.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.jaxb.mappers.common;
2 |
3 | import io.github.project.openubl.xbuilder.content.jaxb.models.XMLAddress;
4 | import io.github.project.openubl.xbuilder.content.models.common.Direccion;
5 | import org.mapstruct.Mapper;
6 | import org.mapstruct.Mapping;
7 |
8 | @Mapper
9 | public interface DireccionMapper {
10 |
11 | @Mapping(target = "ubigeo", source = "id")
12 | @Mapping(target = "codigoLocal", source = "addressTypeCode")
13 | @Mapping(target = "urbanizacion", source = "citySubdivisionName")
14 | @Mapping(target = "provincia", source = "cityName")
15 | @Mapping(target = "departamento", source = "countrySubEntity")
16 | @Mapping(target = "distrito", source = "district")
17 | @Mapping(target = "codigoPais", source = "country.identificationCode")
18 | @Mapping(target = "direccion", source = "addressLine.line")
19 | Direccion map(XMLAddress xml);
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/xbuilder/quarkus-extension/runtime/src/main/java/io/github/project/openubl/quarkus/xbuilder/XBuilder.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.quarkus.xbuilder;
2 |
3 | import io.github.project.openubl.xbuilder.enricher.config.Defaults;
4 | import io.quarkus.qute.Template;
5 |
6 | public interface XBuilder {
7 | Template getTemplate(Type type);
8 |
9 | Defaults getDefaults();
10 |
11 | enum Type {
12 | INVOICE("invoice.xml"),
13 | CREDIT_NOTE("creditNote.xml"),
14 | DEBIT_NOTE("debitNote.xml"),
15 | VOIDED_DOCUMENTS("voidedDocuments.xml"),
16 | SUMMARY_DOCUMENTS("summaryDocuments.xml"),
17 | PERCEPTION("perception.xml"),
18 | RETENTION("retention.xml"),
19 | DESPATCH_ADVICE("despatchAdvice.xml");
20 |
21 | private final String templatePath;
22 |
23 | Type(String templatePath) {
24 | this.templatePath = templatePath;
25 | }
26 |
27 | public String getTemplatePath() {
28 | return templatePath;
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLDebitNote.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.jaxb.models;
2 |
3 | import lombok.Data;
4 | import lombok.EqualsAndHashCode;
5 | import lombok.NoArgsConstructor;
6 |
7 | import jakarta.xml.bind.annotation.XmlAccessType;
8 | import jakarta.xml.bind.annotation.XmlAccessorType;
9 | import jakarta.xml.bind.annotation.XmlElement;
10 | import jakarta.xml.bind.annotation.XmlRootElement;
11 | import java.util.List;
12 |
13 | @XmlAccessorType(XmlAccessType.NONE)
14 | @XmlRootElement(name = "DebitNote", namespace = "urn:oasis:names:specification:ubl:schema:xsd:DebitNote-2")
15 | @EqualsAndHashCode(callSuper = true)
16 | @Data
17 | @NoArgsConstructor
18 | public class XMLDebitNote extends XMLSalesDocument {
19 | @XmlElement(name = "RequestedMonetaryTotal", namespace = XMLConstants.CAC)
20 | private MonetaryTotal monetaryTotal;
21 |
22 | @XmlElement(name = "DebitNoteLine", namespace = XMLConstants.CAC)
23 | private List lines;
24 | }
25 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLCreditNote.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.jaxb.models;
2 |
3 | import lombok.Data;
4 | import lombok.EqualsAndHashCode;
5 | import lombok.NoArgsConstructor;
6 |
7 | import jakarta.xml.bind.annotation.XmlAccessType;
8 | import jakarta.xml.bind.annotation.XmlAccessorType;
9 | import jakarta.xml.bind.annotation.XmlElement;
10 | import jakarta.xml.bind.annotation.XmlRootElement;
11 | import java.util.List;
12 |
13 | @XmlAccessorType(XmlAccessType.NONE)
14 | @XmlRootElement(name = "CreditNote", namespace = "urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2")
15 | @EqualsAndHashCode(callSuper = true)
16 | @Data
17 | @NoArgsConstructor
18 | public class XMLCreditNote extends XMLSalesDocument {
19 | @XmlElement(name = "LegalMonetaryTotal", namespace = XMLConstants.CAC)
20 | private MonetaryTotal monetaryTotal;
21 |
22 | @XmlElement(name = "CreditNoteLine", namespace = XMLConstants.CAC)
23 | private List lines;
24 | }
25 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/percepcionretencion/ComprobanteAfectado.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import java.math.BigDecimal;
10 | import java.time.LocalDate;
11 |
12 | @Data
13 | @Builder
14 | @NoArgsConstructor
15 | @AllArgsConstructor
16 | public class ComprobanteAfectado {
17 | private String moneda;
18 |
19 | @Schema(description = "Catalogo 01")
20 | private String tipoComprobante;
21 |
22 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
23 | private String serieNumero;
24 |
25 | @Schema(description = "Format: \"YYYY-MM-SS\". Ejemplo: 2022-12-25", pattern = "^\\d{4}-\\d{2}-\\d{2}$")
26 | private LocalDate fechaEmision;
27 |
28 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
29 | private BigDecimal importeTotal;
30 | }
31 |
--------------------------------------------------------------------------------
/xsender/quarkus-extension/deployment/src/test/java/io/github/project/openubl/quarkus/xsender/test/QuarkusXsenderTest.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.quarkus.xsender.test;
2 |
3 | import io.quarkus.test.QuarkusUnitTest;
4 | import org.jboss.shrinkwrap.api.ShrinkWrap;
5 | import org.jboss.shrinkwrap.api.spec.JavaArchive;
6 | import org.junit.jupiter.api.Assertions;
7 | import org.junit.jupiter.api.Test;
8 | import org.junit.jupiter.api.extension.RegisterExtension;
9 |
10 | public class QuarkusXsenderTest {
11 |
12 | // Start unit test with your extension loaded
13 | @RegisterExtension
14 | static final QuarkusUnitTest unitTest = new QuarkusUnitTest()
15 | .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class));
16 |
17 | @Test
18 | public void writeYourOwnUnitTest() {
19 | // Write your unit tests here - see the testing extension guide https://quarkus.io/guides/writing-extensions#testing-extensions for more information
20 | Assertions.assertTrue(true, "Add some assertions to " + getClass().getName());
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/xbuilder/quarkus-extension/deployment/src/test/java/io/github/project/openubl/quarkus/xbuilder/test/QuarkusXbuilderTest.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.quarkus.xbuilder.test;
2 |
3 | import io.quarkus.test.QuarkusUnitTest;
4 | import org.jboss.shrinkwrap.api.ShrinkWrap;
5 | import org.jboss.shrinkwrap.api.spec.JavaArchive;
6 | import org.junit.jupiter.api.Assertions;
7 | import org.junit.jupiter.api.Test;
8 | import org.junit.jupiter.api.extension.RegisterExtension;
9 |
10 | public class QuarkusXbuilderTest {
11 |
12 | // Start unit test with your extension loaded
13 | @RegisterExtension
14 | static final QuarkusUnitTest unitTest = new QuarkusUnitTest()
15 | .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class));
16 |
17 | @Test
18 | public void writeYourOwnUnitTest() {
19 | // Write your unit tests here - see the testing extension guide https://quarkus.io/guides/writing-extensions#testing-extensions for more information
20 | Assertions.assertTrue(true, "Add some assertions to " + getClass().getName());
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/AbstractHeaderRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie;
2 |
3 | import io.github.project.openubl.xbuilder.enricher.config.Defaults;
4 | import io.github.project.openubl.xbuilder.enricher.kie.ruleunits.HeaderRuleContext;
5 |
6 | public abstract class AbstractHeaderRule implements RuleFactory, Rule {
7 |
8 | private Defaults defaults;
9 | private HeaderRuleContext ruleContext;
10 |
11 | @Override
12 | public Rule create(Defaults defaults, RuleContext ruleContext) {
13 | this.defaults = defaults;
14 | if (ruleContext instanceof HeaderRuleContext) {
15 | this.ruleContext = (HeaderRuleContext) ruleContext;
16 | } else {
17 | throw new IllegalStateException("HeaderRule requires HeaderContext");
18 | }
19 | return this;
20 | }
21 |
22 | public Defaults getDefaults() {
23 | return defaults;
24 | }
25 |
26 | public HeaderRuleContext getRuleContext() {
27 | return ruleContext;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/resources/templates/ubl/standard/include/customer.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {cliente.numeroDocumentoIdentidad}
5 |
6 |
7 |
8 | {#if cliente.direccion}
9 |
10 | {#include ubl/standard/include/address.xml direccion=cliente.direccion /}
11 |
12 | {/if}
13 |
14 | {#if cliente.contacto}
15 | {#include ubl/standard/include/contact.xml contacto=cliente.contacto /}
16 | {/if}
17 |
18 |
19 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/resumen/SummaryDocuments.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.sunat.resumen;
2 |
3 | import io.github.project.openubl.xbuilder.content.models.sunat.SunatDocument;
4 | import io.swagger.v3.oas.annotations.media.ArraySchema;
5 | import io.swagger.v3.oas.annotations.media.Schema;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 | import lombok.NoArgsConstructor;
9 | import lombok.Singular;
10 | import lombok.ToString;
11 | import lombok.experimental.SuperBuilder;
12 | import lombok.extern.jackson.Jacksonized;
13 |
14 | import java.util.List;
15 |
16 | @Jacksonized
17 | @Data
18 | @SuperBuilder
19 | @NoArgsConstructor
20 | @EqualsAndHashCode(callSuper = true)
21 | @ToString(callSuper = true)
22 | public class SummaryDocuments extends SunatDocument {
23 |
24 | /**
25 | * Lista de comprobantes
26 | */
27 | @Singular
28 | @ArraySchema(minItems = 1, schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED))
29 | private List comprobantes;
30 | }
31 |
--------------------------------------------------------------------------------
/xbuilder/core/src/test/java/e2e/enricher/enrich/InvoiceTest.java:
--------------------------------------------------------------------------------
1 | package e2e.enricher.enrich;
2 |
3 | import e2e.AbstractTest;
4 | import io.github.project.openubl.xbuilder.content.catalogs.Catalog1_Invoice;
5 | import io.github.project.openubl.xbuilder.content.models.standard.general.Invoice;
6 | import io.github.project.openubl.xbuilder.enricher.ContentEnricher;
7 | import org.junit.jupiter.api.Test;
8 |
9 | import static org.junit.jupiter.api.Assertions.assertEquals;
10 |
11 | public class InvoiceTest extends AbstractTest {
12 |
13 | @Test
14 | public void testEnrichTipoComprobante() {
15 | // Given
16 | Invoice input = Invoice.builder()
17 | .serie("F001-1")
18 | .tipoComprobante(Catalog1_Invoice.BOLETA.getCode()) // This should be overwritten
19 | .build();
20 |
21 | // When
22 | ContentEnricher enricher = new ContentEnricher(defaults, dateProvider);
23 | enricher.enrich(input);
24 |
25 | // Then
26 | assertEquals(Catalog1_Invoice.FACTURA.getCode(), input.getTipoComprobante());
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/baja/VoidedDocuments.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.sunat.baja;
2 |
3 | import io.github.project.openubl.xbuilder.content.models.sunat.SunatDocument;
4 | import io.swagger.v3.oas.annotations.media.ArraySchema;
5 | import io.swagger.v3.oas.annotations.media.Schema;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 | import lombok.NoArgsConstructor;
9 | import lombok.Singular;
10 | import lombok.ToString;
11 | import lombok.experimental.SuperBuilder;
12 | import lombok.extern.jackson.Jacksonized;
13 |
14 | import java.util.List;
15 |
16 | @Jacksonized
17 | @Data
18 | @SuperBuilder
19 | @NoArgsConstructor
20 | @EqualsAndHashCode(callSuper = true)
21 | @ToString(callSuper = true)
22 | public class VoidedDocuments extends SunatDocument {
23 |
24 | /**
25 | * Lista de comprobantes a dar de baja
26 | */
27 | @Singular
28 | @ArraySchema(minItems = 1, schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED))
29 | private List comprobantes;
30 | }
31 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/catalogs/Catalog.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.catalogs;
2 |
3 | import java.util.Optional;
4 | import java.util.function.Supplier;
5 | import java.util.stream.Stream;
6 |
7 | public interface Catalog {
8 | Supplier extends RuntimeException> invalidCatalogValue = (Supplier) () ->
9 | new IllegalStateException("No se pudo convertir el valor del catálogo");
10 |
11 | /**
12 | * @param Class you want to search for
13 | * @param enumType class you want to search for
14 | * @param code the code or Enum value
15 | * @return an instance of Catalog which is equal to ValueOf or contains the same code
16 | */
17 | static Optional valueOfCode(Class enumType, String code) {
18 | return Stream
19 | .of(enumType.getEnumConstants())
20 | .filter(p -> p.toString().equalsIgnoreCase(code) || p.getCode().equals(code))
21 | .findFirst();
22 | }
23 |
24 | String getCode();
25 | }
26 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/general/CuotaDePago.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.standard.general;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import java.math.BigDecimal;
10 | import java.time.LocalDate;
11 |
12 | /**
13 | * Cuota de pago para Invoice
14 | *
15 | * @author Carlos Feria
16 | */
17 | @Data
18 | @Builder
19 | @NoArgsConstructor
20 | @AllArgsConstructor
21 | public class CuotaDePago {
22 |
23 | /**
24 | * Importe de la cuota
25 | */
26 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, minimum = "0", exclusiveMinimum = true)
27 | private BigDecimal importe;
28 |
29 | /**
30 | * Fecha de pago de la cuota
31 | */
32 | @Schema(description = "Ejemplo 2022-12-25", requiredMode = Schema.RequiredMode.REQUIRED, pattern = "^\\d{4}-\\d{2}-\\d{2}$")
33 | private LocalDate fechaPago;
34 | }
35 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLVoidedDocumentsLine.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.jaxb.models;
2 |
3 | import lombok.Data;
4 | import lombok.NoArgsConstructor;
5 |
6 | import jakarta.xml.bind.annotation.XmlAccessType;
7 | import jakarta.xml.bind.annotation.XmlAccessorType;
8 | import jakarta.xml.bind.annotation.XmlElement;
9 | import jakarta.xml.bind.annotation.XmlType;
10 |
11 | @XmlType(name = "VoidedDocumentsLine")
12 | @XmlAccessorType(XmlAccessType.NONE)
13 | @Data
14 | @NoArgsConstructor
15 | public class XMLVoidedDocumentsLine {
16 |
17 | @XmlElement(name = "DocumentTypeCode", namespace = XMLConstants.CBC)
18 | private String documentTypeCode;
19 |
20 | @XmlElement(name = "DocumentSerialID", namespace = XMLConstants.SAC)
21 | private String documentSerialID;
22 |
23 | @XmlElement(name = "DocumentNumberID", namespace = XMLConstants.SAC)
24 | private Integer documentNumberID;
25 |
26 | @XmlElement(name = "VoidReasonDescription", namespace = XMLConstants.SAC)
27 | private String voidReasonDescription;
28 | }
29 |
--------------------------------------------------------------------------------
/xsender/quarkus-extension/deployment/src/test/java/io/github/project/openubl/quarkus/xsender/test/QuarkusXsenderDevModeTest.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.quarkus.xsender.test;
2 |
3 | import io.quarkus.test.QuarkusDevModeTest;
4 | import org.jboss.shrinkwrap.api.ShrinkWrap;
5 | import org.jboss.shrinkwrap.api.spec.JavaArchive;
6 | import org.junit.jupiter.api.Assertions;
7 | import org.junit.jupiter.api.Test;
8 | import org.junit.jupiter.api.extension.RegisterExtension;
9 |
10 | public class QuarkusXsenderDevModeTest {
11 |
12 | // Start hot reload (DevMode) test with your extension loaded
13 | @RegisterExtension
14 | static final QuarkusDevModeTest devModeTest = new QuarkusDevModeTest()
15 | .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class));
16 |
17 | @Test
18 | public void writeYourOwnDevModeTest() {
19 | // Write your dev mode tests here - see the testing extension guide https://quarkus.io/guides/writing-extensions#testing-hot-reload for more information
20 | Assertions.assertTrue(true, "Add dev mode assertions to " + getClass().getName());
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/xbuilder/quarkus-extension/deployment/src/test/java/io/github/project/openubl/quarkus/xbuilder/test/QuarkusXbuilderDevModeTest.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.quarkus.xbuilder.test;
2 |
3 | import io.quarkus.test.QuarkusDevModeTest;
4 | import org.jboss.shrinkwrap.api.ShrinkWrap;
5 | import org.jboss.shrinkwrap.api.spec.JavaArchive;
6 | import org.junit.jupiter.api.Assertions;
7 | import org.junit.jupiter.api.Test;
8 | import org.junit.jupiter.api.extension.RegisterExtension;
9 |
10 | public class QuarkusXbuilderDevModeTest {
11 |
12 | // Start hot reload (DevMode) test with your extension loaded
13 | @RegisterExtension
14 | static final QuarkusDevModeTest devModeTest = new QuarkusDevModeTest()
15 | .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class));
16 |
17 | @Test
18 | public void writeYourOwnDevModeTest() {
19 | // Write your dev mode tests here - see the testing extension guide https://quarkus.io/guides/writing-extensions#testing-hot-reload for more information
20 | Assertions.assertTrue(true, "Add dev mode assertions to " + getClass().getName());
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/xsender/core/src/main/java/io/github/project/openubl/xsender/sunat/catalog/Catalog1.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xsender.sunat.catalog;
2 |
3 | import java.util.Optional;
4 | import java.util.stream.Stream;
5 |
6 | public enum Catalog1 {
7 | FACTURA("01"),
8 | BOLETA("03"),
9 | NOTA_CREDITO("07"),
10 | NOTA_DEBITO("08"),
11 | GUIA_REMISION_REMITENTE("09"),
12 | TICKET_MAQUINA_REGISTRADORA("12"),
13 | DOCUMENTOS_FINANCIEROS("13"),
14 | DOCUMENTOS_AFP("18"),
15 | GUIA_REMISION_TRANSPORTISTA("31"),
16 | COMPROBANTE_PAGO_SEAE("56"),
17 | GUIA_REMISION_REMITENTE_COMPLEMENTARIA("71"),
18 | GUIA_REMISION_TRANSPORTISTA_COMPLEMENTARIA("72"),
19 |
20 | RETENCION("20"),
21 | PERCEPCION("40"),
22 | PERCEPCION_VENTA_INTERNA("21");
23 |
24 | private final String code;
25 |
26 | Catalog1(String code) {
27 | this.code = code;
28 | }
29 |
30 | public String getCode() {
31 | return code;
32 | }
33 |
34 | public static Optional valueOfCode(String code) {
35 | return Stream.of(Catalog1.values()).filter(p -> p.getCode().equals(code)).findFirst();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/mappers/common/SerieNumeroMapper.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.jaxb.mappers.common;
2 |
3 | @SerieNumeroTranslator
4 | public class SerieNumeroMapper {
5 |
6 | @SerieTranslator
7 | public String toSerie(String serieNumero) {
8 | if (serieNumero == null) {
9 | return null;
10 | }
11 |
12 | String[] split = serieNumero.split("-");
13 | return split.length >= 1 ? split[0] : null;
14 | }
15 |
16 | @Numero2Translator
17 | public Integer toNumero2(String serieNumero) {
18 | if (serieNumero == null) {
19 | return null;
20 | }
21 |
22 | String[] split = serieNumero.split("-");
23 | return split.length >= 2 ? Integer.parseInt(split[1]) : null;
24 | }
25 |
26 | @Numero3Translator
27 | public Integer toNumero3(String serieNumero) {
28 | if (serieNumero == null) {
29 | return null;
30 | }
31 |
32 | String[] split = serieNumero.split("-");
33 | return split.length >= 3 ? Integer.parseInt(split[2]) : null;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/xsender/core/src/main/java/io/github/project/openubl/xsender/sunat/BillServiceDestination.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xsender.sunat;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.Getter;
7 | import org.apache.camel.component.http.HttpMethods;
8 |
9 | @Data
10 | @Builder
11 | @AllArgsConstructor
12 | public class BillServiceDestination {
13 | private final String url;
14 | private final SoapOperation soapOperation;
15 | private final RestOperation restOperation;
16 |
17 | @Getter
18 | @AllArgsConstructor
19 | public enum SoapOperation {
20 | SEND_BILL("sendBill"),
21 | SEND_SUMMARY("sendSummary"),
22 | SEND_PACK("sendPack"),
23 | GET_STATUS("getStatus");
24 |
25 | private final String webMethod;
26 | }
27 |
28 | @Getter
29 | @AllArgsConstructor
30 | public enum RestOperation {
31 | SEND_DOCUMENT(HttpMethods.POST, "/comprobantes"),
32 | VERIFY_TICKET(HttpMethods.GET, "/comprobantes/envios");
33 |
34 | private final HttpMethods method;
35 | private final String path;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/catalogs/Catalog1.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.catalogs;
2 |
3 | import java.util.Optional;
4 | import java.util.stream.Stream;
5 |
6 | public enum Catalog1 implements Catalog {
7 | FACTURA("01"),
8 | BOLETA("03"),
9 | NOTA_CREDITO("07"),
10 | NOTA_DEBITO("08"),
11 | GUIA_REMISION_REMITENTE("09"),
12 | TICKET_MAQUINA_REGISTRADORA("12"),
13 | DOCUMENTOS_FINANCIEROS("13"),
14 | DOCUMENTOS_AFP("18"),
15 | GUIA_REMISION_TRANSPORTISTA("31"),
16 | COMPROBANTE_PAGO_SEAE("56"),
17 | GUIA_REMISION_REMITENTE_COMPLEMENTARIA("71"),
18 | GUIA_REMISION_TRANSPORTISTA_COMPLEMENTARIA("72"),
19 |
20 | RETENCION("20"),
21 | PERCEPCION("40"),
22 | PERCEPCION_VENTA_INTERNA("21");
23 |
24 | private final String code;
25 |
26 | Catalog1(String code) {
27 | this.code = code;
28 | }
29 |
30 | public static Optional valueOfCode(String code) {
31 | return Stream.of(Catalog1.values()).filter(p -> p.code.equals(code)).findFirst();
32 | }
33 |
34 | @Override
35 | public String getCode() {
36 | return code;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/SunatDocument.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.sunat;
2 |
3 | import io.github.project.openubl.xbuilder.content.models.common.Document;
4 | import io.swagger.v3.oas.annotations.media.Schema;
5 | import lombok.Data;
6 | import lombok.EqualsAndHashCode;
7 | import lombok.NoArgsConstructor;
8 | import lombok.ToString;
9 | import lombok.experimental.SuperBuilder;
10 |
11 | import java.time.LocalDate;
12 |
13 | @Data
14 | @SuperBuilder
15 | @NoArgsConstructor
16 | @EqualsAndHashCode(callSuper = true)
17 | @ToString(callSuper = true)
18 | public class SunatDocument extends Document {
19 |
20 | /**
21 | * Numero de comprobante emitido para la fecha de emision dada
22 | */
23 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, minimum = "1", maximum = "99999999")
24 | private Integer numero;
25 |
26 | /**
27 | * Fecha de emisión de los comprobantes dados de baja. Ejemplo 2022-12-25 (YYYY-MM-SS)
28 | */
29 | @Schema(description = "Format: \"YYYY-MM-SS\". Ejemplo: 2022-12-25", pattern = "^\\d{4}-\\d{2}-\\d{2}$")
30 | private LocalDate fechaEmisionComprobantes;
31 | }
32 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Transportista.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.standard.guia;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | @Data
10 | @Builder
11 | @NoArgsConstructor
12 | @AllArgsConstructor
13 | public class Transportista {
14 |
15 | @Schema(description = "Catalogo 06", requiredMode = Schema.RequiredMode.REQUIRED)
16 | private String tipoDocumentoIdentidad;
17 |
18 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
19 | private String numeroDocumentoIdentidad;
20 |
21 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
22 | private String nombre;
23 |
24 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
25 | private String placaDelVehiculo;
26 |
27 | @Schema(description = "Catalogo 06", requiredMode = Schema.RequiredMode.REQUIRED)
28 | private String choferTipoDocumentoIdentidad;
29 |
30 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
31 | private String choferNumeroDocumentoIdentidad;
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/RuleFactoryRegistry.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie;
2 |
3 | import java.util.List;
4 | import java.util.Map;
5 | import java.util.ServiceLoader;
6 | import java.util.stream.Collectors;
7 |
8 | public class RuleFactoryRegistry {
9 |
10 | public static List getRuleFactories(RulePhase.PhaseType phaseType) {
11 | return ServiceLoader
12 | .load(RuleFactory.class)
13 | .stream()
14 | .map(ruleProvider -> {
15 | RulePhase rulePhase = ruleProvider.type().getAnnotation(RulePhase.class);
16 | return Map.entry(ruleProvider, rulePhase);
17 | })
18 | .filter(ruleProviderPhaseEntry -> {
19 | RulePhase rulePhase = ruleProviderPhaseEntry.getValue();
20 | return rulePhase.type().equals(phaseType);
21 | })
22 | .sorted((o1, o2) -> o2.getValue().priority() - o1.getValue().priority())
23 | .map(ruleProviderPhaseEntry -> ruleProviderPhaseEntry.getKey().get())
24 | .collect(Collectors.toList());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/resources/templates/ubl/standard/include/supplier.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {proveedor.ruc}
5 |
6 | {#if proveedor.nombreComercial}
7 |
8 | {proveedor.nombreComercial}
9 |
10 | {/if}
11 |
12 |
13 | {#if proveedor.direccion}
14 |
15 | {#include ubl/standard/include/address.xml direccion=proveedor.direccion /}
16 |
17 | {/if}
18 |
19 | {#if proveedor.contacto}
20 | {#include ubl/standard/include/contact.xml contacto=proveedor.contacto /}
21 | {/if}
22 |
23 |
24 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/header/MonedaRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.rules.enrich.header;
2 |
3 | import io.github.project.openubl.xbuilder.content.models.common.Document;
4 | import io.github.project.openubl.xbuilder.enricher.kie.AbstractHeaderRule;
5 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
6 |
7 | import java.util.function.Consumer;
8 |
9 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isDocument;
10 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenDocument;
11 |
12 | @RulePhase(type = RulePhase.PhaseType.ENRICH)
13 | public class MonedaRule extends AbstractHeaderRule {
14 |
15 | @Override
16 | public boolean test(Object object) {
17 | return (
18 | isDocument.test(object) &&
19 | whenDocument.apply(object).map(documento -> documento.getMoneda() == null).orElse(false)
20 | );
21 | }
22 |
23 | @Override
24 | public void modify(Object object) {
25 | Consumer consumer = document -> document.setMoneda("PEN");
26 | whenDocument.apply(object).ifPresent(consumer);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/percepcionretencion/Perception.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import lombok.Data;
5 | import lombok.EqualsAndHashCode;
6 | import lombok.NoArgsConstructor;
7 | import lombok.ToString;
8 | import lombok.experimental.SuperBuilder;
9 | import lombok.extern.jackson.Jacksonized;
10 |
11 | import java.math.BigDecimal;
12 |
13 | @Jacksonized
14 | @Data
15 | @SuperBuilder
16 | @NoArgsConstructor
17 | @EqualsAndHashCode(callSuper = true)
18 | @ToString(callSuper = true)
19 | public class Perception extends BasePercepcionRetencion {
20 | /**
21 | * Serie del comprobante
22 | */
23 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, minLength = 4, pattern = "^[P|p].*$")
24 | private String serie;
25 |
26 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, description = "Catalog 22")
27 | private String tipoRegimen;
28 |
29 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, minimum = "0")
30 | private BigDecimal importeTotalPercibido;
31 |
32 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, minimum = "0")
33 | private BigDecimal importeTotalCobrado;
34 | }
35 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/percepcionretencion/Retention.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import lombok.Data;
5 | import lombok.EqualsAndHashCode;
6 | import lombok.NoArgsConstructor;
7 | import lombok.ToString;
8 | import lombok.experimental.SuperBuilder;
9 | import lombok.extern.jackson.Jacksonized;
10 |
11 | import java.math.BigDecimal;
12 |
13 | @Jacksonized
14 | @Data
15 | @SuperBuilder
16 | @NoArgsConstructor
17 | @EqualsAndHashCode(callSuper = true)
18 | @ToString(callSuper = true)
19 | public class Retention extends BasePercepcionRetencion {
20 | /**
21 | * Serie del comprobante
22 | */
23 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, minLength = 4, pattern = "^[R|r].*$")
24 | private String serie;
25 |
26 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, description = "Catalog 23")
27 | private String tipoRegimen;
28 |
29 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, minimum = "0")
30 | private BigDecimal importeTotalRetenido;
31 |
32 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, minimum = "0")
33 | private BigDecimal importeTotalPagado;
34 | }
35 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLInvoiceLine.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.jaxb.models;
2 |
3 | import lombok.Data;
4 | import lombok.EqualsAndHashCode;
5 | import lombok.NoArgsConstructor;
6 |
7 | import jakarta.xml.bind.annotation.XmlAccessType;
8 | import jakarta.xml.bind.annotation.XmlAccessorType;
9 | import jakarta.xml.bind.annotation.XmlAttribute;
10 | import jakarta.xml.bind.annotation.XmlElement;
11 | import jakarta.xml.bind.annotation.XmlType;
12 | import jakarta.xml.bind.annotation.XmlValue;
13 | import java.math.BigDecimal;
14 |
15 | @XmlType(name = "InvoiceDocumentLine")
16 | @XmlAccessorType(XmlAccessType.NONE)
17 | @Data
18 | @EqualsAndHashCode(callSuper = true)
19 | @NoArgsConstructor
20 | public class XMLInvoiceLine extends XMLSalesDocumentLine {
21 | @XmlElement(name = "InvoicedQuantity", namespace = XMLConstants.CBC)
22 | private Quantity quantity;
23 |
24 | @XmlAccessorType(XmlAccessType.NONE)
25 | @XmlType(name = "InvoiceDocumentLine.Quantity")
26 | @Data
27 | @NoArgsConstructor
28 | public static class Quantity {
29 | @XmlValue
30 | private BigDecimal value;
31 |
32 | @XmlAttribute(name = "unitCode")
33 | private String unitCode;
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/percepcionretencion/PercepcionRetencionOperacion.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion;
2 |
3 | import io.github.project.openubl.xbuilder.content.models.common.TipoCambio;
4 | import io.swagger.v3.oas.annotations.media.Schema;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | import java.math.BigDecimal;
11 | import java.time.LocalDate;
12 |
13 | @Data
14 | @Builder
15 | @NoArgsConstructor
16 | @AllArgsConstructor
17 | public class PercepcionRetencionOperacion {
18 |
19 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, description = "Numero de cobro o pago")
20 | private Integer numeroOperacion;
21 |
22 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, description = "Fecha en la que se realiza el cobro o pago")
23 | private LocalDate fechaOperacion;
24 |
25 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, description = "Importe del cobro o pago")
26 | private BigDecimal importeOperacion;
27 |
28 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
29 | private ComprobanteAfectado comprobante;
30 |
31 | private TipoCambio tipoCambio;
32 | }
33 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLDebitNoteLine.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.jaxb.models;
2 |
3 | import lombok.Data;
4 | import lombok.EqualsAndHashCode;
5 | import lombok.NoArgsConstructor;
6 |
7 | import jakarta.xml.bind.annotation.XmlAccessType;
8 | import jakarta.xml.bind.annotation.XmlAccessorType;
9 | import jakarta.xml.bind.annotation.XmlAttribute;
10 | import jakarta.xml.bind.annotation.XmlElement;
11 | import jakarta.xml.bind.annotation.XmlType;
12 | import jakarta.xml.bind.annotation.XmlValue;
13 | import java.math.BigDecimal;
14 |
15 | @XmlType(name = "DebitNoteDocumentLine")
16 | @XmlAccessorType(XmlAccessType.NONE)
17 | @Data
18 | @EqualsAndHashCode(callSuper = true)
19 | @NoArgsConstructor
20 | public class XMLDebitNoteLine extends XMLSalesDocumentLine {
21 | @XmlElement(name = "DebitedQuantity", namespace = XMLConstants.CBC)
22 | private Quantity quantity;
23 |
24 | @XmlAccessorType(XmlAccessType.NONE)
25 | @XmlType(name = "DebitNoteDocumentLine.Quantity")
26 | @Data
27 | @NoArgsConstructor
28 | public static class Quantity {
29 | @XmlValue
30 | private BigDecimal value;
31 |
32 | @XmlAttribute(name = "unitCode")
33 | private String unitCode;
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLCreditNoteLine.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.jaxb.models;
2 |
3 | import lombok.Data;
4 | import lombok.EqualsAndHashCode;
5 | import lombok.NoArgsConstructor;
6 |
7 | import jakarta.xml.bind.annotation.XmlAccessType;
8 | import jakarta.xml.bind.annotation.XmlAccessorType;
9 | import jakarta.xml.bind.annotation.XmlAttribute;
10 | import jakarta.xml.bind.annotation.XmlElement;
11 | import jakarta.xml.bind.annotation.XmlType;
12 | import jakarta.xml.bind.annotation.XmlValue;
13 | import java.math.BigDecimal;
14 |
15 | @XmlType(name = "CreditNoteDocumentLine")
16 | @XmlAccessorType(XmlAccessType.NONE)
17 | @Data
18 | @EqualsAndHashCode(callSuper = true)
19 | @NoArgsConstructor
20 | public class XMLCreditNoteLine extends XMLSalesDocumentLine {
21 | @XmlElement(name = "CreditedQuantity", namespace = XMLConstants.CBC)
22 | private Quantity quantity;
23 |
24 | @XmlAccessorType(XmlAccessType.NONE)
25 | @XmlType(name = "CreditNoteDocumentLine.Quantity")
26 | @Data
27 | @NoArgsConstructor
28 | public static class Quantity {
29 | @XmlValue
30 | private BigDecimal value;
31 |
32 | @XmlAttribute(name = "unitCode")
33 | private String unitCode;
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/resumen/Comprobante.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.sunat.resumen;
2 |
3 | import io.github.project.openubl.xbuilder.content.models.common.Cliente;
4 | import io.swagger.v3.oas.annotations.media.Schema;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | @Data
11 | @Builder
12 | @NoArgsConstructor
13 | @AllArgsConstructor
14 | public class Comprobante {
15 |
16 | @Schema(requiredMode = Schema.RequiredMode.AUTO, description = "Moneda del comprobante declarado")
17 | private String moneda;
18 |
19 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, description = "Catalogo 01")
20 | private String tipoComprobante;
21 |
22 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
23 | private String serieNumero;
24 |
25 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
26 | private Cliente cliente;
27 |
28 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
29 | private ComprobanteValorVenta valorVenta;
30 |
31 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
32 | private ComprobanteImpuestos impuestos;
33 |
34 | private ComprobanteAfectado comprobanteAfectado;
35 | }
36 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/catalogs/Catalog5.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.catalogs;
2 |
3 | public enum Catalog5 implements Catalog {
4 | IGV("1000", "VAT", "S", "IGV"),
5 | IMPUESTO_ARROZ_PILADO("1016", "VAT", "S", "IVAP"),
6 | ISC("2000", "EXC", "S", "ISC"),
7 | EXPORTACION("9995", "FRE", "S", "EXP"),
8 | GRATUITO("9996", "FRE", "S", "GRA"),
9 | EXONERADO("9997", "VAT", "S", "EXO"),
10 | INAFECTO("9998", "FRE", "S", "INA"),
11 | ICBPER("7152", "OTH", "S", "ICBPER"),
12 | OTROS("9999", "OTH", "S", "OTROS");
13 |
14 | private final String code;
15 | private final String tipo;
16 | private final String categoria;
17 | private final String nombre;
18 |
19 | Catalog5(String code, String tipo, String categoria, String nombre) {
20 | this.code = code;
21 | this.tipo = tipo;
22 | this.categoria = categoria;
23 | this.nombre = nombre;
24 | }
25 |
26 | @Override
27 | public String getCode() {
28 | return code;
29 | }
30 |
31 | public String getTipo() {
32 | return tipo;
33 | }
34 |
35 | public String getCategoria() {
36 | return categoria;
37 | }
38 |
39 | public String getNombre() {
40 | return nombre;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/header/TasaIgvRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.rules.enrich.header;
2 |
3 | import io.github.project.openubl.xbuilder.content.models.standard.general.SalesDocument;
4 | import io.github.project.openubl.xbuilder.enricher.kie.AbstractHeaderRule;
5 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
6 |
7 | import java.util.function.Consumer;
8 |
9 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isSalesDocument;
10 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenSalesDocument;
11 |
12 | @RulePhase(type = RulePhase.PhaseType.ENRICH)
13 | public class TasaIgvRule extends AbstractHeaderRule {
14 |
15 | @Override
16 | public boolean test(Object object) {
17 | return (isSalesDocument.test(object) && whenSalesDocument.apply(object)
18 | .map(documento -> documento.getTasaIgv() == null)
19 | .orElse(false)
20 | );
21 | }
22 |
23 | @Override
24 | public void modify(Object object) {
25 | Consumer consumer = document -> document.setTasaIgv(getDefaults().getIgvTasa());
26 | whenSalesDocument.apply(object).ifPresent(consumer);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/common/Proveedor.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.common;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | /**
10 | * Persona que vende o presta un servicio
11 | *
12 | * @author Carlos Feria
13 | */
14 | @Data
15 | @Builder
16 | @NoArgsConstructor
17 | @AllArgsConstructor
18 | public class Proveedor {
19 |
20 | /**
21 | * Número de RUC de la persona jurídica
22 | */
23 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, minLength = 11, maxLength = 11, pattern = "[0-9]+")
24 | private String ruc;
25 |
26 | /**
27 | * Nombre comercial de la persona jurídica
28 | */
29 | private String nombreComercial;
30 |
31 | /**
32 | * Razón social de la persona jurídica
33 | */
34 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
35 | private String razonSocial;
36 |
37 | /**
38 | * Dirección de la persona jurídica
39 | */
40 | private Direccion direccion;
41 |
42 | /**
43 | * Contacto de la persona jurídica
44 | */
45 | private Contacto contacto;
46 | }
47 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/header/TasaIvapRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.rules.enrich.header;
2 |
3 | import io.github.project.openubl.xbuilder.content.models.standard.general.SalesDocument;
4 | import io.github.project.openubl.xbuilder.enricher.kie.AbstractHeaderRule;
5 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
6 |
7 | import java.util.function.Consumer;
8 |
9 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isSalesDocument;
10 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenSalesDocument;
11 |
12 | @RulePhase(type = RulePhase.PhaseType.ENRICH)
13 | public class TasaIvapRule extends AbstractHeaderRule {
14 |
15 | @Override
16 | public boolean test(Object object) {
17 | return (isSalesDocument.test(object) && whenSalesDocument.apply(object)
18 | .map(documento -> documento.getTasaIvap() == null)
19 | .orElse(false)
20 | );
21 | }
22 |
23 | @Override
24 | public void modify(Object object) {
25 | Consumer consumer = document -> document.setTasaIvap(getDefaults().getIvapTasa());
26 | whenSalesDocument.apply(object).ifPresent(consumer);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/common/Document.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.common;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 | import lombok.experimental.SuperBuilder;
7 |
8 | import java.time.LocalDate;
9 |
10 | @Data
11 | @SuperBuilder
12 | @NoArgsConstructor
13 | public abstract class Document {
14 |
15 | /**
16 | * Moneda en la que se emite el comprobante
17 | */
18 | @Schema(minLength = 3, maxLength = 3)
19 | private String moneda;
20 |
21 | /**
22 | * Fecha de emisión del comprobante. Ejemplo 2022-12-25 (YYYY-MM-SS)
23 | */
24 | @Schema(description = "Format: \"YYYY-MM-SS\". Ejemplo: 2022-12-25", pattern = "^\\d{4}-\\d{2}-\\d{2}$")
25 | private LocalDate fechaEmision;
26 |
27 | /**
28 | * Proveedor del bien o servicio
29 | */
30 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
31 | private Proveedor proveedor;
32 |
33 | /**
34 | * Persona que firma electrónicamente el comprobante. Si es NULL los datos del proveedor son usados.
35 | */
36 | @Schema(description = "Persona que firma el comprobante. Si NULL los datos del proveedor son usados.")
37 | private Firmante firmante;
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/header/TasaIcbRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.rules.enrich.header;
2 |
3 | import io.github.project.openubl.xbuilder.content.models.standard.general.SalesDocument;
4 | import io.github.project.openubl.xbuilder.enricher.kie.AbstractHeaderRule;
5 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
6 |
7 | import java.util.function.Consumer;
8 |
9 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isSalesDocument;
10 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenSalesDocument;
11 |
12 | @RulePhase(type = RulePhase.PhaseType.ENRICH)
13 | public class TasaIcbRule extends AbstractHeaderRule {
14 |
15 | @Override
16 | public boolean test(Object object) {
17 | return (
18 | isSalesDocument.test(object) &&
19 | whenSalesDocument.apply(object).map(documento -> documento.getTasaIcb() == null).orElse(false)
20 | );
21 | }
22 |
23 | @Override
24 | public void modify(Object object) {
25 | Consumer consumer = document -> document.setTasaIcb(getDefaults().getIcbTasa());
26 | whenSalesDocument.apply(object).ifPresent(consumer);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/body/descuento/FactorRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.rules.enrich.body.descuento;
2 |
3 | import io.github.project.openubl.xbuilder.content.models.standard.general.Descuento;
4 | import io.github.project.openubl.xbuilder.enricher.kie.AbstractBodyRule;
5 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
6 |
7 | import java.math.BigDecimal;
8 | import java.util.function.Consumer;
9 |
10 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isDescuento;
11 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenDescuento;
12 |
13 | @RulePhase(type = RulePhase.PhaseType.ENRICH)
14 | public class FactorRule extends AbstractBodyRule {
15 |
16 | @Override
17 | public boolean test(Object object) {
18 | return isDescuento.test(object) && whenDescuento.apply(object)
19 | .map(descuento -> descuento.getFactor() == null)
20 | .orElse(false);
21 | }
22 |
23 | @Override
24 | public void modify(Object object) {
25 | Consumer consumer = descuento -> {
26 | descuento.setFactor(BigDecimal.ONE);
27 | };
28 | whenDescuento.apply(object).ifPresent(consumer);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLRetention.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.jaxb.models;
2 |
3 | import lombok.Data;
4 | import lombok.EqualsAndHashCode;
5 | import lombok.NoArgsConstructor;
6 |
7 | import jakarta.xml.bind.annotation.XmlAccessType;
8 | import jakarta.xml.bind.annotation.XmlAccessorType;
9 | import jakarta.xml.bind.annotation.XmlElement;
10 | import jakarta.xml.bind.annotation.XmlRootElement;
11 | import java.math.BigDecimal;
12 |
13 | @XmlAccessorType(XmlAccessType.NONE)
14 | @XmlRootElement(name = "Retention", namespace = "urn:sunat:names:specification:ubl:peru:schema:xsd:Retention-1")
15 | @EqualsAndHashCode(callSuper = true)
16 | @Data
17 | @NoArgsConstructor
18 | public class XMLRetention extends XMLPercepcionRetencionBase {
19 | @XmlElement(name = "SUNATRetentionSystemCode", namespace = XMLConstants.SAC)
20 | private String sunatSystemCode;
21 |
22 | @XmlElement(name = "SUNATRetentionPercent", namespace = XMLConstants.SAC)
23 | private BigDecimal sunatPercent;
24 |
25 | @XmlElement(name = "SUNATTotalPaid", namespace = XMLConstants.SAC)
26 | private BigDecimal sunatTotal;
27 |
28 | @XmlElement(name = "SUNATRetentionDocumentReference", namespace = XMLConstants.SAC)
29 | private XMLRetentionSunatDocumentReference sunatDocumentReference;
30 | }
31 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/body/descuento/MontoBaseRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.rules.enrich.body.descuento;
2 |
3 | import io.github.project.openubl.xbuilder.content.models.standard.general.Descuento;
4 | import io.github.project.openubl.xbuilder.enricher.kie.AbstractBodyRule;
5 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
6 |
7 | import java.util.function.Consumer;
8 |
9 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isDescuento;
10 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenDescuento;
11 |
12 | @RulePhase(type = RulePhase.PhaseType.ENRICH)
13 | public class MontoBaseRule extends AbstractBodyRule {
14 |
15 | @Override
16 | public boolean test(Object object) {
17 | return isDescuento.test(object) && whenDescuento.apply(object)
18 | .map(descuento -> descuento.getMontoBase() == null && descuento.getMonto() != null)
19 | .orElse(false);
20 | }
21 |
22 | @Override
23 | public void modify(Object object) {
24 | Consumer consumer = descuento -> {
25 | descuento.setMontoBase(descuento.getMonto());
26 | };
27 | whenDescuento.apply(object).ifPresent(consumer);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/body/detalle/UnidadDeMedidaRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.rules.enrich.body.detalle;
2 |
3 | import io.github.project.openubl.xbuilder.content.models.standard.general.DocumentoVentaDetalle;
4 | import io.github.project.openubl.xbuilder.enricher.kie.AbstractBodyRule;
5 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
6 |
7 | import java.util.function.Consumer;
8 |
9 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isSalesDocumentItem;
10 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenSalesDocumentItem;
11 |
12 | @RulePhase(type = RulePhase.PhaseType.ENRICH)
13 | public class UnidadDeMedidaRule extends AbstractBodyRule {
14 |
15 | @Override
16 | public boolean test(Object object) {
17 | return (isSalesDocumentItem.test(object) && whenSalesDocumentItem.apply(object)
18 | .map(documento -> documento.getUnidadMedida() == null)
19 | .orElse(false)
20 | );
21 | }
22 |
23 | @Override
24 | public void modify(Object object) {
25 | Consumer consumer = detalle -> detalle.setUnidadMedida("NIU");
26 | whenSalesDocumentItem.apply(object).ifPresent(consumer);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLPercepcion.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.jaxb.models;
2 |
3 | import lombok.Data;
4 | import lombok.EqualsAndHashCode;
5 | import lombok.NoArgsConstructor;
6 |
7 | import jakarta.xml.bind.annotation.XmlAccessType;
8 | import jakarta.xml.bind.annotation.XmlAccessorType;
9 | import jakarta.xml.bind.annotation.XmlElement;
10 | import jakarta.xml.bind.annotation.XmlRootElement;
11 | import java.math.BigDecimal;
12 |
13 | @XmlAccessorType(XmlAccessType.NONE)
14 | @XmlRootElement(name = "Perception", namespace = "urn:sunat:names:specification:ubl:peru:schema:xsd:Perception-1")
15 | @EqualsAndHashCode(callSuper = true)
16 | @Data
17 | @NoArgsConstructor
18 | public class XMLPercepcion extends XMLPercepcionRetencionBase {
19 |
20 | @XmlElement(name = "SUNATPerceptionSystemCode", namespace = XMLConstants.SAC)
21 | private String sunatSystemCode;
22 |
23 | @XmlElement(name = "SUNATPerceptionPercent", namespace = XMLConstants.SAC)
24 | private BigDecimal sunatPercent;
25 |
26 | @XmlElement(name = "SUNATTotalCashed", namespace = XMLConstants.SAC)
27 | private BigDecimal sunatTotal;
28 |
29 | @XmlElement(name = "SUNATPerceptionDocumentReference", namespace = XMLConstants.SAC)
30 | private XMLPercepcionSunatDocumentReference sunatDocumentReference;
31 | }
32 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/sunat/percepcionretencion/BasePercepcionRetencion.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion;
2 |
3 | import io.github.project.openubl.xbuilder.content.models.common.Cliente;
4 | import io.github.project.openubl.xbuilder.content.models.common.Document;
5 | import io.swagger.v3.oas.annotations.media.Schema;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 | import lombok.NoArgsConstructor;
9 | import lombok.experimental.SuperBuilder;
10 |
11 | import java.math.BigDecimal;
12 |
13 | @Data
14 | @SuperBuilder
15 | @NoArgsConstructor
16 | @EqualsAndHashCode(callSuper = true)
17 | public abstract class BasePercepcionRetencion extends Document {
18 |
19 | /**
20 | * Número del comprobante
21 | */
22 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, minimum = "1", maximum = "99999999")
23 | private Integer numero;
24 |
25 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, minimum = "0", maximum = "100", exclusiveMinimum = true)
26 | private BigDecimal tipoRegimenPorcentaje;
27 |
28 | private String observacion;
29 |
30 | /**
31 | * Cliente
32 | */
33 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
34 | private Cliente cliente;
35 |
36 | private PercepcionRetencionOperacion operacion;
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/xsender/core/src/main/java/io/github/project/openubl/xsender/files/xml/XmlContentProvider.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xsender.files.xml;
2 |
3 | import org.xml.sax.SAXException;
4 |
5 | import javax.xml.parsers.ParserConfigurationException;
6 | import javax.xml.parsers.SAXParser;
7 | import javax.xml.parsers.SAXParserFactory;
8 | import java.io.IOException;
9 | import java.io.InputStream;
10 |
11 | public class XmlContentProvider {
12 |
13 | private XmlContentProvider() {
14 | // Only static methods
15 | }
16 |
17 | public static XmlContent getSunatDocument(InputStream is) throws ParserConfigurationException, SAXException, IOException {
18 | XmlHandler handler = new XmlHandler();
19 |
20 | SAXParserFactory factory = SAXParserFactory.newDefaultInstance();
21 | factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
22 | factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
23 | factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
24 | factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
25 | factory.setNamespaceAware(true);
26 |
27 | SAXParser parser = factory.newSAXParser();
28 | parser.parse(is, handler);
29 |
30 | return handler.getModel();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLSignature.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.jaxb.models;
2 |
3 | import lombok.Data;
4 | import lombok.NoArgsConstructor;
5 |
6 | import jakarta.xml.bind.annotation.XmlAccessType;
7 | import jakarta.xml.bind.annotation.XmlAccessorType;
8 | import jakarta.xml.bind.annotation.XmlElement;
9 | import jakarta.xml.bind.annotation.XmlType;
10 |
11 | @XmlAccessorType(XmlAccessType.NONE)
12 | @XmlType(name = "Signature")
13 | @Data
14 | @NoArgsConstructor
15 | public class XMLSignature {
16 | @XmlElement(name = "ID", namespace = XMLConstants.CBC)
17 | private String id;
18 |
19 | @XmlElement(name = "SignatoryParty", namespace = XMLConstants.CAC)
20 | private SignatoryParty signatoryParty;
21 |
22 | @XmlAccessorType(XmlAccessType.NONE)
23 | @XmlType(name = "Signature.SignatoryParty")
24 | @Data
25 | @NoArgsConstructor
26 | public static class SignatoryParty {
27 | @XmlElement(name = "PartyName", namespace = XMLConstants.CAC)
28 | private PartyName partyName;
29 | }
30 |
31 | @XmlType(name = "Signature.PartyName")
32 | @XmlAccessorType(XmlAccessType.NONE)
33 | @Data
34 | @NoArgsConstructor
35 | public static class PartyName {
36 | @XmlElement(name = "Name", namespace = XMLConstants.CBC)
37 | private String name;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/general/Detraccion.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.standard.general;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import java.math.BigDecimal;
10 |
11 | /**
12 | * Detracción asociada a un Invoice
13 | *
14 | * @author Carlos Feria
15 | */
16 | @Data
17 | @Builder
18 | @NoArgsConstructor
19 | @AllArgsConstructor
20 | public class Detraccion {
21 |
22 | /**
23 | * Catalog59
24 | **/
25 | @Schema(description = "Catalogo 59", requiredMode = Schema.RequiredMode.REQUIRED)
26 | private String medioDePago;
27 |
28 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
29 | private String cuentaBancaria;
30 |
31 | /**
32 | * Catalog54
33 | **/
34 | @Schema(description = "Catalog 54", requiredMode = Schema.RequiredMode.REQUIRED)
35 | private String tipoBienDetraido;
36 |
37 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, minimum = "0", maximum = "1", exclusiveMinimum = true)
38 | private BigDecimal porcentaje;
39 |
40 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED, minimum = "0", exclusiveMinimum = true)
41 | private BigDecimal monto;
42 | }
43 |
--------------------------------------------------------------------------------
/xsender/quarkus-extension/runtime/src/main/java/io/github/project/openubl/quarkus/xsender/XSender.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.quarkus.xsender;
2 |
3 | import io.github.project.openubl.quarkus.xsender.runtime.XSenderConfig;
4 | import io.github.project.openubl.xsender.camel.routes.CxfEndpointConfiguration;
5 | import org.apache.camel.component.cxf.jaxws.CxfEndpoint;
6 |
7 | import jakarta.enterprise.context.ApplicationScoped;
8 | import jakarta.enterprise.inject.Produces;
9 | import jakarta.inject.Inject;
10 | import jakarta.inject.Named;
11 |
12 | public class XSender {
13 |
14 | @Inject
15 | XSenderConfig config;
16 |
17 | @Produces
18 | @ApplicationScoped
19 | @Named("cxfBillServiceEndpoint")
20 | CxfEndpoint produceCxfBillServiceEndpoint() {
21 | return new CxfEndpointConfiguration().cxfBillServiceEndpoint(config.enableLoggingFeature);
22 | }
23 |
24 | @Produces
25 | @ApplicationScoped
26 | @Named("cxfBillConsultServiceEndpoint")
27 | CxfEndpoint produceCxfBillConsultServiceEndpoint() {
28 | return new CxfEndpointConfiguration().cxfBillConsultServiceEndpoint(config.enableLoggingFeature);
29 | }
30 |
31 | @Produces
32 | @ApplicationScoped
33 | @Named("cxfBillValidServiceEndpoint")
34 | CxfEndpoint produceCxfBillValidServiceEndpoint() {
35 | return new CxfEndpointConfiguration().cxfBillValidServiceEndpoint(config.enableLoggingFeature);
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/mappers/common/ProveedorMapper.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.jaxb.mappers.common;
2 |
3 | import io.github.project.openubl.xbuilder.content.jaxb.models.XMLSupplier;
4 | import io.github.project.openubl.xbuilder.content.jaxb.models.XMLSupplierSunat;
5 | import io.github.project.openubl.xbuilder.content.models.common.Proveedor;
6 | import org.mapstruct.Mapper;
7 | import org.mapstruct.Mapping;
8 |
9 | @Mapper(uses = {
10 | ContactoMapper.class,
11 | DireccionMapper.class
12 | })
13 | public interface ProveedorMapper {
14 |
15 | @Mapping(target = "ruc", source = "partyIdentification.id")
16 | @Mapping(target = "nombreComercial", source = "partyName.name")
17 | @Mapping(target = "razonSocial", source = "partyLegalEntity.registrationName")
18 | @Mapping(target = "direccion", source = "partyLegalEntity.address")
19 | @Mapping(target = "contacto", source = "contact")
20 | Proveedor map(XMLSupplier xml);
21 |
22 | @Mapping(target = "ruc", source = "customerAssignedAccountID")
23 | @Mapping(target = "nombreComercial", source = "partyName.name")
24 | @Mapping(target = "razonSocial", source = "party.partyLegalEntity.registrationName")
25 | @Mapping(target = "direccion", source = "party.partyLegalEntity.address")
26 | @Mapping(target = "contacto", source = "contact")
27 | Proveedor map(XMLSupplierSunat xml);
28 | }
29 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/header/invoice/FormaDePagoRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.rules.enrich.header.invoice;
2 |
3 | import io.github.project.openubl.xbuilder.content.models.standard.general.FormaDePago;
4 | import io.github.project.openubl.xbuilder.content.models.standard.general.Invoice;
5 | import io.github.project.openubl.xbuilder.enricher.kie.AbstractHeaderRule;
6 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
7 |
8 | import java.util.function.Consumer;
9 |
10 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isInvoice;
11 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenInvoice;
12 |
13 | @RulePhase(type = RulePhase.PhaseType.ENRICH)
14 | public class FormaDePagoRule extends AbstractHeaderRule {
15 |
16 | @Override
17 | public boolean test(Object object) {
18 | return (
19 | isInvoice.test(object) &&
20 | whenInvoice.apply(object).map(documento -> documento.getFormaDePago() == null).orElse(false)
21 | );
22 | }
23 |
24 | @Override
25 | public void modify(Object object) {
26 | Consumer consumer = document -> {
27 | document.setFormaDePago(FormaDePago.builder().build());
28 | };
29 | whenInvoice.apply(object).ifPresent(consumer);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/xbuilder/core/src/test/resources/xsd/2.1/common/UBL-XAdESv141-2.1.xsd:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/body/detalle/TasaIcbRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.rules.enrich.body.detalle;
2 |
3 | import io.github.project.openubl.xbuilder.content.models.standard.general.DocumentoVentaDetalle;
4 | import io.github.project.openubl.xbuilder.enricher.kie.AbstractBodyRule;
5 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
6 |
7 | import java.math.BigDecimal;
8 | import java.util.function.Consumer;
9 |
10 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isSalesDocumentItem;
11 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenSalesDocumentItem;
12 |
13 | @RulePhase(type = RulePhase.PhaseType.ENRICH)
14 | public class TasaIcbRule extends AbstractBodyRule {
15 |
16 | @Override
17 | public boolean test(Object object) {
18 | return (isSalesDocumentItem.test(object) && whenSalesDocumentItem.apply(object)
19 | .map(documento -> documento.getTasaIcb() == null)
20 | .orElse(false)
21 | );
22 | }
23 |
24 | @Override
25 | public void modify(Object object) {
26 | Consumer consumer = detalle -> {
27 | BigDecimal tasaIcb = getRuleContext().getTasaIcb();
28 | detalle.setTasaIcb(tasaIcb);
29 | };
30 | whenSalesDocumentItem.apply(object).ifPresent(consumer);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/jaxb/models/XMLSunatDocument.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.jaxb.models;
2 |
3 | import io.github.project.openubl.xbuilder.content.jaxb.adapters.LocalDateAdapter;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | import jakarta.xml.bind.annotation.XmlAccessType;
8 | import jakarta.xml.bind.annotation.XmlAccessorType;
9 | import jakarta.xml.bind.annotation.XmlElement;
10 | import jakarta.xml.bind.annotation.XmlType;
11 | import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
12 | import java.time.LocalDate;
13 |
14 | @XmlType(name = "SunatDocument")
15 | @XmlAccessorType(XmlAccessType.NONE)
16 | @Data
17 | @NoArgsConstructor
18 | public abstract class XMLSunatDocument {
19 |
20 | @XmlElement(name = "ID", namespace = XMLConstants.CBC)
21 | private String documentId;
22 |
23 | @XmlJavaTypeAdapter(LocalDateAdapter.class)
24 | @XmlElement(name = "ReferenceDate", namespace = XMLConstants.CBC)
25 | private LocalDate referenceDate;
26 |
27 | @XmlJavaTypeAdapter(LocalDateAdapter.class)
28 | @XmlElement(name = "IssueDate", namespace = XMLConstants.CBC)
29 | private LocalDate issueDate;
30 |
31 | @XmlElement(name = "Signature", namespace = XMLConstants.CAC)
32 | private XMLSignature signature;
33 |
34 | @XmlElement(name = "AccountingSupplierParty", namespace = XMLConstants.CAC)
35 | private XMLSupplierSunat accountingSupplierParty;
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/examples/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | io.github.project-openubl
8 | xhandler-parent
9 | 5.0.3-SNAPSHOT
10 | ../pom.xml
11 |
12 |
13 | examples-parent
14 | Examples - Parent
15 | Examples parent
16 | pom
17 |
18 |
19 | xbuilder
20 | xsender
21 | wildfly
22 | tomcat
23 | springbot
24 |
25 |
26 |
27 |
28 |
29 |
30 | org.apache.maven.plugins
31 | maven-war-plugin
32 | 3.4.0
33 |
34 | false
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/resources/templates/ubl/standard/include/address.xml:
--------------------------------------------------------------------------------
1 | {#if direccion.ubigeo}
2 | {direccion.ubigeo}
3 | {/if}
4 | {#if direccion.codigoLocal}
5 | {direccion.codigoLocal}
6 | {/if}
7 | {#if direccion.urbanizacion}
8 | {direccion.urbanizacion}
9 | {/if}
10 | {#if direccion.provincia}
11 | {direccion.provincia}
12 | {/if}
13 | {#if direccion.departamento}
14 | {direccion.departamento}
15 | {/if}
16 | {#if direccion.distrito}
17 | {direccion.distrito}
18 | {/if}
19 | {#if direccion.direccion}
20 |
21 |
22 |
23 | {/if}
24 | {#if direccion.codigoPais}
25 |
26 | {direccion.codigoPais}
27 |
28 | {/if}
29 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/body/summaryDocumentItem/MonedaRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.rules.enrich.body.summaryDocumentItem;
2 |
3 | import io.github.project.openubl.xbuilder.content.models.sunat.resumen.SummaryDocumentsItem;
4 | import io.github.project.openubl.xbuilder.enricher.kie.AbstractBodyRule;
5 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
6 |
7 | import java.util.function.Consumer;
8 |
9 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isSummaryDocumentsItem;
10 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenSummaryDocumentsItem;
11 |
12 | @RulePhase(type = RulePhase.PhaseType.ENRICH)
13 | public class MonedaRule extends AbstractBodyRule {
14 |
15 | @Override
16 | public boolean test(Object object) {
17 | return (isSummaryDocumentsItem.test(object) && whenSummaryDocumentsItem.apply(object)
18 | .map(item -> item.getComprobante() != null &&
19 | item.getComprobante().getMoneda() == null
20 | )
21 | .orElse(false)
22 | );
23 | }
24 |
25 | @Override
26 | public void modify(Object object) {
27 | Consumer consumer = item -> {
28 | String moneda = getRuleContext().getMoneda();
29 | item.getComprobante().setMoneda(moneda);
30 | };
31 | whenSummaryDocumentsItem.apply(object).ifPresent(consumer);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/process/body/detalle/IcbAplicaRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.rules.process.body.detalle;
2 |
3 | import io.github.project.openubl.xbuilder.content.models.standard.general.DocumentoVentaDetalle;
4 | import io.github.project.openubl.xbuilder.enricher.kie.AbstractBodyRule;
5 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
6 |
7 | import java.math.BigDecimal;
8 | import java.util.function.Consumer;
9 |
10 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isSalesDocumentItem;
11 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenSalesDocumentItem;
12 |
13 | @RulePhase(type = RulePhase.PhaseType.PROCESS)
14 | public class IcbAplicaRule extends AbstractBodyRule {
15 |
16 | @Override
17 | public boolean test(Object object) {
18 | return (isSalesDocumentItem.test(object) && whenSalesDocumentItem.apply(object)
19 | .map(documento -> !documento.isIcbAplica() &&
20 | documento.getIcb() != null &&
21 | documento.getIcb().compareTo(BigDecimal.ZERO) > 0
22 | )
23 | .orElse(false)
24 | );
25 | }
26 |
27 | @Override
28 | public void modify(Object object) {
29 | Consumer consumer = detalle -> {
30 | detalle.setIcbAplica(true);
31 | };
32 | whenSalesDocumentItem.apply(object).ifPresent(consumer);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/xsender/spring-boot-extension/runtime/src/main/java/io/github/project/openubl/spring/xsender/runtime/XSenderSpringSetup.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.spring.xsender.runtime;
2 |
3 | import io.github.project.openubl.xsender.camel.routes.CxfEndpointConfiguration;
4 | import io.github.project.openubl.xsender.camel.routes.SunatRouteBuilder;
5 | import org.apache.camel.component.cxf.jaxws.CxfEndpoint;
6 | import org.springframework.beans.factory.annotation.Value;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 |
10 | @Configuration
11 | public class XSenderSpringSetup {
12 |
13 | @Value("${spring.xsender.enable-logging-feature:false}")
14 | private boolean enableLoggingFeature;
15 |
16 | @Bean
17 | public SunatRouteBuilder produceSunatRouteBuilder() {
18 | return new SunatRouteBuilder();
19 | }
20 |
21 | @Bean(name = "cxfBillServiceEndpoint")
22 | CxfEndpoint produceCxfBillServiceEndpoint() {
23 | return new CxfEndpointConfiguration().cxfBillServiceEndpoint(enableLoggingFeature);
24 | }
25 |
26 | @Bean(name = "cxfBillConsultServiceEndpoint")
27 | CxfEndpoint produceCxfBillConsultServiceEndpoint() {
28 | return new CxfEndpointConfiguration().cxfBillConsultServiceEndpoint(enableLoggingFeature);
29 | }
30 |
31 | @Bean(name = "cxfBillValidServiceEndpoint")
32 | CxfEndpoint produceCxfBillValidServiceEndpoint() {
33 | return new CxfEndpointConfiguration().cxfBillValidServiceEndpoint(enableLoggingFeature);
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/process/body/detalle/IcbRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.rules.process.body.detalle;
2 |
3 | import io.github.project.openubl.xbuilder.content.models.standard.general.DocumentoVentaDetalle;
4 | import io.github.project.openubl.xbuilder.enricher.kie.AbstractBodyRule;
5 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
6 |
7 | import java.math.BigDecimal;
8 | import java.util.function.Consumer;
9 |
10 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isSalesDocumentItem;
11 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenSalesDocumentItem;
12 |
13 | @RulePhase(type = RulePhase.PhaseType.PROCESS)
14 | public class IcbRule extends AbstractBodyRule {
15 |
16 | @Override
17 | public boolean test(Object object) {
18 | return (isSalesDocumentItem.test(object) && whenSalesDocumentItem.apply(object)
19 | .map(documento -> documento.getIcb() == null)
20 | .orElse(false)
21 | );
22 | }
23 |
24 | @Override
25 | public void modify(Object object) {
26 | Consumer consumer = detalle -> {
27 | BigDecimal icb = detalle.isIcbAplica()
28 | ? detalle.getCantidad().multiply(getRuleContext().getTasaIcb())
29 | : BigDecimal.ZERO;
30 | detalle.setIcb(icb);
31 | };
32 | whenSalesDocumentItem.apply(object).ifPresent(consumer);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/catalogs/Catalog53.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.catalogs;
2 |
3 | public enum Catalog53 implements Catalog {
4 | DESCUENTO_AFECTA_BASE_IMPONIBLE_IGV_IVAP("00"),
5 | DESCUENTO_NO_AFECTA_BASE_IMPONIBLE_IGV_IVAP("01"),
6 | DESCUENTO_GLOBAL_AFECTA_BASE_IMPONIBLE_IGV_IVAP("02"),
7 | DESCUENTO_GLOBAL_NO_AFECTA_BASE_IMPONIBLE_IGV_IVAP("03"),
8 | DESCUENTO_GLOBAL_POR_ANTICIPOS_GRAVADOS_AFECTA_BASE_IMPONIBLE_IGV_IVAP("04"),
9 | DESCUENTO_GLOBAL_POR_ANTICIPOS_EXONERADOS("05"),
10 | DESCUENTO_GLOBAL_POR_ANTICIPOS_INAFECTOS("06"),
11 | FACTOR_DE_COMPENSACION("07"),
12 | ANTICIPO_DE_ISC("20"),
13 | FISE("45"),
14 | RECARGO_AL_CONSUMO_Y_O_PROPINAS("46"),
15 | CARGOS_QUE_AFECTAN_BASE_IMPONIBLE_IGV_IVAP("47"),
16 | CARGOS_QUE_NO_AFECTAN_BASE_IMPONIBLE_IGV_IVAP("48"),
17 | CARGOS_GLOBALES_QUE_AFECTAN_BASE_IMPONIBLE_IGV_IVAP("49"),
18 | CARGOS_GLOBALES_QUE_NO_AFECTAN_BASE_IMPONIBLE_IGV_IVAP("50"),
19 | PERCEPCION_VENTA_INTERNA("51"),
20 | PERCEPCION_A_LA_ADQUISICION_DE_COMBUSTIBLE("52"),
21 | PERCEPCION_REALIZADA_AL_AGENTE_DE_PERCEPCION_CON_TASA_ESPECIAL("53"),
22 | FACTOR_DE_APORTACION("54"),
23 | RETENCION_DE_RENTA_POR_ANTICIPOS("61"),
24 | RETENCION_DEL_IGV("62"),
25 | RETENCION_DE_RENTA_DE_SEGUNDA_CATEGORIA("62");
26 |
27 | private final String code;
28 |
29 | Catalog53(String code) {
30 | this.code = code;
31 | }
32 |
33 | @Override
34 | public String getCode() {
35 | return code;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/header/invoice/FormaDePagoTipoRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.rules.enrich.header.invoice;
2 |
3 | import io.github.project.openubl.xbuilder.content.catalogs.CatalogContadoCredito;
4 | import io.github.project.openubl.xbuilder.content.models.standard.general.Invoice;
5 | import io.github.project.openubl.xbuilder.enricher.kie.AbstractHeaderRule;
6 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
7 |
8 | import java.util.function.Consumer;
9 |
10 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isInvoice;
11 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenInvoice;
12 |
13 | @RulePhase(type = RulePhase.PhaseType.ENRICH)
14 | public class FormaDePagoTipoRule extends AbstractHeaderRule {
15 |
16 | @Override
17 | public boolean test(Object object) {
18 | return isInvoice.test(object);
19 | }
20 |
21 | @Override
22 | public void modify(Object object) {
23 | Consumer consumer = document -> {
24 | CatalogContadoCredito formaDePagoTipo = document.getFormaDePago().getCuotas() == null ||
25 | document.getFormaDePago().getCuotas().isEmpty()
26 | ? CatalogContadoCredito.CONTADO
27 | : CatalogContadoCredito.CREDITO;
28 |
29 | document.getFormaDePago().setTipo(formaDePagoTipo.getCode());
30 | };
31 | whenInvoice.apply(object).ifPresent(consumer);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/ruleunits/BodyRuleUnit.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.ruleunits;
2 |
3 | import io.github.project.openubl.xbuilder.enricher.config.Defaults;
4 | import io.github.project.openubl.xbuilder.enricher.kie.RuleFactory;
5 | import io.github.project.openubl.xbuilder.enricher.kie.RuleFactoryRegistry;
6 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
7 | import io.github.project.openubl.xbuilder.enricher.kie.RuleUnit;
8 |
9 | import java.util.List;
10 |
11 | public class BodyRuleUnit implements RuleUnit {
12 |
13 | private final Defaults defaults;
14 | private final BodyRuleContext context;
15 | private final List rules;
16 |
17 | public BodyRuleUnit(RulePhase.PhaseType phaseType, Defaults defaults, BodyRuleContext context) {
18 | this.defaults = defaults;
19 | this.context = context;
20 | this.rules = RuleFactoryRegistry.getRuleFactories(phaseType);
21 | }
22 |
23 | @Override
24 | public void modify(Object object) {
25 | int prevHashCode;
26 | int currentHashCode;
27 |
28 | do {
29 | prevHashCode = object.hashCode();
30 | rules
31 | .stream()
32 | .filter(factory -> factory.test(object))
33 | .map(factory -> factory.create(defaults, context))
34 | .forEach(rule -> rule.modify(object));
35 | currentHashCode = object.hashCode();
36 | } while (prevHashCode != currentHashCode);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/ruleunits/HeaderRuleUnit.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.ruleunits;
2 |
3 | import io.github.project.openubl.xbuilder.enricher.config.Defaults;
4 | import io.github.project.openubl.xbuilder.enricher.kie.RuleFactory;
5 | import io.github.project.openubl.xbuilder.enricher.kie.RuleFactoryRegistry;
6 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
7 | import io.github.project.openubl.xbuilder.enricher.kie.RuleUnit;
8 |
9 | import java.util.List;
10 |
11 | public class HeaderRuleUnit implements RuleUnit {
12 |
13 | private final Defaults defaults;
14 | private final HeaderRuleContext context;
15 | private final List rules;
16 |
17 | public HeaderRuleUnit(RulePhase.PhaseType phaseType, Defaults defaults, HeaderRuleContext context) {
18 | this.defaults = defaults;
19 | this.context = context;
20 | this.rules = RuleFactoryRegistry.getRuleFactories(phaseType);
21 | }
22 |
23 | @Override
24 | public void modify(Object object) {
25 | int prevHashCode;
26 | int currentHashCode;
27 |
28 | do {
29 | prevHashCode = object.hashCode();
30 | rules
31 | .stream()
32 | .filter(factory -> factory.test(object))
33 | .map(factory -> factory.create(defaults, context))
34 | .forEach(rule -> rule.modify(object));
35 | currentHashCode = object.hashCode();
36 | } while (prevHashCode != currentHashCode);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/process/body/detalle/IgvRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.rules.process.body.detalle;
2 |
3 | import io.github.project.openubl.xbuilder.content.models.standard.general.DocumentoVentaDetalle;
4 | import io.github.project.openubl.xbuilder.enricher.kie.AbstractBodyRule;
5 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
6 |
7 | import java.math.BigDecimal;
8 | import java.util.function.Consumer;
9 |
10 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isSalesDocumentItem;
11 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenSalesDocumentItem;
12 |
13 | @RulePhase(type = RulePhase.PhaseType.PROCESS)
14 | public class IgvRule extends AbstractBodyRule {
15 |
16 | @Override
17 | public boolean test(Object object) {
18 | return (isSalesDocumentItem.test(object) && whenSalesDocumentItem.apply(object)
19 | .map(documento -> documento.getIgv() == null &&
20 | documento.getIgvBaseImponible() != null &&
21 | documento.getTasaIgv() != null
22 | )
23 | .orElse(false)
24 | );
25 | }
26 |
27 | @Override
28 | public void modify(Object object) {
29 | Consumer consumer = detalle -> {
30 | BigDecimal igv = detalle.getIgvBaseImponible().multiply(detalle.getTasaIgv());
31 | detalle.setIgv(igv);
32 | };
33 | whenSalesDocumentItem.apply(object).ifPresent(consumer);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/process/body/detalle/IscRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.rules.process.body.detalle;
2 |
3 | import io.github.project.openubl.xbuilder.content.models.standard.general.DocumentoVentaDetalle;
4 | import io.github.project.openubl.xbuilder.enricher.kie.AbstractBodyRule;
5 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
6 |
7 | import java.math.BigDecimal;
8 | import java.util.function.Consumer;
9 |
10 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isSalesDocumentItem;
11 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenSalesDocumentItem;
12 |
13 | @RulePhase(type = RulePhase.PhaseType.PROCESS)
14 | public class IscRule extends AbstractBodyRule {
15 |
16 | @Override
17 | public boolean test(Object object) {
18 | return (isSalesDocumentItem.test(object) && whenSalesDocumentItem.apply(object)
19 | .map(documento -> documento.getIsc() == null &&
20 | documento.getIscBaseImponible() != null &&
21 | documento.getTasaIsc() != null
22 | )
23 | .orElse(false)
24 | );
25 | }
26 |
27 | @Override
28 | public void modify(Object object) {
29 | Consumer consumer = detalle -> {
30 | BigDecimal isc = detalle.getIscBaseImponible().multiply(detalle.getTasaIsc());
31 | detalle.setIsc(isc);
32 | };
33 | whenSalesDocumentItem.apply(object).ifPresent(consumer);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Envio.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.standard.guia;
2 |
3 | import io.swagger.v3.oas.annotations.media.Schema;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | import java.math.BigDecimal;
10 | import java.time.LocalDate;
11 |
12 | @Data
13 | @Builder
14 | @NoArgsConstructor
15 | @AllArgsConstructor
16 | public class Envio {
17 |
18 | @Schema(description = "Catalog 20", requiredMode = Schema.RequiredMode.REQUIRED)
19 | private String tipoTraslado;
20 | private String motivoTraslado;
21 |
22 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
23 | private BigDecimal pesoTotal;
24 |
25 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
26 | private String pesoTotalUnidadMedida;
27 |
28 | private Integer numeroDeBultos;
29 | private boolean transbordoProgramado;
30 |
31 | @Schema(description = "Catalog 18", requiredMode = Schema.RequiredMode.REQUIRED)
32 | private String tipoModalidadTraslado;
33 |
34 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
35 | private LocalDate fechaTraslado;
36 |
37 | private String numeroDeContenedor;
38 | private String codigoDePuerto;
39 |
40 | @Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED)
41 | private Transportista transportista;
42 |
43 | @Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED)
44 | private Partida partida;
45 |
46 | @Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED)
47 | private Destino destino;
48 | }
49 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/body/summaryDocumentItem/TipoOperacionRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.rules.enrich.body.summaryDocumentItem;
2 |
3 | import io.github.project.openubl.xbuilder.content.catalogs.Catalog;
4 | import io.github.project.openubl.xbuilder.content.catalogs.Catalog19;
5 | import io.github.project.openubl.xbuilder.content.models.sunat.resumen.SummaryDocumentsItem;
6 | import io.github.project.openubl.xbuilder.enricher.kie.AbstractBodyRule;
7 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
8 |
9 | import java.util.function.Consumer;
10 |
11 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isSummaryDocumentsItem;
12 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenSummaryDocumentsItem;
13 |
14 | @RulePhase(type = RulePhase.PhaseType.ENRICH)
15 | public class TipoOperacionRule extends AbstractBodyRule {
16 |
17 | @Override
18 | public boolean test(Object object) {
19 | return (
20 | isSummaryDocumentsItem.test(object) &&
21 | whenSummaryDocumentsItem.apply(object).map(item -> item.getTipoOperacion() != null).orElse(false)
22 | );
23 | }
24 |
25 | @Override
26 | public void modify(Object object) {
27 | Consumer consumer = item -> {
28 | Catalog.valueOfCode(Catalog19.class, item.getTipoOperacion())
29 | .ifPresent(catalog -> item.setTipoOperacion(catalog.getCode()));
30 | };
31 | whenSummaryDocumentsItem.apply(object).ifPresent(consumer);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/body/detalle/IscTipoRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.rules.enrich.body.detalle;
2 |
3 | import io.github.project.openubl.xbuilder.content.catalogs.Catalog;
4 | import io.github.project.openubl.xbuilder.content.catalogs.Catalog8;
5 | import io.github.project.openubl.xbuilder.content.models.standard.general.DocumentoVentaDetalle;
6 | import io.github.project.openubl.xbuilder.enricher.kie.AbstractBodyRule;
7 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
8 |
9 | import java.util.function.Consumer;
10 |
11 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isSalesDocumentItem;
12 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenSalesDocumentItem;
13 |
14 | @RulePhase(type = RulePhase.PhaseType.ENRICH)
15 | public class IscTipoRule extends AbstractBodyRule {
16 |
17 | @Override
18 | public boolean test(Object object) {
19 | return isSalesDocumentItem.test(object);
20 | }
21 |
22 | @Override
23 | public void modify(Object object) {
24 | Consumer consumer = detalle -> {
25 | Catalog8 catalog8;
26 | if (detalle.getIscTipo() == null) {
27 | catalog8 = Catalog8.SISTEMA_AL_VALOR;
28 | } else {
29 | catalog8 = Catalog.valueOfCode(Catalog8.class, detalle.getIscTipo()).orElseThrow(Catalog.invalidCatalogValue);
30 | }
31 |
32 | detalle.setIscTipo(catalog8.getCode());
33 | };
34 | whenSalesDocumentItem.apply(object).ifPresent(consumer);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/header/invoice/PercepcionRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.rules.enrich.header.invoice;
2 |
3 | import io.github.project.openubl.xbuilder.content.catalogs.Catalog52;
4 | import io.github.project.openubl.xbuilder.content.models.standard.general.Invoice;
5 | import io.github.project.openubl.xbuilder.enricher.kie.AbstractHeaderRule;
6 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
7 |
8 | import java.util.HashMap;
9 | import java.util.Map;
10 | import java.util.function.Consumer;
11 |
12 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isInvoice;
13 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenInvoice;
14 |
15 | @RulePhase(type = RulePhase.PhaseType.ENRICH)
16 | public class PercepcionRule extends AbstractHeaderRule {
17 |
18 | @Override
19 | public boolean test(Object object) {
20 | return (
21 | isInvoice.test(object) &&
22 | whenInvoice.apply(object).map(documento -> documento.getPercepcion() != null).orElse(false)
23 | );
24 | }
25 |
26 | @Override
27 | public void modify(Object object) {
28 | Consumer consumer = document -> {
29 | Catalog52 leyenda = Catalog52.COMPROBANTE_DE_PERCEPCION;
30 |
31 | Map leyendas = new HashMap<>(document.getLeyendas());
32 | leyendas.put(leyenda.getCode(), leyenda.getLabel());
33 |
34 | document.setLeyendas(leyendas);
35 | };
36 | whenInvoice.apply(object).ifPresent(consumer);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/header/invoice/DetraccionRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.rules.enrich.header.invoice;
2 |
3 | import io.github.project.openubl.xbuilder.content.catalogs.Catalog52;
4 | import io.github.project.openubl.xbuilder.content.models.standard.general.Invoice;
5 | import io.github.project.openubl.xbuilder.enricher.kie.AbstractHeaderRule;
6 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
7 |
8 | import java.util.HashMap;
9 | import java.util.Map;
10 | import java.util.function.Consumer;
11 |
12 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isInvoice;
13 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenInvoice;
14 |
15 | @RulePhase(type = RulePhase.PhaseType.ENRICH)
16 | public class DetraccionRule extends AbstractHeaderRule {
17 |
18 | @Override
19 | public boolean test(Object object) {
20 | return (
21 | isInvoice.test(object) &&
22 | whenInvoice.apply(object).map(documento -> documento.getDetraccion() != null).orElse(false)
23 | );
24 | }
25 |
26 | @Override
27 | public void modify(Object object) {
28 | Consumer consumer = document -> {
29 | Catalog52 leyenda = Catalog52.OPERACION_SUJETA_A_DETRACCION;
30 |
31 | Map leyendas = new HashMap<>(document.getLeyendas());
32 | leyendas.put(leyenda.getCode(), leyenda.getLabel());
33 |
34 | document.setLeyendas(leyendas);
35 | };
36 | whenInvoice.apply(object).ifPresent(consumer);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/body/detalle/IgvTipoRule.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.enricher.kie.rules.enrich.body.detalle;
2 |
3 | import io.github.project.openubl.xbuilder.content.catalogs.Catalog;
4 | import io.github.project.openubl.xbuilder.content.catalogs.Catalog7;
5 | import io.github.project.openubl.xbuilder.content.models.standard.general.DocumentoVentaDetalle;
6 | import io.github.project.openubl.xbuilder.enricher.kie.AbstractBodyRule;
7 | import io.github.project.openubl.xbuilder.enricher.kie.RulePhase;
8 |
9 | import java.util.function.Consumer;
10 |
11 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isSalesDocumentItem;
12 | import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenSalesDocumentItem;
13 |
14 | @RulePhase(type = RulePhase.PhaseType.ENRICH)
15 | public class IgvTipoRule extends AbstractBodyRule {
16 |
17 | @Override
18 | public boolean test(Object object) {
19 | return isSalesDocumentItem.test(object);
20 | }
21 |
22 | @Override
23 | public void modify(Object object) {
24 | Consumer consumer = detalle -> {
25 | Catalog7 catalog7;
26 | if (detalle.getIgvTipo() == null) {
27 | catalog7 = Catalog7.GRAVADO_OPERACION_ONEROSA;
28 | } else {
29 | catalog7 = Catalog.valueOfCode(Catalog7.class, detalle.getIgvTipo()).orElseThrow(Catalog.invalidCatalogValue);
30 | }
31 |
32 | detalle.setIgvTipo(catalog7.getCode());
33 | };
34 | whenSalesDocumentItem.apply(object).ifPresent(consumer);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/models/common/Cliente.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.models.common;
2 |
3 | import io.github.project.openubl.xbuilder.content.catalogs.Catalog6;
4 | import io.swagger.v3.oas.annotations.media.Schema;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | /**
11 | * Cliente de la operación.
12 | *
13 | * @author Carlos Feria
14 | */
15 | @Data
16 | @Builder
17 | @NoArgsConstructor
18 | @AllArgsConstructor
19 | public class Cliente {
20 |
21 | /**
22 | * Tipo de documento de identidad del cliente.
23 | *
24 | * Catalogo 06.
25 | *
26 | * Valores válidos: {@link Catalog6}
27 | */
28 | @Schema(description = "Catalogo 06", requiredMode = Schema.RequiredMode.REQUIRED)
29 | private String tipoDocumentoIdentidad;
30 |
31 | /**
32 | * Número de documento de identidad del cliente.
33 | */
34 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
35 | private String numeroDocumentoIdentidad;
36 |
37 | /**
38 | * Nombre del cliente. Si el cliente es personal natural entonces
39 | * es el nombre y apellidos de la persona; si el cliente es una persona jurídica
40 | * entonces es la razón social de la empresa.
41 | */
42 | @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
43 | private String nombre;
44 |
45 | /**
46 | * Dirección del cliente
47 | */
48 | private Direccion direccion;
49 |
50 | /**
51 | * Datos de contacto del cliente
52 | */
53 | private Contacto contacto;
54 | }
55 |
--------------------------------------------------------------------------------
/xbuilder/quarkus-extension/runtime/src/main/java/io/github/project/openubl/quarkus/xbuilder/runtime/DefaultXBuilder.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.quarkus.xbuilder.runtime;
2 |
3 | import io.github.project.openubl.quarkus.xbuilder.XBuilder;
4 | import io.github.project.openubl.xbuilder.enricher.config.Defaults;
5 | import io.github.project.openubl.xbuilder.renderer.EngineProducer;
6 | import io.quarkus.qute.Engine;
7 | import io.quarkus.qute.EngineBuilder;
8 | import io.quarkus.qute.HtmlEscaper;
9 | import io.quarkus.qute.Template;
10 |
11 | import jakarta.enterprise.event.Observes;
12 | import jakarta.inject.Inject;
13 | import jakarta.inject.Singleton;
14 | import java.math.BigDecimal;
15 | import java.util.List;
16 |
17 | @Singleton
18 | public class DefaultXBuilder implements XBuilder {
19 |
20 | @Inject
21 | Engine engine;
22 |
23 | @Inject
24 | XBuilderConfig config;
25 |
26 | void configureEngine(@Observes EngineBuilder builder) {
27 | builder.addResultMapper(
28 | new HtmlEscaper(List.of("text/html", "text/xml", "application/xml", "application/xhtml+xml"))
29 | );
30 |
31 | EngineProducer.getInstance().getEngine().getValueResolvers().forEach(builder::addValueResolver);
32 | }
33 |
34 | @Override
35 | public Template getTemplate(Type type) {
36 | return engine.getTemplate(CustomTemplateLocator.PREFIX + type.getTemplatePath());
37 | }
38 |
39 | @Override
40 | public Defaults getDefaults() {
41 | return Defaults.builder()
42 | .igvTasa(config.igvTasa.orElse(new BigDecimal("0.18")))
43 | .icbTasa(config.icbTasa.orElse(new BigDecimal("0.2")))
44 | .build();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/xbuilder/core/src/main/java/io/github/project/openubl/xbuilder/content/catalogs/Catalog59.java:
--------------------------------------------------------------------------------
1 | package io.github.project.openubl.xbuilder.content.catalogs;
2 |
3 | public enum Catalog59 implements Catalog {
4 | DEPOSITO_EN_CUENTA("001"),
5 | GIRO("002"),
6 | TRANSFERENCIA_DE_FONDOS("003"),
7 | ORDEN_DE_PAGO("004"),
8 | TARJETA_DE_DEBITO("005"),
9 | TARJETA_DE_CREDITO_EMITIDA_EN_EL_PAIS_POR_UNA_EMPRESA_DEL_SISTEMA_FINANCIERO("006"),
10 | CHEQUES_CON_LA_CLAUSULA_DE_NONEGOCIABLE_INTRANSFERIBLE_NOALAORDEN_U_OTRA_EQUIVALENTE("007"),
11 | EFECTIVO_POR_OPERACIONES_EN_LAS_QUE_NO_EXISTE_OBLIGACION_DE_UTILIZAR_MEDIO_DE_PAGO("008"),
12 | EFECTIVO_EN_LOS_DEMAS_CASOS("009"),
13 | MEDIOS_DE_PAGO_USADOS_EN_COMERCIO_EXTERIOR("010"),
14 | DOCUMENTOS_EMITIDOS_POR_LAS_EDPYMES_Y_LAS_COOPERATIVAS("011"),
15 | TARJETA_DE_CREDITO_EMITIDA_EN_EL_PAIS_O_EN_EXTERIOR_EMITIDA_POR_EMPRESA_NO_PERTENECIENTE_AL_SISTEMA_FINANCIERO("012"),
16 | TARJETAS_DE_CREDITO_EMITIDAS_EN_EL_EXTERIOR_POR_EMPRESAS_BANCARIAS_O_FINANCIERAS_NO_DOMICILIADAS("013"),
17 | TRANSFERENCIAS_COMERCIO_EXTERIOR("101"),
18 | CHEQUES_BANCARIOS_COMERCIO_EXTERIOR("102"),
19 | ORDEN_DE_PAGO_SIMPLE_COMERCIO_EXTERIOR("103"),
20 | ORDEN_DE_PAGO_DOCUMENTARIO_COMERCIO_EXTERIOR("104"),
21 | REMESA_SIMPLE_COMERCIO_EXTERIOR("105"),
22 | REMESA_DOCUMENTARIA_COMERCIO_EXTERIOR("106"),
23 | CARTA_DE_CREDITO_SIMPLE_COMERCIO_EXTERIOR("107"),
24 | CARTA_DE_CREDITO_DOCUMENTARIO_COMERCIO_EXTERIOR("108"),
25 | OTROS_MEDIOS_DE_PAGO("999");
26 |
27 | private final String code;
28 |
29 | Catalog59(String code) {
30 | this.code = code;
31 | }
32 |
33 | @Override
34 | public String getCode() {
35 | return code;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------