diff --git a/xbuilder/resources/templates/ubl/standard/include/document-line.xml b/xbuilder/resources/templates/ubl/standard/include/document-line.xml
index 15819271..7656d435 100644
--- a/xbuilder/resources/templates/ubl/standard/include/document-line.xml
+++ b/xbuilder/resources/templates/ubl/standard/include/document-line.xml
@@ -73,6 +73,28 @@
{{item.codigo_sunat}}
{%- endif %}
+ {%- for atributo in item.atributos %}
+
+ {{atributo.nombre}}
+ {{atributo.codigo}}
+ {%- if atributo.valor %}
+ {{atributo.valor}}
+ {%- endif %}
+ {%- if atributo.fecha_inicio or atributo.fecha_fin or atributo.duracion %}
+
+ {%- if atributo.fecha_inicio %}
+ {{atributo.fecha_inicio}}
+ {%- endif %}
+ {%- if atributo.fecha_fin %}
+ {{atributo.fecha_fin}}
+ {%- endif %}
+ {%- if atributo.duracion %}
+ {{atributo.duracion}}
+ {%- endif %}
+
+ {%- endif %}
+
+ {%- endfor %}
{{item.precio | round_decimal}}
diff --git a/xbuilder/src/models/common.rs b/xbuilder/src/models/common.rs
index b01bc773..77acf01d 100644
--- a/xbuilder/src/models/common.rs
+++ b/xbuilder/src/models/common.rs
@@ -149,6 +149,17 @@ pub struct CodigoGS1 {
pub tipo: &'static str,
}
+/// Atributo adicional de un detalle
+#[derive(Clone, Debug, Serialize, Default)]
+pub struct Atributo {
+ pub nombre: &'static str,
+ pub codigo: &'static str,
+ pub valor: Option<&'static str>,
+ pub fecha_inicio: Option,
+ pub fecha_fin: Option,
+ pub duracion: Option,
+}
+
/// Detalle de las ventas en Boleta/Factura/Nota Credito/Nota Debito
#[derive(Clone, Debug, Serialize, Default)]
pub struct Detalle {
@@ -190,6 +201,8 @@ pub struct Detalle {
pub isc_base_imponible: Option,
pub total_impuestos: Option,
+
+ pub atributos: Vec,
}
/// Total Importe Invoice
diff --git a/xbuilder/tests/credit_note_atributos.rs b/xbuilder/tests/credit_note_atributos.rs
new file mode 100644
index 00000000..cd90d9e2
--- /dev/null
+++ b/xbuilder/tests/credit_note_atributos.rs
@@ -0,0 +1,43 @@
+use rust_decimal_macros::dec;
+
+use xbuilder::prelude::*;
+
+use crate::common::{assert_credit_note, credit_note_base};
+
+mod common;
+
+const BASE: &str = "tests/resources/e2e/renderer/creditnote/CreditNoteAtributosTest";
+
+#[serial_test::serial]
+#[tokio::test]
+async fn credit_note_with_atributos() {
+ let mut credit_note = CreditNote {
+ detalles: vec![Detalle {
+ descripcion: "Item1",
+ cantidad: dec!(10),
+ precio: Some(dec!(100)),
+ atributos: vec![
+ Atributo {
+ nombre: "Marca",
+ codigo: "BRA",
+ valor: Some("Samsung"),
+ fecha_inicio: None,
+ fecha_fin: None,
+ duracion: None,
+ },
+ Atributo {
+ nombre: "Color",
+ codigo: "COL",
+ valor: Some("Negro"),
+ fecha_inicio: None,
+ fecha_fin: None,
+ duracion: None,
+ },
+ ],
+ ..Default::default()
+ }],
+ ..credit_note_base()
+ };
+
+ assert_credit_note(&mut credit_note, &format!("{BASE}/atributosSimple.xml")).await;
+}
diff --git a/xbuilder/tests/debit_note_atributos.rs b/xbuilder/tests/debit_note_atributos.rs
new file mode 100644
index 00000000..6dbd880e
--- /dev/null
+++ b/xbuilder/tests/debit_note_atributos.rs
@@ -0,0 +1,43 @@
+use rust_decimal_macros::dec;
+
+use xbuilder::prelude::*;
+
+use crate::common::{assert_debit_note, debit_note_base};
+
+mod common;
+
+const BASE: &str = "tests/resources/e2e/renderer/debitnote/DebitNoteAtributosTest";
+
+#[serial_test::serial]
+#[tokio::test]
+async fn debit_note_with_atributos() {
+ let mut debit_note = DebitNote {
+ detalles: vec![Detalle {
+ descripcion: "Item1",
+ cantidad: dec!(10),
+ precio: Some(dec!(100)),
+ atributos: vec![
+ Atributo {
+ nombre: "Marca",
+ codigo: "BRA",
+ valor: Some("Samsung"),
+ fecha_inicio: None,
+ fecha_fin: None,
+ duracion: None,
+ },
+ Atributo {
+ nombre: "Color",
+ codigo: "COL",
+ valor: Some("Negro"),
+ fecha_inicio: None,
+ fecha_fin: None,
+ duracion: None,
+ },
+ ],
+ ..Default::default()
+ }],
+ ..debit_note_base()
+ };
+
+ assert_debit_note(&mut debit_note, &format!("{BASE}/atributosSimple.xml")).await;
+}
diff --git a/xbuilder/tests/invoice_atributos.rs b/xbuilder/tests/invoice_atributos.rs
new file mode 100644
index 00000000..41cdf502
--- /dev/null
+++ b/xbuilder/tests/invoice_atributos.rs
@@ -0,0 +1,79 @@
+use chrono::NaiveDate;
+use rust_decimal_macros::dec;
+
+use xbuilder::prelude::*;
+
+use crate::common::assert_invoice;
+use crate::common::invoice_base;
+
+mod common;
+
+const BASE: &str = "tests/resources/e2e/renderer/invoice/InvoiceAtributosTest";
+
+#[serial_test::serial]
+#[tokio::test]
+async fn invoice_with_atributos_simple() {
+ let mut invoice = Invoice {
+ detalles: vec![Detalle {
+ descripcion: "Item1",
+ cantidad: dec!(2),
+ precio: Some(dec!(100)),
+ atributos: vec![
+ Atributo {
+ nombre: "Marca",
+ codigo: "BRA",
+ valor: Some("Samsung"),
+ fecha_inicio: None,
+ fecha_fin: None,
+ duracion: None,
+ },
+ Atributo {
+ nombre: "Color",
+ codigo: "COL",
+ valor: Some("Negro"),
+ fecha_inicio: None,
+ fecha_fin: None,
+ duracion: None,
+ },
+ ],
+ ..Default::default()
+ }],
+ ..invoice_base()
+ };
+
+ assert_invoice(&mut invoice, &format!("{BASE}/atributosSimple.xml")).await;
+}
+
+#[serial_test::serial]
+#[tokio::test]
+async fn invoice_with_atributos_con_periodo() {
+ let mut invoice = Invoice {
+ detalles: vec![Detalle {
+ descripcion: "Item1",
+ cantidad: dec!(2),
+ precio: Some(dec!(100)),
+ atributos: vec![
+ Atributo {
+ nombre: "Garantia",
+ codigo: "WAR",
+ valor: Some("12 meses"),
+ fecha_inicio: Some(NaiveDate::from_ymd_opt(2019, 12, 24).unwrap()),
+ fecha_fin: Some(NaiveDate::from_ymd_opt(2020, 12, 24).unwrap()),
+ duracion: Some(365),
+ },
+ Atributo {
+ nombre: "Modelo",
+ codigo: "MOD",
+ valor: Some("Galaxy S10"),
+ fecha_inicio: None,
+ fecha_fin: None,
+ duracion: None,
+ },
+ ],
+ ..Default::default()
+ }],
+ ..invoice_base()
+ };
+
+ assert_invoice(&mut invoice, &format!("{BASE}/atributosConPeriodo.xml")).await;
+}
diff --git a/xbuilder/tests/resources/e2e/renderer/creditnote/CreditNoteAtributosTest/atributosSimple.xml b/xbuilder/tests/resources/e2e/renderer/creditnote/CreditNoteAtributosTest/atributosSimple.xml
new file mode 100644
index 00000000..5b7f1d87
--- /dev/null
+++ b/xbuilder/tests/resources/e2e/renderer/creditnote/CreditNoteAtributosTest/atributosSimple.xml
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
+ 2.1
+ 2.0
+ FC01-1
+ 2019-12-24
+ PEN
+
+ F001-1
+ 01
+
+
+
+
+ F001-1
+ 01
+
+
+
+ 12345678912
+
+
+ 12345678912
+
+
+
+
+
+
+
+ #PROJECT-OPENUBL-SIGN
+
+
+
+
+
+
+ 12345678912
+
+
+
+
+ 0000
+
+
+
+
+
+
+
+ 12121212121
+
+
+
+
+
+
+
+ 180.00
+
+ 1000.00
+ 180.00
+
+ S
+
+ 1000
+ IGV
+ VAT
+
+
+
+
+
+ 1000.00
+ 1180.00
+ 1180.00
+
+
+ 1
+ 10
+ 1000.00
+
+
+ 118.00
+ 01
+
+
+
+ 180.00
+
+ 1000.00
+ 180.00
+
+ S
+ 18.00
+ 10
+
+ 1000
+ IGV
+ VAT
+
+
+
+
+
+
+
+ Marca
+ BRA
+ Samsung
+
+
+ Color
+ COL
+ Negro
+
+
+
+ 100.00
+
+
+
diff --git a/xbuilder/tests/resources/e2e/renderer/debitnote/DebitNoteAtributosTest/atributosSimple.xml b/xbuilder/tests/resources/e2e/renderer/debitnote/DebitNoteAtributosTest/atributosSimple.xml
new file mode 100644
index 00000000..56ea7741
--- /dev/null
+++ b/xbuilder/tests/resources/e2e/renderer/debitnote/DebitNoteAtributosTest/atributosSimple.xml
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
+ 2.1
+ 2.0
+ FD01-1
+ 2019-12-24
+ PEN
+
+ F001-1
+ 01
+
+
+
+
+ F001-1
+ 01
+
+
+
+ 12345678912
+
+
+ 12345678912
+
+
+
+
+
+
+
+ #PROJECT-OPENUBL-SIGN
+
+
+
+
+
+
+ 12345678912
+
+
+
+
+ 0000
+
+
+
+
+
+
+
+ 12121212121
+
+
+
+
+
+
+
+ 180.00
+
+ 1000.00
+ 180.00
+
+ S
+
+ 1000
+ IGV
+ VAT
+
+
+
+
+
+ 1000.00
+ 1180.00
+ 1180.00
+
+
+ 1
+ 10
+ 1000.00
+
+
+ 118.00
+ 01
+
+
+
+ 180.00
+
+ 1000.00
+ 180.00
+
+ S
+ 18.00
+ 10
+
+ 1000
+ IGV
+ VAT
+
+
+
+
+
+
+
+ Marca
+ BRA
+ Samsung
+
+
+ Color
+ COL
+ Negro
+
+
+
+ 100.00
+
+
+
diff --git a/xbuilder/tests/resources/e2e/renderer/invoice/InvoiceAtributosTest/atributosConPeriodo.xml b/xbuilder/tests/resources/e2e/renderer/invoice/InvoiceAtributosTest/atributosConPeriodo.xml
new file mode 100644
index 00000000..4cf5cf0e
--- /dev/null
+++ b/xbuilder/tests/resources/e2e/renderer/invoice/InvoiceAtributosTest/atributosConPeriodo.xml
@@ -0,0 +1,139 @@
+
+
+
+
+
+
+
+ 2.1
+ 2.0
+ F001-1
+ 2019-12-24
+ 01
+ PEN
+
+ 12345678912
+
+
+ 12345678912
+
+
+
+
+
+
+
+ #PROJECT-OPENUBL-SIGN
+
+
+
+
+
+
+ 12345678912
+
+
+
+
+ 0000
+
+
+
+
+
+
+
+ 12121212121
+
+
+
+
+
+
+
+ FormaPago
+ Contado
+
+
+ 36.00
+
+ 200.00
+ 36.00
+
+ S
+
+ 1000
+ IGV
+ VAT
+
+
+
+
+
+ 200.00
+ 236.00
+ 0
+ 0
+ 236.00
+
+
+ 1
+ 2
+ 200.00
+
+
+ 118.00
+ 01
+
+
+
+ 36.00
+
+ 200.00
+ 36.00
+
+ S
+ 18.00
+ 10
+
+ 1000
+ IGV
+ VAT
+
+
+
+
+
+
+
+ Garantia
+ WAR
+ 12 meses
+
+ 2019-12-24
+ 2020-12-24
+ 365
+
+
+
+ Modelo
+ MOD
+ Galaxy S10
+
+
+
+ 100.00
+
+
+
diff --git a/xbuilder/tests/resources/e2e/renderer/invoice/InvoiceAtributosTest/atributosSimple.xml b/xbuilder/tests/resources/e2e/renderer/invoice/InvoiceAtributosTest/atributosSimple.xml
new file mode 100644
index 00000000..4408001d
--- /dev/null
+++ b/xbuilder/tests/resources/e2e/renderer/invoice/InvoiceAtributosTest/atributosSimple.xml
@@ -0,0 +1,134 @@
+
+
+
+
+
+
+
+ 2.1
+ 2.0
+ F001-1
+ 2019-12-24
+ 01
+ PEN
+
+ 12345678912
+
+
+ 12345678912
+
+
+
+
+
+
+
+ #PROJECT-OPENUBL-SIGN
+
+
+
+
+
+
+ 12345678912
+
+
+
+
+ 0000
+
+
+
+
+
+
+
+ 12121212121
+
+
+
+
+
+
+
+ FormaPago
+ Contado
+
+
+ 36.00
+
+ 200.00
+ 36.00
+
+ S
+
+ 1000
+ IGV
+ VAT
+
+
+
+
+
+ 200.00
+ 236.00
+ 0
+ 0
+ 236.00
+
+
+ 1
+ 2
+ 200.00
+
+
+ 118.00
+ 01
+
+
+
+ 36.00
+
+ 200.00
+ 36.00
+
+ S
+ 18.00
+ 10
+
+ 1000
+ IGV
+ VAT
+
+
+
+
+
+
+
+ Marca
+ BRA
+ Samsung
+
+
+ Color
+ COL
+ Negro
+
+
+
+ 100.00
+
+
+