From ac770e4545d9d16792a37c4f5b89898b2df2c908 Mon Sep 17 00:00:00 2001
From: "monomono@disroot.org" <monomono@disroot.org>
Date: Sat, 5 Sep 2020 23:15:43 +0000
Subject: [PATCH] Ajustando RegimenFiscal

facho/fe/data/dian/codelist/RegimenFiscal-2.1.custom.gc: nueva lista
facho/fe/form.py (Responsability): nueva clase

FossilOrigin-Name: fde15d01925fe3f58ca79e4eaf5bee18d98a459a8ffa929cca2f176734fdd569
---
 .../dian/codelist/RegimenFiscal-2.1.custom.gc | 50 +++++++++++++++++++
 facho/fe/data/dian/codelist/__init__.py       |  6 ++-
 facho/fe/form.py                              | 31 +++++++++---
 3 files changed, 79 insertions(+), 8 deletions(-)
 create mode 100644 facho/fe/data/dian/codelist/RegimenFiscal-2.1.custom.gc

diff --git a/facho/fe/data/dian/codelist/RegimenFiscal-2.1.custom.gc b/facho/fe/data/dian/codelist/RegimenFiscal-2.1.custom.gc
new file mode 100644
index 0000000..d72d94a
--- /dev/null
+++ b/facho/fe/data/dian/codelist/RegimenFiscal-2.1.custom.gc
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- DIAN Genericode listas de valores:: Ultima modificación 18-02-2019 - evb-->
+<gc:CodeList xmlns:gc="http://docs.oasis-open.org/codelist/ns/genericode/1.0/">
+	<Identification>
+		<ShortName>RegimenFiscal</ShortName>
+		<LongName xml:lang="es">Regimen Fiscal</LongName>
+		<Version>1</Version>
+		<CanonicalUri>urn:dian:names:especificacion:ubl:listacodigos:gc:RegimenFiscal</CanonicalUri>
+		<CanonicalVersionUri>urn:dian:names:especificacion:ubl:listacodigos:gc:RegimenFiscal</CanonicalVersionUri>
+		<LocationUri>http://dian.gov.co/ubl/os-ubl-2.0/cl/gc/default/RegimenFiscal.gc</LocationUri>
+		<Agency>
+			<LongName xml:lang="es">DIAN (Dirección de Impuestos y Aduanas Nacionales)</LongName>
+			<Identifier>195</Identifier>
+		</Agency>
+	</Identification>
+	<ColumnSet>
+		<Column Id="code" Use="required">
+			<ShortName>Code</ShortName>
+			<LongName xml:lang="es">Codigo Comun</LongName>
+			<Data Type="normalizedString"/>
+		</Column>
+		<Column Id="name" Use="required">
+			<ShortName>Name</ShortName>
+			<LongName xml:lang="es">Nombre</LongName>
+			<Data Type="string"/>
+		</Column>
+		<Key Id="codeKey">
+			<ShortName>CodeKey</ShortName>
+			<ColumnRef Ref="code"/>
+		</Key>
+	</ColumnSet>
+	<SimpleCodeList>
+		<Row>
+			<Value ColumnRef="code">
+				<SimpleValue>48</SimpleValue>
+			</Value>
+			<Value ColumnRef="name">
+				<SimpleValue>responsable del impuesto sobre las ventas –IVA</SimpleValue>
+			</Value>
+		</Row>
+		<Row>
+			<Value ColumnRef="code">
+				<SimpleValue>49</SimpleValue>
+			</Value>
+			<Value ColumnRef="name">
+				<SimpleValue>No responsable de IVA</SimpleValue>
+			</Value>
+		</Row>
+	</SimpleCodeList>
+</gc:CodeList>
diff --git a/facho/fe/data/dian/codelist/__init__.py b/facho/fe/data/dian/codelist/__init__.py
index 4855a10..1d13d22 100644
--- a/facho/fe/data/dian/codelist/__init__.py
+++ b/facho/fe/data/dian/codelist/__init__.py
@@ -49,6 +49,8 @@ class CodeList:
     def __getitem__(self, key):
         return self.rows[str(key)]
 
+    def __contains__(self, key):
+        return key in self.rows
 
     def by_name(self, name):
         for k, v in self.rows.items():
@@ -69,7 +71,8 @@ __all__ = ['TipoOrganizacion',
            'TipoAmbiente',
            'TipoDocumento',
            'CodigoPrecioReferencia',
-           'MediosPago']
+           'MediosPago',
+           'RegimenFiscal']
 
 def path_for_codelist(name):
     return os.path.join(DATA_DIR, name)
@@ -81,3 +84,4 @@ TipoAmbiente = CodeList(path_for_codelist('TipoAmbiente-2.1.gc'), 'code', 'name'
 TipoDocumento = CodeList(path_for_codelist('TipoDocumento-2.1.gc'), 'code', 'name')
 CodigoPrecioReferencia = CodeList(path_for_codelist('CodigoPrecioReferencia-2.1.gc'), 'code', 'name')
 MediosPago = CodeList(path_for_codelist('MediosPago-2.1.gc'), 'code', 'name')
+RegimenFiscal = CodeList(path_for_codelist('RegimenFiscal-2.1.custom.gc'), 'code', 'name')
diff --git a/facho/fe/form.py b/facho/fe/form.py
index d2c312e..9a1d6fc 100644
--- a/facho/fe/form.py
+++ b/facho/fe/form.py
@@ -50,12 +50,27 @@ class PartyIdentification:
 
     def full(self):
         return "%s%s" % [self.number, self.dv]
+
+@dataclass
+class Responsability:
+    codes: list
+
+    def __str__(self):
+        return ';'.join(self.codes)
+
+    def __eq__(self, other):
+        return str(self) == str(other)
+
+    def __iter__(self):
+        return iter(self.codes)
+
         
 @dataclass
 class Party:
     name: str
     ident: str
     responsability_code: str
+    responsability_regime_code: str
     organization_code: str
 
     phone: str = ''
@@ -231,12 +246,11 @@ class DianResolucion0001Validator:
         self.errors = []
 
     def _validate_party(self, model, party):
-        try:
-            codelist.TipoResponsabilidad[party.responsability_code]
-        except KeyError:
-            self.errors.append((model,
-                                'responsability_code',
-                                'not found %s' % (party.responsability_code)))
+        for code in party.responsability_code:
+            if code not in codelist.TipoResponsabilidad:
+                self.errors.append((model,
+                                    'responsability_code',
+                                    'not found %s' % (code)))
 
         try:
             codelist.TipoOrganizacion[party.organization_code]
@@ -309,7 +323,10 @@ class DIANInvoiceXML(fe.FeXML):
                           **supplier_company_id_attrs)
 
         fexml.set_element('/fe:Invoice/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:TaxLevelCode',
-                          invoice.invoice_supplier.responsability_code)
+                          #DIAN 1.7.-2020: FAJ26
+                          invoice.invoice_supplier.responsability_code,
+                          #DIAN 1.7.-2020: FAJ27
+                          listName=invoice.invoice_supplier.responsability_regime_code)
 
         fexml.placeholder_for('/fe:Invoice/cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cac:TaxScheme')
         fexml.set_element('/fe:Invoice/cac:AccountingSupplierParty/cac:Party/cac:PartyLegalEntity/cbc:RegistrationName',