diff --git a/README.md b/README.md index b7a9a4d5..4aec3353 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,6 @@ ![CI](https://github.com/project-openubl/xbuilder/workflows/CI/badge.svg) [![Project Chat](https://img.shields.io/badge/zulip-join_chat-brightgreen.svg?style=for-the-badge&logo=zulip)](https://projectopenubl.zulipchat.com/) -[![Supported JVM Versions](https://img.shields.io/badge/JVM-11--17-brightgreen.svg?style=for-the-badge&logo=Java)](https://github.com/project-openubl/xbuilder/actions/runs/472762588/) - -| Artifact | Version | -|----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| XBuilder | [![Maven Central](https://img.shields.io/maven-central/v/io.github.project-openubl/xbuilder)](https://search.maven.org/artifact/io.github.project-openubl/xbuilder/) | -| XBuilder Quarkus extension | [![Maven Central](https://img.shields.io/maven-central/v/io.github.project-openubl/quarkus-xbuilder)](https://search.maven.org/artifact/io.github.project-openubl/quarkus-xbuilder/) | # XBuilder diff --git a/src/catalogs/mod.rs b/src/catalogs.rs similarity index 86% rename from src/catalogs/mod.rs rename to src/catalogs.rs index f05d8166..6f73783d 100644 --- a/src/catalogs/mod.rs +++ b/src/catalogs.rs @@ -1,67 +1,19 @@ use std::fmt; use std::fmt::{Display, Formatter}; +/// A trait for providing the 'code' of a catalog pub trait Catalog { fn code(&self) -> &str; } -pub trait Label { - fn label(&self) -> &str; -} - -pub fn catalog7_value_of_code(code: &str) -> Option { - match code { - "10" => Some(Catalog7::GravadoOperacionOnerosa), - "11" => Some(Catalog7::GravadoRetiroPorPremio), - "12" => Some(Catalog7::GravadoRetiroPorDonacion), - "13" => Some(Catalog7::GravadoRetiro), - "14" => Some(Catalog7::GravadoRetiroPorPublicidad), - "15" => Some(Catalog7::GravadoBonificaciones), - "16" => Some(Catalog7::GravadoRetiroPorEntregaATrabajadores), - "17" => Some(Catalog7::GravadoIvap), - - "20" => Some(Catalog7::ExoneradoOperacionOnerosa), - "21" => Some(Catalog7::ExoneradoTransferenciaGratuita), - - "30" => Some(Catalog7::InafectoOperacionOnerosa), - "31" => Some(Catalog7::InafectoRetiroPorBonificacion), - "32" => Some(Catalog7::InafectoRetiro), - "33" => Some(Catalog7::InafectoRetiroPorMuestrasMedicas), - "34" => Some(Catalog7::InafectoRetiroPorConvenioColectivo), - "35" => Some(Catalog7::InafectoRetiroPorPremio), - "36" => Some(Catalog7::InafectoRetiroPorPublicidad), - - "40" => Some(Catalog7::Exportacion), - _ => None, - } +/// A trait for getting a catalog from its 'code' +pub trait FromCode: Sized { + fn from_code(code: &str) -> Result; } -pub fn catalog53_value_of_code(code: &'static str) -> Option { - match code { - "00" => Some(Catalog53::DescuentoAfectaBaseImponibleIgvIvap), - "01" => Some(Catalog53::DescuentoNoAfectaBaseImponibleIgvIvap), - "02" => Some(Catalog53::DescuentoGlobalAfectaBaseImponibleIgvIvap), - "03" => Some(Catalog53::DescuentoGlobalNoAfectaBaseImponibleIgvIvap), - "04" => Some(Catalog53::DescuentoGlobalPorAnticiposGravadosAfectaBaseImponibleIgvIvap), - "05" => Some(Catalog53::DescuentoGlobalPorAnticiposExonerados), - "06" => Some(Catalog53::DescuentoGlobalPorAnticiposInafectos), - "07" => Some(Catalog53::FactorDeCompensacion), - "20" => Some(Catalog53::AnticipoDeIsc), - "45" => Some(Catalog53::FISE), - "46" => Some(Catalog53::RecargoAlConsumoYOPropinas), - "47" => Some(Catalog53::CargosQueAfectanBaseImponibleIgvIvap), - "48" => Some(Catalog53::CargosQueNoAfectanBaseImponibleIgvIvap), - "49" => Some(Catalog53::CargosGlobalesQueAfectanBaseImponibleIgvIvap), - "50" => Some(Catalog53::CargosGlobalesQueNoAfectanBaseImponibleIgvIvap), - "51" => Some(Catalog53::PercepcionVentaInterna), - "52" => Some(Catalog53::PercepcionALaAdquisicionDeCombustible), - "53" => Some(Catalog53::PercepcionRealizadaAlAgenteDePercepcionConTasaEspecial), - "61" => Some(Catalog53::FactorDeAportacion), - "62" => Some(Catalog53::RetencionDeRentaPorAnticipos), - "63" => Some(Catalog53::RetencionDelIgv), - "64" => Some(Catalog53::RetencionDeRentaDeSegundaCategoria), - _ => None, - } +/// A trait for providing a 'label' representation +pub trait Label { + fn label(&self) -> &str; } #[derive(Clone, Debug)] @@ -367,6 +319,36 @@ impl Display for Catalog7 { } } +impl FromCode for Catalog7 { + fn from_code(code: &str) -> Result { + match code { + "10" => Ok(Catalog7::GravadoOperacionOnerosa), + "11" => Ok(Catalog7::GravadoRetiroPorPremio), + "12" => Ok(Catalog7::GravadoRetiroPorDonacion), + "13" => Ok(Catalog7::GravadoRetiro), + "14" => Ok(Catalog7::GravadoRetiroPorPublicidad), + "15" => Ok(Catalog7::GravadoBonificaciones), + "16" => Ok(Catalog7::GravadoRetiroPorEntregaATrabajadores), + "17" => Ok(Catalog7::GravadoIvap), + + "20" => Ok(Catalog7::ExoneradoOperacionOnerosa), + "21" => Ok(Catalog7::ExoneradoTransferenciaGratuita), + + "30" => Ok(Catalog7::InafectoOperacionOnerosa), + "31" => Ok(Catalog7::InafectoRetiroPorBonificacion), + "32" => Ok(Catalog7::InafectoRetiro), + "33" => Ok(Catalog7::InafectoRetiroPorMuestrasMedicas), + "34" => Ok(Catalog7::InafectoRetiroPorConvenioColectivo), + "35" => Ok(Catalog7::InafectoRetiroPorPremio), + "36" => Ok(Catalog7::InafectoRetiroPorPublicidad), + + "40" => Ok(Catalog7::Exportacion), + + _ => Err(format!("code {code} did not match")), + } + } +} + #[derive(Clone, Debug)] pub enum Catalog8 { SistemaAlValor, @@ -582,6 +564,36 @@ impl Catalog for Catalog53 { } } +impl FromCode for Catalog53 { + fn from_code(code: &str) -> Result { + match code { + "00" => Ok(Catalog53::DescuentoAfectaBaseImponibleIgvIvap), + "01" => Ok(Catalog53::DescuentoNoAfectaBaseImponibleIgvIvap), + "02" => Ok(Catalog53::DescuentoGlobalAfectaBaseImponibleIgvIvap), + "03" => Ok(Catalog53::DescuentoGlobalNoAfectaBaseImponibleIgvIvap), + "04" => Ok(Catalog53::DescuentoGlobalPorAnticiposGravadosAfectaBaseImponibleIgvIvap), + "05" => Ok(Catalog53::DescuentoGlobalPorAnticiposExonerados), + "06" => Ok(Catalog53::DescuentoGlobalPorAnticiposInafectos), + "07" => Ok(Catalog53::FactorDeCompensacion), + "20" => Ok(Catalog53::AnticipoDeIsc), + "45" => Ok(Catalog53::FISE), + "46" => Ok(Catalog53::RecargoAlConsumoYOPropinas), + "47" => Ok(Catalog53::CargosQueAfectanBaseImponibleIgvIvap), + "48" => Ok(Catalog53::CargosQueNoAfectanBaseImponibleIgvIvap), + "49" => Ok(Catalog53::CargosGlobalesQueAfectanBaseImponibleIgvIvap), + "50" => Ok(Catalog53::CargosGlobalesQueNoAfectanBaseImponibleIgvIvap), + "51" => Ok(Catalog53::PercepcionVentaInterna), + "52" => Ok(Catalog53::PercepcionALaAdquisicionDeCombustible), + "53" => Ok(Catalog53::PercepcionRealizadaAlAgenteDePercepcionConTasaEspecial), + "61" => Ok(Catalog53::FactorDeAportacion), + "62" => Ok(Catalog53::RetencionDeRentaPorAnticipos), + "63" => Ok(Catalog53::RetencionDelIgv), + "64" => Ok(Catalog53::RetencionDeRentaDeSegundaCategoria), + _ => Err(format!("code {code} did not match")), + } + } +} + #[derive(Clone, Debug)] pub enum Catalog54 { Azucar, diff --git a/src/enricher/rules/phase1fill/detalle/igvtasa.rs b/src/enricher/rules/phase1fill/detalle/igvtasa.rs index 1c0184f7..d599b866 100644 --- a/src/enricher/rules/phase1fill/detalle/igvtasa.rs +++ b/src/enricher/rules/phase1fill/detalle/igvtasa.rs @@ -1,6 +1,6 @@ use rust_decimal::Decimal; -use crate::catalogs::{catalog7_value_of_code, Catalog7, Catalog7Group}; +use crate::catalogs::{Catalog7, Catalog7Group, FromCode}; use crate::enricher::rules::phase1fill::detalle::detalles::DetalleDefaults; use crate::models::traits::detalle::igvtasa::{DetalleIGVTasaGetter, DetalleIGVTasaSetter}; use crate::models::traits::detalle::igvtipo::DetalleIGVTipoGetter; @@ -16,7 +16,7 @@ where fn fill(&mut self, defaults: &DetalleDefaults) -> bool { match (self.get_igvtasa(), *self.get_igvtipo()) { (None, Some(igv_tipo)) => { - if let Some(catalog) = catalog7_value_of_code(igv_tipo) { + if let Ok(catalog) = Catalog7::from_code(igv_tipo) { let tasa = match catalog { Catalog7::GravadoIvap => defaults.ivap_tasa, _ => match catalog.group() { diff --git a/src/enricher/rules/phase1fill/detalle/isctasa.rs b/src/enricher/rules/phase1fill/detalle/isctasa.rs index 0922806b..9a47c044 100644 --- a/src/enricher/rules/phase1fill/detalle/isctasa.rs +++ b/src/enricher/rules/phase1fill/detalle/isctasa.rs @@ -1,7 +1,7 @@ use log::trace; use rust_decimal::Decimal; -use crate::catalogs::{catalog7_value_of_code, Catalog7Group}; +use crate::catalogs::{Catalog7, Catalog7Group, FromCode}; use crate::enricher::rules::phase1fill::detalle::detalles::DetalleDefaults; use crate::models::traits::detalle::igvtipo::DetalleIGVTipoGetter; use crate::models::traits::detalle::isctasa::{DetalleISCTasaGetter, DetalleISCTasaSetter}; @@ -17,7 +17,7 @@ where fn fill(&mut self, _: &DetalleDefaults) -> bool { match (&self.get_isctasa(), &self.get_igvtipo()) { (Some(isc_tasa), Some(igv_tipo)) => { - if let Some(catalog) = catalog7_value_of_code(igv_tipo) { + if let Ok(catalog) = Catalog7::from_code(igv_tipo) { let tasa = if !catalog.onerosa() { Decimal::ZERO } else { diff --git a/src/enricher/rules/phase1fill/detalle/precioreferenciatipo.rs b/src/enricher/rules/phase1fill/detalle/precioreferenciatipo.rs index 0e23d0fc..dd17ef03 100644 --- a/src/enricher/rules/phase1fill/detalle/precioreferenciatipo.rs +++ b/src/enricher/rules/phase1fill/detalle/precioreferenciatipo.rs @@ -1,4 +1,4 @@ -use crate::catalogs::{catalog7_value_of_code, Catalog, Catalog16}; +use crate::catalogs::{Catalog, Catalog16, Catalog7, FromCode}; use crate::enricher::rules::phase1fill::detalle::detalles::DetalleDefaults; use crate::models::traits::detalle::igvtipo::DetalleIGVTipoGetter; use crate::models::traits::detalle::precioreferenciatipo::{ @@ -16,7 +16,7 @@ where fn fill(&mut self, _: &DetalleDefaults) -> bool { match (self.get_precioreferenciatipo(), *self.get_igvtipo()) { (None, Some(igv_tipo)) => { - if let Some(catalog) = catalog7_value_of_code(igv_tipo) { + if let Ok(catalog) = Catalog7::from_code(igv_tipo) { let catalog16 = if catalog.onerosa() { &Catalog16::PrecioUnitarioIncluyeIgv } else { diff --git a/src/enricher/rules/phase1fill/invoice/anticipos.rs b/src/enricher/rules/phase1fill/invoice/anticipos.rs index 6b059876..bf9d7e9a 100644 --- a/src/enricher/rules/phase1fill/invoice/anticipos.rs +++ b/src/enricher/rules/phase1fill/invoice/anticipos.rs @@ -1,11 +1,11 @@ use log::warn; use regex::Regex; +use crate::{BOLETA_SERIE_REGEX, FACTURA_SERIE_REGEX}; use crate::catalogs::{Catalog, Catalog12, Catalog53}; use crate::models::traits::invoice::anticipos::{ AnticipoGetter, AnticipoSetter, InvoiceAnticiposGetter, }; -use crate::{BOLETA_SERIE_REGEX, FACTURA_SERIE_REGEX}; pub trait InvoiceAnticiposEnrichRule { fn fill(&mut self) -> bool; diff --git a/src/enricher/rules/phase1fill/invoice/tipocomprobante.rs b/src/enricher/rules/phase1fill/invoice/tipocomprobante.rs index 30d5e5a4..869d55d9 100644 --- a/src/enricher/rules/phase1fill/invoice/tipocomprobante.rs +++ b/src/enricher/rules/phase1fill/invoice/tipocomprobante.rs @@ -1,11 +1,11 @@ use regex::Regex; +use crate::{BOLETA_SERIE_REGEX, FACTURA_SERIE_REGEX}; use crate::catalogs::{Catalog, Catalog1}; use crate::models::traits::invoice::tipocomprobante::{ InvoiceTipoComprobanteGetter, InvoiceTipoComprobanteSetter, }; use crate::models::traits::serienumero::SerieNumeroGetter; -use crate::{BOLETA_SERIE_REGEX, FACTURA_SERIE_REGEX}; pub trait InvoiceTipoComprobanteEnrichRule { fn fill(&mut self) -> bool; diff --git a/src/enricher/rules/phase1fill/note/tipocomprobanteafectado.rs b/src/enricher/rules/phase1fill/note/tipocomprobanteafectado.rs index 2b2122b7..aa92cc92 100644 --- a/src/enricher/rules/phase1fill/note/tipocomprobanteafectado.rs +++ b/src/enricher/rules/phase1fill/note/tipocomprobanteafectado.rs @@ -1,12 +1,12 @@ use log::warn; use regex::Regex; +use crate::{BOLETA_SERIE_REGEX, FACTURA_SERIE_REGEX}; use crate::catalogs::{Catalog, Catalog1}; use crate::models::traits::note::tipocomprobanteafectado::{ NoteTipoComprobanteAfectadoGetter, NoteTipoComprobanteAfectadoSetter, }; use crate::models::traits::serienumero::SerieNumeroGetter; -use crate::{BOLETA_SERIE_REGEX, FACTURA_SERIE_REGEX}; pub trait NoteTipoComprobanteAfectadoEnrichRule { fn fill(&mut self) -> bool; diff --git a/src/enricher/rules/phase2process/detalle/igv_base_imponible.rs b/src/enricher/rules/phase2process/detalle/igv_base_imponible.rs index 6ee49c84..6bfe5c2b 100644 --- a/src/enricher/rules/phase2process/detalle/igv_base_imponible.rs +++ b/src/enricher/rules/phase2process/detalle/igv_base_imponible.rs @@ -1,6 +1,6 @@ use log::warn; -use crate::catalogs::catalog7_value_of_code; +use crate::catalogs::FromCode; use crate::models::traits::detalle::cantidad::DetalleCantidadGetter; use crate::models::traits::detalle::igvbaseimponible::{ DetalleIGVBaseImponibleGetter, DetalleIGVBaseImponibleSetter, @@ -9,6 +9,7 @@ use crate::models::traits::detalle::igvtipo::DetalleIGVTipoGetter; use crate::models::traits::detalle::isc::DetalleISCGetter; use crate::models::traits::detalle::precio::DetallePrecioGetter; use crate::models::traits::detalle::precioreferencia::DetallePrecioReferenciaGetter; +use crate::prelude::Catalog7; pub trait DetalleIGVBaseImponibleProcessRule { fn process(&mut self) -> bool; @@ -33,7 +34,7 @@ where &self.get_isc(), ) { (None, Some(igv_tipo), Some(precio), Some(precio_referencia), Some(isc)) => { - if let Some(catalog) = catalog7_value_of_code(igv_tipo) { + if let Ok(catalog) = Catalog7::from_code(igv_tipo) { let base_imponible = if catalog.onerosa() { self.get_cantidad() * precio } else { diff --git a/src/enricher/rules/phase2process/detalle/isc.rs b/src/enricher/rules/phase2process/detalle/isc.rs index 5fa23775..77518d2b 100644 --- a/src/enricher/rules/phase2process/detalle/isc.rs +++ b/src/enricher/rules/phase2process/detalle/isc.rs @@ -1,6 +1,6 @@ use rust_decimal::Decimal; -use crate::catalogs::{catalog7_value_of_code, Catalog7Group}; +use crate::catalogs::{Catalog7, Catalog7Group, FromCode}; use crate::models::traits::detalle::igvtipo::DetalleIGVTipoGetter; use crate::models::traits::detalle::isc::{DetalleISCGetter, DetalleISCSetter}; use crate::models::traits::detalle::iscbaseimponible::DetalleISCBaseImponibleGetter; @@ -26,7 +26,7 @@ where &self.get_igvtipo(), ) { (None, Some(isc_base_imponible), Some(isc_tasa), Some(igv_tipo)) => { - if let Some(catalog) = catalog7_value_of_code(igv_tipo) { + if let Ok(catalog) = Catalog7::from_code(igv_tipo) { let tasa = if catalog.onerosa() { match catalog.group() { Catalog7Group::Gravado => *isc_tasa, diff --git a/src/enricher/rules/phase2process/detalle/isc_base_imponible.rs b/src/enricher/rules/phase2process/detalle/isc_base_imponible.rs index 570e9a62..27c8a81c 100644 --- a/src/enricher/rules/phase2process/detalle/isc_base_imponible.rs +++ b/src/enricher/rules/phase2process/detalle/isc_base_imponible.rs @@ -1,4 +1,4 @@ -use crate::catalogs::catalog7_value_of_code; +use crate::catalogs::{Catalog7, FromCode}; use crate::models::traits::detalle::cantidad::DetalleCantidadGetter; use crate::models::traits::detalle::igvtipo::DetalleIGVTipoGetter; use crate::models::traits::detalle::iscbaseimponible::{ @@ -28,7 +28,7 @@ where &self.get_precioreferencia(), ) { (None, Some(igv_tipo), Some(precio), Some(precio_referencia)) => { - if let Some(catalog) = catalog7_value_of_code(igv_tipo) { + if let Ok(catalog) = Catalog7::from_code(igv_tipo) { let base_imponible = if catalog.onerosa() { self.get_cantidad() * *precio } else { diff --git a/src/enricher/rules/phase2process/detalle/precio.rs b/src/enricher/rules/phase2process/detalle/precio.rs index 81d872fc..7faba438 100644 --- a/src/enricher/rules/phase2process/detalle/precio.rs +++ b/src/enricher/rules/phase2process/detalle/precio.rs @@ -1,6 +1,6 @@ use rust_decimal::Decimal; -use crate::catalogs::catalog7_value_of_code; +use crate::catalogs::{Catalog7, FromCode}; use crate::models::traits::detalle::igvtasa::DetalleIGVTasaGetter; use crate::models::traits::detalle::igvtipo::DetalleIGVTipoGetter; use crate::models::traits::detalle::isctasa::DetalleISCTasaGetter; @@ -29,7 +29,7 @@ where &self.get_precioconimpuestos(), ) { (None, Some(igv_tipo), Some(igv_tasa), Some(isc_tasa), Some(precio_con_impuestos)) => { - if let Some(catalog) = catalog7_value_of_code(igv_tipo) { + if let Ok(catalog) = Catalog7::from_code(igv_tipo) { let precio = if catalog.onerosa() { precio_con_impuestos / (Decimal::ONE + *igv_tasa) @@ -46,7 +46,7 @@ where } // Si operacion onerosa y precio es diferente de cero => modificarlo (Some(precio), Some(igv_tipo), Some(_), Some(_), Some(_)) => { - if let Some(catalog) = catalog7_value_of_code(igv_tipo) { + if let Ok(catalog) = Catalog7::from_code(igv_tipo) { if !catalog.onerosa() && precio > &Decimal::ZERO { self.set_precio(Decimal::ZERO); true diff --git a/src/enricher/rules/phase2process/detalle/precioconimpuestos.rs b/src/enricher/rules/phase2process/detalle/precioconimpuestos.rs index 9d981f11..5e6b4d32 100644 --- a/src/enricher/rules/phase2process/detalle/precioconimpuestos.rs +++ b/src/enricher/rules/phase2process/detalle/precioconimpuestos.rs @@ -1,6 +1,6 @@ use rust_decimal_macros::dec; -use crate::catalogs::catalog7_value_of_code; +use crate::catalogs::{Catalog7, FromCode}; use crate::models::traits::detalle::igvtasa::DetalleIGVTasaGetter; use crate::models::traits::detalle::igvtipo::DetalleIGVTipoGetter; use crate::models::traits::detalle::isctasa::DetalleISCTasaGetter; @@ -31,7 +31,7 @@ where &self.get_precio(), ) { (None, Some(igv_tipo), Some(igv_tasa), Some(isc_tasa), Some(precio)) => { - if let Some(catalog) = catalog7_value_of_code(igv_tipo) { + if let Ok(catalog) = Catalog7::from_code(igv_tipo) { let precio_con_impuestos = if catalog.onerosa() { precio * (dec!(1) + *igv_tasa) * (dec!(1) + *isc_tasa) } else { @@ -46,7 +46,7 @@ where } // Si operacion no es onerosa y precio es diferente de cero => modificarlo (Some(precio_con_impuestos), Some(igv_tipo), Some(_), Some(_), Some(_)) => { - if let Some(catalog) = catalog7_value_of_code(igv_tipo) { + if let Ok(catalog) = Catalog7::from_code(igv_tipo) { if !catalog.onerosa() && precio_con_impuestos > &dec!(0) { self.set_precioconimpuestos(dec!(0)); true diff --git a/src/enricher/rules/phase2process/detalle/precioreferencia.rs b/src/enricher/rules/phase2process/detalle/precioreferencia.rs index bf12a388..57a4eb8a 100644 --- a/src/enricher/rules/phase2process/detalle/precioreferencia.rs +++ b/src/enricher/rules/phase2process/detalle/precioreferencia.rs @@ -1,10 +1,11 @@ -use crate::catalogs::catalog7_value_of_code; +use crate::catalogs::FromCode; use crate::models::traits::detalle::igvtipo::DetalleIGVTipoGetter; use crate::models::traits::detalle::precio::DetallePrecioGetter; use crate::models::traits::detalle::precioconimpuestos::DetallePrecioConImpuestosGetter; use crate::models::traits::detalle::precioreferencia::{ DetallePrecioReferenciaGetter, DetallePrecioReferenciaSetter, }; +use crate::prelude::Catalog7; pub trait DetallePrecioReferenciaProcessRule { fn process(&mut self) -> bool; @@ -26,7 +27,7 @@ where &self.get_precioconimpuestos(), ) { (None, Some(igv_tipo), Some(precio), Some(precio_con_impuestos)) => { - if let Some(catalog) = catalog7_value_of_code(igv_tipo) { + if let Ok(catalog) = Catalog7::from_code(igv_tipo) { let precio_referencia = if catalog.onerosa() { precio_con_impuestos } else { diff --git a/src/enricher/rules/phase2process/detalle/totalimpuestos.rs b/src/enricher/rules/phase2process/detalle/totalimpuestos.rs index 7c5d85fa..1a4d7d14 100644 --- a/src/enricher/rules/phase2process/detalle/totalimpuestos.rs +++ b/src/enricher/rules/phase2process/detalle/totalimpuestos.rs @@ -1,6 +1,6 @@ use rust_decimal_macros::dec; -use crate::catalogs::catalog7_value_of_code; +use crate::catalogs::{Catalog7, FromCode}; use crate::models::traits::detalle::icb::DetalleICBGetter; use crate::models::traits::detalle::igv::DetalleIGVGetter; use crate::models::traits::detalle::igvtipo::DetalleIGVTipoGetter; @@ -31,7 +31,7 @@ where &self.get_isc(), ) { (None, Some(igv_tipo), Some(igv), Some(icb), Some(isc)) => { - if let Some(catalog) = catalog7_value_of_code(igv_tipo) { + if let Ok(catalog) = Catalog7::from_code(igv_tipo) { let igv_isc = if catalog.onerosa() { (*igv, *isc) } else { diff --git a/src/enricher/rules/phase3summary/invoice/totalimporte.rs b/src/enricher/rules/phase3summary/invoice/totalimporte.rs index daa41309..b03a9ac7 100644 --- a/src/enricher/rules/phase3summary/invoice/totalimporte.rs +++ b/src/enricher/rules/phase3summary/invoice/totalimporte.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use rust_decimal::Decimal; use rust_decimal_macros::dec; -use crate::catalogs::{catalog53_value_of_code, catalog7_value_of_code, Catalog5, Catalog53}; +use crate::catalogs::{Catalog5, Catalog53, Catalog7, FromCode}; use crate::models::general::TotalImporte; use crate::models::traits::detalle::DetallesGetter; use crate::models::traits::igv::IGVTasaGetter; @@ -38,7 +38,7 @@ where .get_detalles() .iter() .filter(|e| { - if let Some(catalog7) = catalog7_value_of_code(e.igv_tipo.unwrap_or("")) { + if let Ok(catalog7) = Catalog7::from_code(e.igv_tipo.unwrap_or("")) { catalog7.tax_category() != Catalog5::Gratuito } else { false @@ -73,7 +73,7 @@ where .iter() .fold(HashMap::new(), |mut acc, current| { if let Some(tipo) = current.tipo { - if let Some(catalog53) = catalog53_value_of_code(tipo) { + if let Ok(catalog53) = Catalog53::from_code(tipo) { let monto = acc.get(&catalog53).unwrap_or(&dec!(0)) + current.monto; acc.insert(catalog53, monto); diff --git a/src/enricher/rules/phase3summary/invoice/totalimpuestos.rs b/src/enricher/rules/phase3summary/invoice/totalimpuestos.rs index 72edbdb1..151c67b6 100644 --- a/src/enricher/rules/phase3summary/invoice/totalimpuestos.rs +++ b/src/enricher/rules/phase3summary/invoice/totalimpuestos.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use rust_decimal::Decimal; use rust_decimal_macros::dec; -use crate::catalogs::{catalog53_value_of_code, catalog7_value_of_code, Catalog5, Catalog53}; +use crate::catalogs::{Catalog5, Catalog53, Catalog7, FromCode}; use crate::models::general::{Detalle, TotalImpuestos}; use crate::models::traits::detalle::DetallesGetter; use crate::models::traits::invoice::anticipos::InvoiceAnticiposGetter; @@ -71,7 +71,7 @@ where let total_anticipos_gravados = &self.get_anticipos().iter() .filter(|e| { if let Some(tipo) = e.tipo { - if let Some(catalog53) = catalog53_value_of_code(tipo) { + if let Ok(catalog53) = Catalog53::from_code(tipo) { catalog53 == Catalog53::DescuentoGlobalPorAnticiposGravadosAfectaBaseImponibleIgvIvap } else { false @@ -90,7 +90,7 @@ where .iter() .fold(HashMap::new(), |mut acc, current| { if let Some(tipo) = current.tipo { - if let Some(catalog53) = catalog53_value_of_code(tipo) { + if let Ok(catalog53) = Catalog53::from_code(tipo) { let monto = acc.get(&catalog53).unwrap_or(&dec!(0)) + current.monto; acc.insert(catalog53, monto); @@ -166,7 +166,7 @@ fn cal_impuesto_by_tipo(detalles: &[Detalle], categoria: Catalog5) -> Impuesto { .iter() .filter(|e| e.igv_tipo.is_some() && e.igv_tipo.is_some()) .filter(|e| { - if let Some(catalog7) = catalog7_value_of_code(e.igv_tipo.unwrap()) { + if let Ok(catalog7) = Catalog7::from_code(e.igv_tipo.unwrap()) { categoria == catalog7.tax_category() } else { false diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index bc574762..00000000 --- a/src/main.rs +++ /dev/null @@ -1,118 +0,0 @@ -use std::collections::HashMap; - -use chrono::NaiveDate; -use rust_decimal_macros::dec; - -use xbuilder::catalogs::{Catalog, Catalog6}; -use xbuilder::enricher::enrich::{Defaults, EnrichTrait}; -use xbuilder::models::common::{Cliente, Proveedor}; -use xbuilder::models::credit_note::CreditNote; -use xbuilder::models::invoice::Invoice; -use xbuilder::renderer::render_invoice; - -fn main() { - let defaults = Defaults { - date: NaiveDate::from_ymd_opt(2023, 1, 1).unwrap(), - icb_tasa: dec!(0.3), - igv_tasa: dec!(0.18), - ivap_tasa: dec!(0.04), - }; - - let mut invoice = Invoice { - leyendas: HashMap::new(), - serie_numero: "F001-1", - icb_tasa: None, - igv_tasa: None, - ivap_tasa: None, - moneda: None, - fecha_emision: None, - hora_emision: None, - fecha_vencimiento: None, - firmante: None, - proveedor: Proveedor { - ruc: "123456789012", - razon_social: "OpenUBL S.A.C.", - nombre_comercial: None, - direccion: None, - contacto: None, - }, - cliente: Cliente { - tipo_documento_identidad: Catalog6::DNI.code(), - numero_documento_identidad: "1234568", - nombre: "Carlos Feria", - direccion: None, - contacto: None, - }, - detraccion: None, - percepcion: None, - direccion_entrega: None, - forma_de_pago: None, - tipo_comprobante: None, - tipo_operacion: None, - anticipos: vec![], - descuentos: vec![], - detalles: vec![], - total_impuestos: None, - total_importe: None, - - guias: vec![], - documentos_relacionados: vec![], - observaciones: None, - orden_de_compra: None, - }; - - let mut credit_note = CreditNote { - leyendas: HashMap::new(), - serie_numero: "FC01-1", - icb_tasa: None, - igv_tasa: None, - ivap_tasa: None, - moneda: None, - fecha_emision: None, - firmante: None, - proveedor: Proveedor { - ruc: "123456789012", - razon_social: "OpenUBL S.A.C.", - nombre_comercial: None, - direccion: None, - contacto: None, - }, - cliente: Cliente { - tipo_documento_identidad: Catalog6::DNI.code(), - numero_documento_identidad: "1234568", - nombre: "Carlos Feria", - direccion: None, - contacto: None, - }, - - tipo_nota: None, - comprobante_afectado_serie_numero: "F001-1", - comprobante_afectado_tipo: None, - sustento_descripcion: "mis razones", - - detalles: vec![], - - total_impuestos: None, - total_importe: None, - - guias: vec![], - documentos_relacionados: vec![], - - orden_de_compra: None, - }; - - invoice.enrich(&defaults); - credit_note.enrich(&defaults); - - println!("ICB {}", invoice.icb_tasa.unwrap()); - println!("IGV {}", invoice.igv_tasa.unwrap()); - println!("IVAP {}", invoice.ivap_tasa.unwrap()); - println!("Moneda {}", invoice.moneda.unwrap()); - println!("Fecha {}", invoice.fecha_emision.unwrap()); - println!("Proveedor {:?}", invoice.proveedor); - // println!("Firmante {:?}", invoice.firmante.unwrap()); - - let a = &invoice; - let xml = render_invoice(a).unwrap(); - println!("xml {}", xml); -} diff --git a/src/prelude.rs b/src/prelude.rs index af3fa667..07fc39ee 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -1,7 +1,8 @@ pub use crate::catalogs::*; pub use crate::enricher::enrich::{Defaults, EnrichTrait}; +pub use crate::models::*; pub use crate::models::common::*; pub use crate::models::general::*; pub use crate::models::invoice::*; -pub use crate::models::*; pub use crate::renderer::render_invoice; + diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index 6e6de395..d4efb383 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -3,11 +3,12 @@ use std::str::FromStr; use rust_decimal::Decimal; use rust_decimal_macros::dec; +use tera::{Context, Error, from_value, Function, Tera, to_value, Value}; use tera::helpers::tests::{number_args_allowed, value_defined}; -use tera::{from_value, to_value, Context, Error, Function, Tera, Value}; +use crate::catalogs::{Catalog7, FromCode}; use crate::models::invoice::Invoice; -use crate::prelude::{catalog7_value_of_code, Catalog}; +use crate::prelude::Catalog; fn catalog7_taxcategory() -> impl Function { Box::new( @@ -17,8 +18,8 @@ fn catalog7_taxcategory() -> impl Function { let igv_tipo = from_value::(igv_tipo_value.clone())?; let field = from_value::(field_value.clone())?; - match catalog7_value_of_code(&igv_tipo) { - Some(catalog7) => { + match Catalog7::from_code(&igv_tipo) { + Ok(catalog7) => { let category = catalog7.tax_category(); match field.as_str() { "code" => Ok(to_value(category.code()).unwrap()), @@ -27,7 +28,9 @@ fn catalog7_taxcategory() -> impl Function { _ => Err("Parameter field not supported.".into()), } } - None => Err("Parameter igv_tipo is not a valid value for Catalog7".into()), + Err(_) => { + Err("Parameter igv_tipo is not a valid value for Catalog7".into()) + } } } _ => Err("Parameter igv_tipo or field not defined".into()),