From d5a6a47f99bbe51ff5ff86d636d562ab9781b93f Mon Sep 17 00:00:00 2001
From: "bit4bit@riseup.net" <bit4bit@riseup.net>
Date: Tue, 2 Jun 2020 16:36:19 +0000
Subject: [PATCH] cambios a metodo de consulta de codelist

FossilOrigin-Name: f127cde5990855880e481d75cd3c8fe27de0bcb534ce29dee889a630fa8e9d9b
---
 facho/fe/client/dian.py                 |  4 ++--
 facho/fe/data/dian/codelist/__init__.py | 19 +++++++++++++------
 facho/fe/fe.py                          |  6 +++---
 facho/fe/form.py                        | 11 +++++++----
 tests/test_data.py                      |  6 +++---
 tests/test_fe_form.py                   | 22 +++++++++++-----------
 6 files changed, 39 insertions(+), 29 deletions(-)

diff --git a/facho/fe/client/dian.py b/facho/fe/client/dian.py
index 8b3e4c2..b57b74d 100644
--- a/facho/fe/client/dian.py
+++ b/facho/fe/client/dian.py
@@ -91,13 +91,13 @@ class SendBillAsync(SOAPService):
 @dataclass
 class SendTestSetAsyncResponse:
     ZipKey: str
-    ErrorMessageList: List[str] = []
+    ErrorMessageList: List[str]
     
     @classmethod
     def fromdict(cls, data):
         return cls(
             data['ZipKey'],
-            data['ErrorMessageList']
+            data['ErrorMessageList'] or []
         )
     
 @dataclass
diff --git a/facho/fe/data/dian/codelist/__init__.py b/facho/fe/data/dian/codelist/__init__.py
index e030b78..f3c23bc 100644
--- a/facho/fe/data/dian/codelist/__init__.py
+++ b/facho/fe/data/dian/codelist/__init__.py
@@ -8,14 +8,15 @@ DATA_DIR = os.path.dirname(os.path.abspath(__file__))
 
 class CodeList:
 
-    def __init__(self, filename, primary_column):
+    def __init__(self, filename, primary_column, name_column):
         self.short_name = ''
         self.long_name = ''
         self.version = 1
         self.canonical_uri = ''
         self.canonical_version_uri = ''
         self.location_uri = ''
-        
+
+        self.name_column = name_column
         self.rows = {}
         self._load(filename, primary_column)
 
@@ -49,6 +50,12 @@ class CodeList:
         return self.rows[str(key)]
 
 
+    def by_name(self, name):
+        for k, v in self.rows.items():
+            if v[self.name_column] == name:
+                return v
+        raise KeyError
+    
 # nombres de variables igual a ./Identification/ShortName
 # TODO: garantizar unica carga en python
 
