From b4e99b582eb5662f855836d375d78f5dd123fb8f Mon Sep 17 00:00:00 2001 From: "Carlos E. Feria Vila" Date: Fri, 6 Jan 2023 09:10:56 +0100 Subject: [PATCH] Add despatchAdvice (#167) --- .../models/standard/guia/DespatchAdvice.java | 93 +++++++++++ .../standard/guia/DespatchAdviceItem.java | 39 +++++ .../models/standard/guia/Destinatario.java | 39 +++++ .../standard/guia/{info.java => Destino.java} | 10 +- .../models/standard/guia/DocumentoBaja.java | 36 ++++ .../standard/guia/DocumentoRelacionado.java | 36 ++++ .../content/models/standard/guia/Envio.java | 64 ++++++++ .../content/models/standard/guia/Partida.java | 31 ++++ .../models/standard/guia/Proveedor.java | 36 ++++ .../models/standard/guia/Remitente.java | 36 ++++ .../models/standard/guia/Transportista.java | 49 ++++++ .../xbuilder/enricher/ContentEnricher.java | 36 +++- .../rules/enrich/header/FechaEmisionRule.java | 19 ++- .../kie/rules/enrich/header/FirmanteRule.java | 31 +++- .../enricher/kie/rules/utils/Helpers.java | 10 ++ .../xbuilder/renderer/TemplateProducer.java | 4 + .../templates/Renderer/despatchAdvice.xml | 138 ++++++++++++++++ .../java/e2e/renderer/XMLAssertUtils.java | 30 ++-- .../despatchadvice/DespatchAdviceTest.java | 106 ++++++++++++ .../DespatchAdviceTest/minData.xml | 92 +++++++++++ pom.xml | 2 +- .../deployment/QuarkusXbuilderProcessor.java | 27 ++- .../xbuilder/it/QuarkusXbuilderResource.java | 15 ++ .../it/QuarkusXbuilderResourceTest.java | 154 ++++++++++++++++++ .../openubl/quarkus/xbuilder/XBuilder.java | 3 +- 25 files changed, 1095 insertions(+), 41 deletions(-) create mode 100644 core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DespatchAdvice.java create mode 100644 core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DespatchAdviceItem.java create mode 100644 core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Destinatario.java rename core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/{info.java => Destino.java} (78%) create mode 100644 core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DocumentoBaja.java create mode 100644 core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DocumentoRelacionado.java create mode 100644 core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Envio.java create mode 100644 core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Partida.java create mode 100644 core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Proveedor.java create mode 100644 core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Remitente.java create mode 100644 core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Transportista.java create mode 100644 core/src/main/resources/templates/Renderer/despatchAdvice.xml create mode 100644 core/src/test/java/e2e/renderer/despatchadvice/DespatchAdviceTest.java create mode 100644 core/src/test/resources/e2e/renderer/despatchadvice/DespatchAdviceTest/minData.xml diff --git a/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DespatchAdvice.java b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DespatchAdvice.java new file mode 100644 index 00000000..0814cfb2 --- /dev/null +++ b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DespatchAdvice.java @@ -0,0 +1,93 @@ +/* + * Copyright 2019 Project OpenUBL, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License - 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.project.openubl.xbuilder.content.models.standard.guia; + +import io.github.project.openubl.xbuilder.content.models.common.Firmante; +import io.github.project.openubl.xbuilder.content.models.common.Proveedor; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.Singular; +import lombok.extern.jackson.Jacksonized; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.List; + +@Jacksonized +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DespatchAdvice { + /** + * Serie del comprobante + */ + @Schema(requiredMode = Schema.RequiredMode.REQUIRED, minLength = 4, pattern = "^[T|t|V|v].*$") + private String serie; + + /** + * Número del comprobante + */ + @Schema(requiredMode = Schema.RequiredMode.REQUIRED, minimum = "1", maximum = "99999999") + private Integer numero; + + /** + * Fecha de emisión del comprobante. Ejemplo 2022-12-25 (YYYY-MM-SS) + */ + @Schema(description = "Format: \"YYYY-MM-SS\". Ejemplo: 2022-12-25", pattern = "^\\d{4}-\\d{2}-\\d{2}$") + private LocalDate fechaEmision; + + /** + * Hora de emisión del comprobante. Ejemplo 12:00:00 (HH:MM:SS) + */ + @Schema(description = "Format: \"HH:MM:SS\". Ejemplo 12:00:00", pattern = "^\\d{2}:\\d{2}:\\d{2}$") + private LocalTime horaEmision; + + @Schema(description = "Catalogo 01") + private String tipoComprobante; + + private String observaciones; + + @Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private DocumentoBaja documentoBaja; + + @Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private DocumentoRelacionado documentoRelacionado; + + @Schema(description = "Persona que firma electrónicamente el comprobante. Si NULL los datos del proveedor son usados.") + private Firmante firmante; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private Remitente remitente; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private Destinatario destinatario; + + @Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Proveedor proveedor; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private Envio envio; + + @Singular + @ArraySchema(minItems = 1, schema = @Schema(requiredMode = Schema.RequiredMode.REQUIRED)) + private List detalles; +} diff --git a/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DespatchAdviceItem.java b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DespatchAdviceItem.java new file mode 100644 index 00000000..6532444c --- /dev/null +++ b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DespatchAdviceItem.java @@ -0,0 +1,39 @@ +/* + * Copyright 2019 Project OpenUBL, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License - 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.project.openubl.xbuilder.content.models.standard.guia; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.jackson.Jacksonized; + +import java.math.BigDecimal; + +@Jacksonized +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DespatchAdviceItem { + private String unidadMedida; + private BigDecimal cantidad; + + private String descripcion; + private String codigo; + private String codigoSunat; +} diff --git a/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Destinatario.java b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Destinatario.java new file mode 100644 index 00000000..b24a4ff8 --- /dev/null +++ b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Destinatario.java @@ -0,0 +1,39 @@ +/* + * Copyright 2019 Project OpenUBL, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License - 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.project.openubl.xbuilder.content.models.standard.guia; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class Destinatario { + + @Schema(description = "Catalogo 06", requiredMode = Schema.RequiredMode.REQUIRED) + private String tipoDocumentoIdentidad; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private String numeroDocumentoIdentidad; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private String nombre; +} diff --git a/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/info.java b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Destino.java similarity index 78% rename from core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/info.java rename to core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Destino.java index 91595218..f4d3aeed 100644 --- a/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/info.java +++ b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Destino.java @@ -16,8 +16,16 @@ */ package io.github.project.openubl.xbuilder.content.models.standard.guia; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; @Data -public class info { +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class Destino { + private String ubigeo; + private String direccion; } diff --git a/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DocumentoBaja.java b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DocumentoBaja.java new file mode 100644 index 00000000..ce565a6b --- /dev/null +++ b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DocumentoBaja.java @@ -0,0 +1,36 @@ +/* + * Copyright 2019 Project OpenUBL, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License - 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.project.openubl.xbuilder.content.models.standard.guia; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DocumentoBaja { + + @Schema(description = "Catalog 01", requiredMode = Schema.RequiredMode.REQUIRED) + private String tipoDocumento; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private String serieNumero; +} diff --git a/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DocumentoRelacionado.java b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DocumentoRelacionado.java new file mode 100644 index 00000000..bfa1ecde --- /dev/null +++ b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/DocumentoRelacionado.java @@ -0,0 +1,36 @@ +/* + * Copyright 2019 Project OpenUBL, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License - 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.project.openubl.xbuilder.content.models.standard.guia; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DocumentoRelacionado { + + @Schema(description = "Catalog 21", requiredMode = Schema.RequiredMode.REQUIRED) + private String tipoDocumento; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private String serieNumero; +} diff --git a/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Envio.java b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Envio.java new file mode 100644 index 00000000..1cf0d7af --- /dev/null +++ b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Envio.java @@ -0,0 +1,64 @@ +/* + * Copyright 2019 Project OpenUBL, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License - 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.project.openubl.xbuilder.content.models.standard.guia; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.time.LocalDate; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class Envio { + + @Schema(description = "Catalog 20", requiredMode = Schema.RequiredMode.REQUIRED) + private String tipoTraslado; + private String motivoTraslado; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private BigDecimal pesoTotal; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private String pesoTotalUnidadMedida; + + private Integer numeroDeBultos; + private boolean transbordoProgramado; + + @Schema(description = "Catalog 18", requiredMode = Schema.RequiredMode.REQUIRED) + private String tipoModalidadTraslado; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDate fechaTraslado; + + private String numeroDeContenedor; + private String codigoDePuerto; + + @Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Transportista transportista; + + @Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Partida partida; + + @Schema(requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private Destino destino; +} diff --git a/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Partida.java b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Partida.java new file mode 100644 index 00000000..b8021230 --- /dev/null +++ b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Partida.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019 Project OpenUBL, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License - 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.project.openubl.xbuilder.content.models.standard.guia; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class Partida { + private String ubigeo; + private String direccion; +} diff --git a/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Proveedor.java b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Proveedor.java new file mode 100644 index 00000000..131dc1d7 --- /dev/null +++ b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Proveedor.java @@ -0,0 +1,36 @@ +/* + * Copyright 2019 Project OpenUBL, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License - 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.project.openubl.xbuilder.content.models.standard.guia; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class Proveedor { + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED, minLength = 11, maxLength = 11, pattern = "[0-9]+") + private String ruc; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private String razonSocial; +} diff --git a/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Remitente.java b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Remitente.java new file mode 100644 index 00000000..ac94979b --- /dev/null +++ b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Remitente.java @@ -0,0 +1,36 @@ +/* + * Copyright 2019 Project OpenUBL, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License - 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.project.openubl.xbuilder.content.models.standard.guia; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class Remitente { + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED, minLength = 11, maxLength = 11, pattern = "[0-9]+") + private String ruc; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private String razonSocial; +} diff --git a/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Transportista.java b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Transportista.java new file mode 100644 index 00000000..39275b76 --- /dev/null +++ b/core/src/main/java/io/github/project/openubl/xbuilder/content/models/standard/guia/Transportista.java @@ -0,0 +1,49 @@ +/* + * Copyright 2019 Project OpenUBL, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License - 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.project.openubl.xbuilder.content.models.standard.guia; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class Transportista { + + @Schema(description = "Catalogo 06", requiredMode = Schema.RequiredMode.REQUIRED) + private String tipoDocumentoIdentidad; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private String numeroDocumentoIdentidad; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private String nombre; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private String placaDelVehiculo; + + @Schema(description = "Catalogo 06", requiredMode = Schema.RequiredMode.REQUIRED) + private String choferTipoDocumentoIdentidad; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private String choferNumeroDocumentoIdentidad; + +} diff --git a/core/src/main/java/io/github/project/openubl/xbuilder/enricher/ContentEnricher.java b/core/src/main/java/io/github/project/openubl/xbuilder/enricher/ContentEnricher.java index 0b0d7c68..657b5f4a 100644 --- a/core/src/main/java/io/github/project/openubl/xbuilder/enricher/ContentEnricher.java +++ b/core/src/main/java/io/github/project/openubl/xbuilder/enricher/ContentEnricher.java @@ -20,6 +20,7 @@ import io.github.project.openubl.xbuilder.content.models.standard.general.DebitNote; import io.github.project.openubl.xbuilder.content.models.standard.general.Invoice; import io.github.project.openubl.xbuilder.content.models.standard.general.Note; +import io.github.project.openubl.xbuilder.content.models.standard.guia.DespatchAdvice; import io.github.project.openubl.xbuilder.content.models.sunat.baja.VoidedDocuments; import io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.Perception; import io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.Retention; @@ -77,6 +78,30 @@ public void enrich(DebitNote input) { enrichNote(input); } + private void enrichNote(Note input) { + LocalDate systemLocalDate = dateProvider.now(); + + Stream + .of(RulePhase.PhaseType.ENRICH, RulePhase.PhaseType.PROCESS, RulePhase.PhaseType.SUMMARY) + .forEach(phaseType -> { + // Header + HeaderRuleContext ruleContextHeader = HeaderRuleContext.builder() + .localDate(systemLocalDate) + .build(); + RuleUnit ruleUnitHeader = new HeaderRuleUnit(phaseType, defaults, ruleContextHeader); + ruleUnitHeader.modify(input); + + // Body + BodyRuleContext ruleContextBody = BodyRuleContext + .builder() + .tasaIgv(input.getTasaIgv()) + .tasaIcb(input.getTasaIcb()) + .build(); + RuleUnit ruleUnitBody = new BodyRuleUnit(phaseType, defaults, ruleContextBody); + input.getDetalles().forEach(ruleUnitBody::modify); + }); + } + public void enrich(VoidedDocuments input) { LocalDate systemLocalDate = dateProvider.now(); @@ -153,22 +178,21 @@ public void enrich(Retention input) { }); } - private void enrichNote(Note input) { + public void enrich(DespatchAdvice input) { LocalDate systemLocalDate = dateProvider.now(); Stream .of(RulePhase.PhaseType.ENRICH, RulePhase.PhaseType.PROCESS, RulePhase.PhaseType.SUMMARY) .forEach(phaseType -> { // Header - HeaderRuleContext ruleContextHeader = HeaderRuleContext.builder().localDate(systemLocalDate).build(); + HeaderRuleContext ruleContextHeader = HeaderRuleContext.builder() + .localDate(systemLocalDate) + .build(); RuleUnit ruleUnitHeader = new HeaderRuleUnit(phaseType, defaults, ruleContextHeader); ruleUnitHeader.modify(input); // Body - BodyRuleContext ruleContextBody = BodyRuleContext - .builder() - .tasaIgv(input.getTasaIgv()) - .tasaIcb(input.getTasaIcb()) + BodyRuleContext ruleContextBody = BodyRuleContext.builder() .build(); RuleUnit ruleUnitBody = new BodyRuleUnit(phaseType, defaults, ruleContextBody); input.getDetalles().forEach(ruleUnitBody::modify); diff --git a/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/header/FechaEmisionRule.java b/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/header/FechaEmisionRule.java index 3f647597..2a4bf9a7 100644 --- a/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/header/FechaEmisionRule.java +++ b/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/header/FechaEmisionRule.java @@ -17,12 +17,15 @@ package io.github.project.openubl.xbuilder.enricher.kie.rules.enrich.header; import io.github.project.openubl.xbuilder.content.models.common.Document; +import io.github.project.openubl.xbuilder.content.models.standard.guia.DespatchAdvice; import io.github.project.openubl.xbuilder.enricher.kie.AbstractHeaderRule; import io.github.project.openubl.xbuilder.enricher.kie.RulePhase; import java.util.function.Consumer; +import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isDespatchAdvice; import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isDocument; +import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenDespatchAdvice; import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenDocument; @RulePhase(type = RulePhase.PhaseType.ENRICH) @@ -30,15 +33,21 @@ public class FechaEmisionRule extends AbstractHeaderRule { @Override public boolean test(Object object) { - return ( - isDocument.test(object) && - whenDocument.apply(object).map(documento -> documento.getFechaEmision() == null).orElse(false) + return (isDocument.test(object) && whenDocument.apply(object) + .map(documento -> documento.getFechaEmision() == null) + .orElse(false) + ) || (isDespatchAdvice.test(object) && whenDespatchAdvice.apply(object) + .map(documento -> documento.getFechaEmision() == null) + .orElse(false) ); } @Override public void modify(Object object) { - Consumer consumer = document -> document.setFechaEmision(getRuleContext().getLocalDate()); - whenDocument.apply(object).ifPresent(consumer); + Consumer consumer1 = document -> document.setFechaEmision(getRuleContext().getLocalDate()); + Consumer consumer2 = document -> document.setFechaEmision(getRuleContext().getLocalDate()); + + whenDocument.apply(object).ifPresent(consumer1); + whenDespatchAdvice.apply(object).ifPresent(consumer2); } } diff --git a/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/header/FirmanteRule.java b/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/header/FirmanteRule.java index 8aec2850..95e97768 100644 --- a/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/header/FirmanteRule.java +++ b/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/enrich/header/FirmanteRule.java @@ -18,12 +18,15 @@ import io.github.project.openubl.xbuilder.content.models.common.Document; import io.github.project.openubl.xbuilder.content.models.common.Firmante; +import io.github.project.openubl.xbuilder.content.models.standard.guia.DespatchAdvice; import io.github.project.openubl.xbuilder.enricher.kie.AbstractHeaderRule; import io.github.project.openubl.xbuilder.enricher.kie.RulePhase; import java.util.function.Consumer; +import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isDespatchAdvice; import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.isDocument; +import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenDespatchAdvice; import static io.github.project.openubl.xbuilder.enricher.kie.rules.utils.Helpers.whenDocument; @RulePhase(type = RulePhase.PhaseType.ENRICH) @@ -31,16 +34,18 @@ public class FirmanteRule extends AbstractHeaderRule { @Override public boolean test(Object object) { - return ( - isDocument.test(object) && whenDocument.apply(object) - .map(documento -> documento.getProveedor() != null) - .orElse(false) + return (isDocument.test(object) && whenDocument.apply(object) + .map(documento -> documento.getProveedor() != null) + .orElse(false) + ) || (isDespatchAdvice.test(object) && whenDespatchAdvice.apply(object) + .map(documento -> documento.getRemitente() != null) + .orElse(false) ); } @Override public void modify(Object object) { - Consumer consumer = document -> { + Consumer consumer1 = document -> { if (document.getFirmante() == null) { document.setFirmante(Firmante.builder().build()); } @@ -52,6 +57,20 @@ public void modify(Object object) { document.getFirmante().setRazonSocial(document.getProveedor().getRazonSocial()); } }; - whenDocument.apply(object).ifPresent(consumer); + Consumer consumer2 = document -> { + if (document.getFirmante() == null) { + document.setFirmante(Firmante.builder().build()); + } + + if (document.getFirmante().getRuc() == null) { + document.getFirmante().setRuc(document.getRemitente().getRuc()); + } + if (document.getFirmante().getRazonSocial() == null) { + document.getFirmante().setRazonSocial(document.getRemitente().getRazonSocial()); + } + }; + + whenDocument.apply(object).ifPresent(consumer1); + whenDespatchAdvice.apply(object).ifPresent(consumer2); } } diff --git a/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/utils/Helpers.java b/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/utils/Helpers.java index a07678a0..4219124c 100644 --- a/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/utils/Helpers.java +++ b/core/src/main/java/io/github/project/openubl/xbuilder/enricher/kie/rules/utils/Helpers.java @@ -24,6 +24,7 @@ import io.github.project.openubl.xbuilder.content.models.standard.general.Invoice; import io.github.project.openubl.xbuilder.content.models.standard.general.Note; import io.github.project.openubl.xbuilder.content.models.standard.general.SalesDocument; +import io.github.project.openubl.xbuilder.content.models.standard.guia.DespatchAdvice; import io.github.project.openubl.xbuilder.content.models.sunat.baja.VoidedDocuments; import io.github.project.openubl.xbuilder.content.models.sunat.baja.VoidedDocumentsItem; import io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.Perception; @@ -50,6 +51,8 @@ public class Helpers { public static final Predicate isPerception = o -> o instanceof Perception; public static final Predicate isRetention = o -> o instanceof Retention; + public static final Predicate isDespatchAdvice = o -> o instanceof DespatchAdvice; + public static final Predicate isDocument = isInvoice.or(isCreditNote).or(isDebitNote) .or(isVoidedDocuments).or(isSummaryDocuments) .or(isPerception).or(isRetention); @@ -128,4 +131,11 @@ public class Helpers { } return Optional.empty(); }; + + public static final Function> whenDespatchAdvice = o -> { + if (o instanceof DespatchAdvice) { + return Optional.of((DespatchAdvice) o); + } + return Optional.empty(); + }; } diff --git a/core/src/main/java/io/github/project/openubl/xbuilder/renderer/TemplateProducer.java b/core/src/main/java/io/github/project/openubl/xbuilder/renderer/TemplateProducer.java index 622a43be..d7914067 100644 --- a/core/src/main/java/io/github/project/openubl/xbuilder/renderer/TemplateProducer.java +++ b/core/src/main/java/io/github/project/openubl/xbuilder/renderer/TemplateProducer.java @@ -48,6 +48,10 @@ public Template getRetention() { return EngineProducer.getInstance().getEngine().getTemplate("Renderer/retention.xml"); } + public Template getDespatchAdvice() { + return EngineProducer.getInstance().getEngine().getTemplate("Renderer/despatchAdvice.xml"); + } + private static class TemplateProducerHolder { private static final TemplateProducer INSTANCE = new TemplateProducer(); diff --git a/core/src/main/resources/templates/Renderer/despatchAdvice.xml b/core/src/main/resources/templates/Renderer/despatchAdvice.xml new file mode 100644 index 00000000..3ec0fc50 --- /dev/null +++ b/core/src/main/resources/templates/Renderer/despatchAdvice.xml @@ -0,0 +1,138 @@ + + + {#include ubl/standard/include/ubl-extensions.xml /} + {#include ubl/standard/include/general-data.xml item=this /} + {tipoComprobante} + {#if observaciones} + + {/if} + {#if documentoBaja} + + {documentoBaja.serieNumero} + {documentoBaja.tipoDocumento} + + {/if} + {#if documentoRelacionado} + + {documentoRelacionado.serieNumero} + {documentoRelacionado.tipoDocumento} + + {/if} + {#include ubl/common/signature.xml firmante=this.firmante /} + + {remitente.ruc} + + + {remitente.ruc} + + + + + + + + + + {destinatario.numeroDocumentoIdentidad} + + + + + + + {#if proveedor} + + {proveedor.ruc} + + + + + + + {/if} + + 1 + {envio.tipoTraslado} + {#if envio.motivoTraslado} + {envio.motivoTraslado} + {/if} + {envio.pesoTotal.scale(3)} + {#if envio.numeroDeBultos} + {envio.numeroDeBultos} + {/if} + {envio.transbordoProgramado} + + {envio.tipoModalidadTraslado} + + {envio.fechaTraslado} + + {#if envio.transportista} + + + {envio.transportista.numeroDocumentoIdentidad} + + + + + + + + {envio.transportista.placaDelVehiculo} + + + + {envio.transportista.choferNumeroDocumentoIdentidad} + + {/if} + + + + {envio.destino.ubigeo} + + {envio.destino.direccion} + + + + {#if envio.numeroDeContenedor} + + + {envio.numeroDeContenedor} + + + {/if} + + {envio.partida.ubigeo }} + {envio.partida.direccion }} + + {#if envio.codigoDePuerto} + + {{ envio.codigoDePuerto }} + + {/if} + + {#each detalles.orEmpty} + + {it_index.add(1)} + {it.cantidad} + + {it_index.add(1)} + + + + + {it.codigo} + + {#if it.codigoSunat} + + {it.codigoSunat} + + {/if} + + + {/each} + diff --git a/core/src/test/java/e2e/renderer/XMLAssertUtils.java b/core/src/test/java/e2e/renderer/XMLAssertUtils.java index faac3aad..656eda10 100644 --- a/core/src/test/java/e2e/renderer/XMLAssertUtils.java +++ b/core/src/test/java/e2e/renderer/XMLAssertUtils.java @@ -67,6 +67,7 @@ public class XMLAssertUtils { public static final String INVOICE_XSD = "xsd/2.1/maindoc/UBL-Invoice-2.1.xsd"; public static final String CREDIT_NOTE_XSD = "xsd/2.1/maindoc/UBL-CreditNote-2.1.xsd"; public static final String DEBIT_NOTE_XSD = "xsd/2.1/maindoc/UBL-DebitNote-2.1.xsd"; + public static final String DESPATCH_ADVICE_XSD = "xsd/2.1/maindoc/UBL-DespatchAdvice-2.1.xsd"; public static final String VOIDED_DOCUMENTS_XSD = "xsd/2.0/maindoc/UBLPE-VoidedDocuments-1.0.xsd"; public static final String SUMMARY_DOCUMENTS_XSD = "xsd/2.0/maindoc/UBLPE-SummaryDocuments-1.0.xsd"; public static final String PERCEPTION_XSD = "xsd/2.0/maindoc/UBLPE-Perception-1.0.xsd"; @@ -143,8 +144,8 @@ public static void assertSendSunat(String xmlWithoutSignature, String xsdSchema, CERTIFICATE.getX509Certificate(), CERTIFICATE.getPrivateKey() ); - sendFileToSunat(signedXML, xmlWithoutSignature, allowedNotes); isCompliantWithXsd(xsdSchema, signedXML); + sendFileToSunat(signedXML, xmlWithoutSignature, allowedNotes); } } @@ -176,6 +177,12 @@ private static void sendFileToSunat(Document document, String xmlWithoutSignatur BillServiceDestination fileDestination = fileAnalyzer.getSendFileDestination(); BillServiceDestination ticketDestination = fileAnalyzer.getVerifyTicketDestination(); + // TODO mock a Sunat server and test REST sends + if (fileDestination.getRestOperation() != null) { + System.out.println("WARNING: Skipping REST send to SUNAT"); + return; + } + CamelData camelData = getBillServiceCamelData(zipFile, fileDestination, credentials); SunatResponse sendFileSunatResponse = camelContext .createProducerTemplate() @@ -209,12 +216,7 @@ private static void sendFileToSunat(Document document, String xmlWithoutSignatur assertEquals( Status.ACEPTADO, sendFileSunatResponse.getStatus(), - xmlWithoutSignature + - " \n sunat [codigo=" + - sendFileSunatResponse.getMetadata().getResponseCode() + - "], [descripcion=" + - sendFileSunatResponse.getMetadata().getDescription() + - "]" + xmlWithoutSignature + " \n sunat [codigo=" + sendFileSunatResponse.getMetadata().getResponseCode() + "], [descripcion=" + sendFileSunatResponse.getMetadata().getDescription() + "]" ); } else { assertNotNull(sendFileSunatResponse.getSunat().getTicket()); @@ -236,21 +238,11 @@ private static void sendFileToSunat(Document document, String xmlWithoutSignatur assertEquals( Status.ACEPTADO, verifyTicketSunatResponse.getStatus(), - xmlWithoutSignature + - " sunat [status=" + - verifyTicketSunatResponse.getStatus() + - "], [descripcion=" + - verifyTicketSunatResponse.getMetadata().getDescription() + - "]" + xmlWithoutSignature + " sunat [status=" + verifyTicketSunatResponse.getStatus() + "], [descripcion=" + verifyTicketSunatResponse.getMetadata().getDescription() + "]" ); assertNotNull( verifyTicketSunatResponse.getSunat().getCdr(), - xmlWithoutSignature + - " sunat [codigo=" + - verifyTicketSunatResponse.getMetadata().getResponseCode() + - "], [descripcion=" + - verifyTicketSunatResponse.getMetadata().getDescription() + - "]" + xmlWithoutSignature + " sunat [codigo=" + verifyTicketSunatResponse.getMetadata().getResponseCode() + "], [descripcion=" + verifyTicketSunatResponse.getMetadata().getDescription() + "]" ); } } diff --git a/core/src/test/java/e2e/renderer/despatchadvice/DespatchAdviceTest.java b/core/src/test/java/e2e/renderer/despatchadvice/DespatchAdviceTest.java new file mode 100644 index 00000000..940f6f70 --- /dev/null +++ b/core/src/test/java/e2e/renderer/despatchadvice/DespatchAdviceTest.java @@ -0,0 +1,106 @@ +/* + * Copyright 2019 Project OpenUBL, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License - 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package e2e.renderer.despatchadvice; + +import e2e.AbstractTest; +import e2e.renderer.XMLAssertUtils; +import io.github.project.openubl.xbuilder.content.catalogs.Catalog1; +import io.github.project.openubl.xbuilder.content.catalogs.Catalog18; +import io.github.project.openubl.xbuilder.content.catalogs.Catalog1_Invoice; +import io.github.project.openubl.xbuilder.content.catalogs.Catalog20; +import io.github.project.openubl.xbuilder.content.catalogs.Catalog6; +import io.github.project.openubl.xbuilder.content.models.common.Proveedor; +import io.github.project.openubl.xbuilder.content.models.standard.guia.DespatchAdvice; +import io.github.project.openubl.xbuilder.content.models.standard.guia.DespatchAdviceItem; +import io.github.project.openubl.xbuilder.content.models.standard.guia.Destinatario; +import io.github.project.openubl.xbuilder.content.models.standard.guia.Destino; +import io.github.project.openubl.xbuilder.content.models.standard.guia.Envio; +import io.github.project.openubl.xbuilder.content.models.standard.guia.Partida; +import io.github.project.openubl.xbuilder.content.models.standard.guia.Remitente; +import io.github.project.openubl.xbuilder.content.models.sunat.baja.VoidedDocuments; +import io.github.project.openubl.xbuilder.content.models.sunat.baja.VoidedDocumentsItem; +import io.github.project.openubl.xbuilder.enricher.ContentEnricher; +import io.github.project.openubl.xbuilder.renderer.TemplateProducer; +import io.quarkus.qute.Template; +import org.junit.jupiter.api.Test; + +import java.math.BigDecimal; +import java.time.LocalDate; + +import static e2e.renderer.XMLAssertUtils.assertSendSunat; +import static e2e.renderer.XMLAssertUtils.assertSnapshot; + +public class DespatchAdviceTest extends AbstractTest { + + @Test + public void testBasicMinData() throws Exception { + // Given + DespatchAdvice input = DespatchAdvice.builder() + .serie("T001") + .numero(1) + .tipoComprobante(Catalog1.GUIA_REMISION_REMITENTE.getCode()) + .remitente(Remitente.builder() + .ruc("12345678912") + .razonSocial("Softgreen S.A.C.") + .build() + ) + .destinatario(Destinatario.builder() + .tipoDocumentoIdentidad(Catalog6.DNI.getCode()) + .numeroDocumentoIdentidad("12345678") + .nombre("mi cliente") + .build() + ) + .envio(Envio.builder() + .tipoTraslado(Catalog20.TRASLADO_EMISOR_ITINERANTE_CP.getCode()) + .pesoTotal(BigDecimal.ONE) + .pesoTotalUnidadMedida("KG") + .transbordoProgramado(false) + .tipoModalidadTraslado(Catalog18.TRANSPORTE_PRIVADO.getCode()) + .fechaTraslado(dateProvider.now()) + .partida(Partida.builder() + .direccion("DireccionOrigen") + .ubigeo("010101") + .build() + ) + .destino(Destino.builder() + .direccion("DireccionDestino") + .ubigeo("020202") + .build() + ) + .build() + ) + .detalle(DespatchAdviceItem.builder() + .cantidad(new BigDecimal("0.5")) + .unidadMedida("KG") + .codigo("123456") + .build() + ) + .build(); + + ContentEnricher enricher = new ContentEnricher(defaults, dateProvider); + enricher.enrich(input); + + // When + Template template = TemplateProducer.getInstance().getDespatchAdvice(); + String xml = template.data(input).render(); + + // Then + assertSnapshot(xml, getClass(), "minData.xml"); + assertSendSunat(xml, XMLAssertUtils.DESPATCH_ADVICE_XSD); + } + +} diff --git a/core/src/test/resources/e2e/renderer/despatchadvice/DespatchAdviceTest/minData.xml b/core/src/test/resources/e2e/renderer/despatchadvice/DespatchAdviceTest/minData.xml new file mode 100644 index 00000000..ed28a68b --- /dev/null +++ b/core/src/test/resources/e2e/renderer/despatchadvice/DespatchAdviceTest/minData.xml @@ -0,0 +1,92 @@ + + + + + + + + 2.1 + 2.0 + T001-1 + 2019-12-24 + 09 + + 12345678912 + + + 12345678912 + + + + + + + + #PROJECT-OPENUBL-SIGN + + + + + 12345678912 + + + 12345678912 + + + + + + + + + + 12345678 + + + + + + + + 1 + 18 + 1.000 + false + + 02 + + 2019-12-24 + + + + + 020202 + + DireccionDestino + + + + + 010101} + DireccionOrigen} + + + + 1 + 0.5 + + 1 + + + + + 123456 + + + + diff --git a/pom.xml b/pom.xml index 5cacd543..3d9d2510 100644 --- a/pom.xml +++ b/pom.xml @@ -47,7 +47,7 @@ 1.18.24 2.15.2.Final 2.9.0 - 4.0.0.Final + 4.1.0 https://project-openubl.github.io/ diff --git a/quarkus-extension/deployment/src/main/java/io/github/project/openubl/quarkus/xbuilder/deployment/QuarkusXbuilderProcessor.java b/quarkus-extension/deployment/src/main/java/io/github/project/openubl/quarkus/xbuilder/deployment/QuarkusXbuilderProcessor.java index bbc5232b..c9c360d0 100644 --- a/quarkus-extension/deployment/src/main/java/io/github/project/openubl/quarkus/xbuilder/deployment/QuarkusXbuilderProcessor.java +++ b/quarkus-extension/deployment/src/main/java/io/github/project/openubl/quarkus/xbuilder/deployment/QuarkusXbuilderProcessor.java @@ -44,8 +44,7 @@ FeatureBuildItem feature() { @BuildStep AdditionalBeanBuildItem additionalBeans() { - return AdditionalBeanBuildItem - .builder() + return AdditionalBeanBuildItem.builder() .setUnremovable() .addBeanClasses(XBuilder.class, DefaultXBuilder.class, CustomTemplateLocator.class) .build(); @@ -62,6 +61,7 @@ void registerTemplates(BuildProducer resource) thr "templates/Renderer/summaryDocuments.xml", "templates/Renderer/perception.xml", "templates/Renderer/retention.xml", + "templates/Renderer/despatchAdvice.xml", "templates/ubl/common/signature.xml", @@ -177,6 +177,29 @@ ReflectiveClassBuildItem reflection() { io.github.project.openubl.xbuilder.content.models.standard.general.TotalImpuestos.class, io.github.project.openubl.xbuilder.content.models.standard.general.TotalImpuestos.TotalImpuestosBuilder.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.DespatchAdvice.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.DespatchAdvice.DespatchAdviceBuilder.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.DespatchAdviceItem.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.DespatchAdviceItem.DespatchAdviceItemBuilder.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.Destinatario.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.Destinatario.DestinatarioBuilder.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.Destino.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.Destino.DestinoBuilder.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.DocumentoBaja.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.DocumentoBaja.DocumentoBajaBuilder.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.DocumentoRelacionado.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.DocumentoRelacionado.DocumentoRelacionadoBuilder.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.Envio.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.Envio.EnvioBuilder.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.Partida.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.Partida.PartidaBuilder.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.Proveedor.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.Proveedor.ProveedorBuilder.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.Remitente.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.Remitente.RemitenteBuilder.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.Transportista.class, + io.github.project.openubl.xbuilder.content.models.standard.guia.Transportista.TransportistaBuilder.class, + io.github.project.openubl.xbuilder.content.catalogs.Catalog.class, io.github.project.openubl.xbuilder.content.catalogs.CatalogContadoCredito.class, io.github.project.openubl.xbuilder.content.catalogs.Catalog1.class, diff --git a/quarkus-extension/integration-tests/src/main/java/io/github/project/openubl/quarkus/xbuilder/it/QuarkusXbuilderResource.java b/quarkus-extension/integration-tests/src/main/java/io/github/project/openubl/quarkus/xbuilder/it/QuarkusXbuilderResource.java index 0e5f7a5e..3284ee6e 100644 --- a/quarkus-extension/integration-tests/src/main/java/io/github/project/openubl/quarkus/xbuilder/it/QuarkusXbuilderResource.java +++ b/quarkus-extension/integration-tests/src/main/java/io/github/project/openubl/quarkus/xbuilder/it/QuarkusXbuilderResource.java @@ -20,6 +20,7 @@ import io.github.project.openubl.xbuilder.content.models.standard.general.CreditNote; import io.github.project.openubl.xbuilder.content.models.standard.general.DebitNote; import io.github.project.openubl.xbuilder.content.models.standard.general.Invoice; +import io.github.project.openubl.xbuilder.content.models.standard.guia.DespatchAdvice; import io.github.project.openubl.xbuilder.content.models.sunat.baja.VoidedDocuments; import io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.Perception; import io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.Retention; @@ -39,6 +40,7 @@ import static io.github.project.openubl.quarkus.xbuilder.XBuilder.Type.CREDIT_NOTE; import static io.github.project.openubl.quarkus.xbuilder.XBuilder.Type.DEBIT_NOTE; +import static io.github.project.openubl.quarkus.xbuilder.XBuilder.Type.DESPATCH_ADVICE; import static io.github.project.openubl.quarkus.xbuilder.XBuilder.Type.INVOICE; import static io.github.project.openubl.quarkus.xbuilder.XBuilder.Type.PERCEPTION; import static io.github.project.openubl.quarkus.xbuilder.XBuilder.Type.RETENTION; @@ -138,4 +140,17 @@ public String createRetention(JsonObject json) { return template.data(retention).render(); } + @POST + @Path("despatch-advice") + public String createDespatchAdvice(JsonObject json) { + DespatchAdvice despatchAdvice = json.mapTo(DespatchAdvice.class); + + ContentEnricher enricher = new ContentEnricher(xBuilder.getDefaults(), () -> LocalDate.of(2022, 1, 25)); + enricher.enrich(despatchAdvice); + + Template template = xBuilder.getTemplate(DESPATCH_ADVICE); + String xml = template.data(despatchAdvice).render(); + return xml; + } + } diff --git a/quarkus-extension/integration-tests/src/test/java/io/github/project/openubl/quarkus/xbuilder/it/QuarkusXbuilderResourceTest.java b/quarkus-extension/integration-tests/src/test/java/io/github/project/openubl/quarkus/xbuilder/it/QuarkusXbuilderResourceTest.java index 793aee79..8fb73120 100644 --- a/quarkus-extension/integration-tests/src/test/java/io/github/project/openubl/quarkus/xbuilder/it/QuarkusXbuilderResourceTest.java +++ b/quarkus-extension/integration-tests/src/test/java/io/github/project/openubl/quarkus/xbuilder/it/QuarkusXbuilderResourceTest.java @@ -17,8 +17,10 @@ package io.github.project.openubl.quarkus.xbuilder.it; import io.github.project.openubl.xbuilder.content.catalogs.Catalog1; +import io.github.project.openubl.xbuilder.content.catalogs.Catalog18; import io.github.project.openubl.xbuilder.content.catalogs.Catalog19; import io.github.project.openubl.xbuilder.content.catalogs.Catalog1_Invoice; +import io.github.project.openubl.xbuilder.content.catalogs.Catalog20; import io.github.project.openubl.xbuilder.content.catalogs.Catalog22; import io.github.project.openubl.xbuilder.content.catalogs.Catalog23; import io.github.project.openubl.xbuilder.content.catalogs.Catalog6; @@ -28,6 +30,13 @@ import io.github.project.openubl.xbuilder.content.models.standard.general.DebitNote; import io.github.project.openubl.xbuilder.content.models.standard.general.DocumentoVentaDetalle; import io.github.project.openubl.xbuilder.content.models.standard.general.Invoice; +import io.github.project.openubl.xbuilder.content.models.standard.guia.DespatchAdvice; +import io.github.project.openubl.xbuilder.content.models.standard.guia.DespatchAdviceItem; +import io.github.project.openubl.xbuilder.content.models.standard.guia.Destinatario; +import io.github.project.openubl.xbuilder.content.models.standard.guia.Destino; +import io.github.project.openubl.xbuilder.content.models.standard.guia.Envio; +import io.github.project.openubl.xbuilder.content.models.standard.guia.Partida; +import io.github.project.openubl.xbuilder.content.models.standard.guia.Remitente; import io.github.project.openubl.xbuilder.content.models.sunat.baja.VoidedDocuments; import io.github.project.openubl.xbuilder.content.models.sunat.baja.VoidedDocumentsItem; import io.github.project.openubl.xbuilder.content.models.sunat.percepcionretencion.PercepcionRetencionOperacion; @@ -1074,4 +1083,149 @@ public void testRetention() { " \n" + "\n")); } + + @Test + public void testDespatchAdvice() { + DespatchAdvice despatchAdvice = DespatchAdvice.builder() + .serie("T001") + .numero(1) + .tipoComprobante(Catalog1.GUIA_REMISION_REMITENTE.getCode()) + .remitente(Remitente.builder() + .ruc("12345678912") + .razonSocial("Softgreen S.A.C.") + .build() + ) + .destinatario(Destinatario.builder() + .tipoDocumentoIdentidad(Catalog6.DNI.getCode()) + .numeroDocumentoIdentidad("12345678") + .nombre("mi cliente") + .build() + ) + .envio(Envio.builder() + .tipoTraslado(Catalog20.TRASLADO_EMISOR_ITINERANTE_CP.getCode()) + .pesoTotal(BigDecimal.ONE) + .pesoTotalUnidadMedida("KG") + .transbordoProgramado(false) + .tipoModalidadTraslado(Catalog18.TRANSPORTE_PRIVADO.getCode()) + .fechaTraslado(LocalDate.of(2022, 1, 25)) + .partida(Partida.builder() + .direccion("DireccionOrigen") + .ubigeo("010101") + .build() + ) + .destino(Destino.builder() + .direccion("DireccionDestino") + .ubigeo("020202") + .build() + ) + .build() + ) + .detalle(DespatchAdviceItem.builder() + .cantidad(new BigDecimal("0.5")) + .unidadMedida("KG") + .codigo("123456") + .build() + ) + .build(); + + given() + .when() + .contentType(ContentType.JSON) + .body(despatchAdvice) + .post("/quarkus-xbuilder/despatch-advice") + .then() + .statusCode(200) + .body(is("\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 2.1\n" + + " 2.0\n" + + " T001-1\n" + + " 2022-01-25\n" + + " 09\n" + + " \n" + + " 12345678912\n" + + " \n" + + " \n" + + " 12345678912\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " #PROJECT-OPENUBL-SIGN\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 12345678912\n" + + " \n" + + " \n" + + " 12345678912\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 12345678\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 1\n" + + " 18\n" + + " 1.000\n" + + " false\n" + + " \n" + + " 02\n" + + " \n" + + " 2022-01-25\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 020202\n" + + " \n" + + " DireccionDestino\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 010101}\n" + + " DireccionOrigen}\n" + + " \n" + + " \n" + + " \n" + + " 1\n" + + " 0.5\n" + + " \n" + + " 1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 123456\n" + + " \n" + + " \n" + + " \n" + + "\n")); + } } diff --git a/quarkus-extension/runtime/src/main/java/io/github/project/openubl/quarkus/xbuilder/XBuilder.java b/quarkus-extension/runtime/src/main/java/io/github/project/openubl/quarkus/xbuilder/XBuilder.java index 591e7c3b..e627c067 100644 --- a/quarkus-extension/runtime/src/main/java/io/github/project/openubl/quarkus/xbuilder/XBuilder.java +++ b/quarkus-extension/runtime/src/main/java/io/github/project/openubl/quarkus/xbuilder/XBuilder.java @@ -31,7 +31,8 @@ enum Type { VOIDED_DOCUMENTS("voidedDocuments.xml"), SUMMARY_DOCUMENTS("summaryDocuments.xml"), PERCEPTION("perception.xml"), - RETENTION("retention.xml"),; + RETENTION("retention.xml"), + DESPATCH_ADVICE("despatchAdvice.xml"); private final String templatePath;