@@ -59,7 +66,7 @@ __all__ = ['TipoOrganizacion',
 def path_for_codelist(name):
     return os.path.join(DATA_DIR, name)
 
-TipoOrganizacion = CodeList(path_for_codelist('TipoOrganizacion-2.1.gc'), 'name')
-TipoResponsabilidad = CodeList(path_for_codelist('TipoResponsabilidad-2.1.gc'), 'name')
-TipoAmbiente = CodeList(path_for_codelist('TipoAmbiente-2.1.gc'), 'name')
-TipoDocumento = CodeList(path_for_codelist('TipoDocumento-2.1.gc'), 'name')
+TipoOrganizacion = CodeList(path_for_codelist('TipoOrganizacion-2.1.gc'), 'code', 'name')
+TipoResponsabilidad = CodeList(path_for_codelist('TipoResponsabilidad-2.1.gc'), 'code', 'name')
+TipoAmbiente = CodeList(path_for_codelist('TipoAmbiente-2.1.gc'), 'code', 'name')
+TipoDocumento = CodeList(path_for_codelist('TipoDocumento-2.1.gc'), 'code', 'name')
diff --git a/facho/fe/fe.py b/facho/fe/fe.py
index 308594d..1c3b62f 100644
--- a/facho/fe/fe.py
+++ b/facho/fe/fe.py
@@ -41,8 +41,8 @@ class FeXML(FachoXML):
 
 
 class DianXMLExtensionCUFE(FachoXMLExtension):
-    AMBIENTE_PRUEBAS = 'Pruebas'
-    AMBIENTE_PRODUCCION = 'Producción'
+    AMBIENTE_PRUEBAS = codelist.TipoAmbiente.by_name('Pruebas')['code']
+    AMBIENTE_PRODUCCION = codelist.TipoAmbiente.by_name('Producción')['code']
     
     def __init__(self, invoice, tipo_ambiente = AMBIENTE_PRUEBAS, clave_tecnica = ''):
         self.tipo_ambiente = tipo_ambiente
@@ -50,7 +50,7 @@ class DianXMLExtensionCUFE(FachoXMLExtension):
         self.invoice = invoice
 
     def _tipo_ambiente(self):
-        return int(codelist.TipoAmbiente[self.tipo_ambiente]['code'])
+        return int(self.tipo_ambiente)
 
     def build(self, fachoxml):
         cufe = self._generate_cufe(self.invoice, fachoxml)
diff --git a/facho/fe/form.py b/facho/fe/form.py
index b777844..00706ab 100644
--- a/facho/fe/form.py
+++ b/facho/fe/form.py
@@ -18,7 +18,7 @@ class Item:
 
     
 @dataclass
-class StandarItem(Item):
+class StandardItem(Item):
     pass
 
 
@@ -174,12 +174,15 @@ class DianResolucion0001Validator:
         try:
             codelist.TipoResponsabilidad[party.responsability_code]
         except KeyError:
-            self.errors.append((model, 'responsability_code', 'not found'))
+            self.errors.append((model,
+                                'responsability_code',
+                                'not found %s' % (party.responsability_code)))
 
         try:
             codelist.TipoOrganizacion[party.organization_code]
         except KeyError:
-            self.errors.append((model, 'organization_code', 'not found'))
+            self.errors.append((model, 'organization_code' ,
+                                'not found %s' % (party.organization_code)))
 
     def validate(self, invoice):
         invoice.accept(self)
@@ -211,7 +214,7 @@ class DIANInvoiceXML(fe.FeXML):
 
         invoice.calculate()
 
-        fexml.set_element('/fe:Invoice/cbc:InvoiceTypeCode', codelist.TipoDocumento['Factura de Venta Nacional']['code'],
+        fexml.set_element('/fe:Invoice/cbc:InvoiceTypeCode', codelist.TipoDocumento.by_name('Factura de Venta Nacional')['code'],
                           listAgencyID='195',
                           listAgencyName='No matching global declaration available for the validation root',
                           listURI='http://www.dian.gov.co')
diff --git a/tests/test_data.py b/tests/test_data.py
index 8991133..6374393 100644
--- a/tests/test_data.py
+++ b/tests/test_data.py
@@ -10,12 +10,12 @@ from facho.fe.data.dian import codelist
 
 def test_tiporesponsabilidad():
     assert codelist.TipoResponsabilidad.short_name == 'TipoResponsabilidad'
-    assert codelist.TipoResponsabilidad['Autorretenedor']['name'] == 'Autorretenedor'
+    assert codelist.TipoResponsabilidad.by_name('Autorretenedor')['name'] == 'Autorretenedor'
 
 def test_tipoorganizacion():
     assert codelist.TipoOrganizacion.short_name == 'TipoOrganizacion'
-    assert codelist.TipoOrganizacion['Persona Natural']['name'] == 'Persona Natural'
+    assert codelist.TipoOrganizacion.by_name('Persona Natural')['name'] == 'Persona Natural'
 
 def test_tipodocumento():
     assert codelist.TipoDocumento.short_name == 'TipoDocumento'
-    assert codelist.TipoDocumento['Factura de Venta Nacional']['code'] == '01'
+    assert codelist.TipoDocumento.by_name('Factura de Venta Nacional')['code'] == '01'
diff --git a/tests/test_fe_form.py b/tests/test_fe_form.py
index 7ea2c1a..e136a04 100644
--- a/tests/test_fe_form.py
+++ b/tests/test_fe_form.py
@@ -23,15 +23,15 @@ def simple_invoice_without_lines():
     inv.set_supplier(form.Party(
         name = 'facho-supplier',
         ident = 123,
-        responsability_code = 'No aplica',
-        organization_code = 'Persona Natural',
+        responsability_code = 'ZZ',
+        organization_code = '1',
         address = form.Address(name='Test Building')
     ))
     inv.set_customer(form.Party(
         name = 'facho-customer',
         ident = 321,
-        responsability_code = 'No aplica',
-        organization_code = 'Persona Natural',
+        responsability_code = 'ZZ',
+        organization_code = '1',
         address = form.Address(name='Test Building')
     ))
     return inv
@@ -45,19 +45,19 @@ def simple_invoice():
     inv.set_supplier(form.Party(
         name = 'facho-supplier',
         ident = 123,
-        responsability_code = 'No aplica',
-        organization_code = 'Persona Natural'
+        responsability_code = 'ZZ',
+        organization_code = '1'
     ))
     inv.set_customer(form.Party(
         name = 'facho-customer',
         ident = 321,
-        responsability_code = 'No aplica',
-        organization_code = 'Persona Natural'
+        responsability_code = 'ZZ',
+        organization_code = '1'
     ))
     inv.add_invoice_line(form.InvoiceLine(
         quantity = 1,
         description = 'producto facho',
-        item = form.StandarItem('test', 9999),
+        item = form.StandardItem('test', 9999),
         price_amount = 100.0,
         tax = form.TaxTotal(
             tax_amount = 0.0,
@@ -159,7 +159,7 @@ def test_invoice_totals(simple_invoice_without_lines):
     simple_invoice.add_invoice_line(form.InvoiceLine(
         quantity = 1,
         description = 'producto',
-        item = form.StandarItem('test', 9999),
+        item = form.StandardItem('test', 9999),
         price_amount = 1_500_000,
         tax = form.TaxTotal(
             subtotals = [
@@ -182,7 +182,7 @@ def test_invoice_cufe(simple_invoice_without_lines):
     simple_invoice.add_invoice_line(form.InvoiceLine(
         quantity = 1,
         description = 'producto',
-        item = form.StandarItem('test', 111),
+        item = form.StandardItem('test', 111),
         price_amount = 1_500_000,
         tax = form.TaxTotal(
             subtotals = [