se adiciona extensions para la dian
FossilOrigin-Name: f5521ddbfb903915de88a26ba5197b67efa1ebfd66337061ee9e3653c59dd217
This commit is contained in:
		| @@ -2,54 +2,14 @@ import facho.model as model | ||||
| import facho.model.fields as fields | ||||
| import facho.fe.form as form | ||||
| from facho import fe | ||||
| from .common import * | ||||
| from . import dian | ||||
|  | ||||
| from datetime import date, datetime | ||||
| from collections import defaultdict | ||||
| from copy import copy | ||||
| import hashlib | ||||
|  | ||||
| class Name(model.Model): | ||||
|     __name__ = 'Name' | ||||
|  | ||||
| class Date(model.Model): | ||||
|     __name__ = 'Date' | ||||
|  | ||||
|     def __default_set__(self, value): | ||||
|         if isinstance(value, str): | ||||
|             return value | ||||
|         if isinstance(value, date): | ||||
|             return value.isoformat() | ||||
|  | ||||
|     def __str__(self): | ||||
|         return str(self._value) | ||||
|  | ||||
| class Time(model.Model): | ||||
|     __name__ = 'Time' | ||||
|  | ||||
|     def __default_set__(self, value): | ||||
|         if isinstance(value, str): | ||||
|             return value | ||||
|         if isinstance(value, date): | ||||
|             return value.strftime('%H:%M:%S-05:00') | ||||
|  | ||||
|     def __str__(self): | ||||
|         return str(self._value) | ||||
|  | ||||
| class InvoicePeriod(model.Model): | ||||
|     __name__ = 'InvoicePeriod' | ||||
|  | ||||
|     start_date = fields.Many2One(Date, name='StartDate', namespace='cbc') | ||||
|  | ||||
|     end_date = fields.Many2One(Date, name='EndDate', namespace='cbc') | ||||
|  | ||||
| class ID(model.Model): | ||||
|     __name__ = 'ID' | ||||
|  | ||||
|     def __default_get__(self, name, value): | ||||
|         return self._value | ||||
|  | ||||
|     def __str__(self): | ||||
|         return str(self._value) | ||||
|  | ||||
| class PartyTaxScheme(model.Model): | ||||
|     __name__ = 'PartyTaxScheme' | ||||
| @@ -139,10 +99,10 @@ class TaxCategory(model.Model): | ||||
| class TaxSubTotal(model.Model): | ||||
|     __name__ = 'TaxSubTotal' | ||||
|  | ||||
|     taxable_amount = fields.Many2One(Amount, name='TaxableAmount', default=0.00) | ||||
|     tax_amount = fields.Many2One(Amount, name='TaxAmount', default=0.00) | ||||
|     tax_percent = fields.Many2One(Percent) | ||||
|     tax_category = fields.Many2One(TaxCategory) | ||||
|     taxable_amount = fields.Many2One(Amount, name='TaxableAmount', namespace='cbc', default=0.00) | ||||
|     tax_amount = fields.Many2One(Amount, name='TaxAmount', namespace='cbc', default=0.00) | ||||
|     tax_percent = fields.Many2One(Percent, namespace='cbc') | ||||
|     tax_category = fields.Many2One(TaxCategory, namespace='cac') | ||||
|  | ||||
|     percent = fields.Virtual(setter='set_category', getter='get_category') | ||||
|     scheme = fields.Virtual(setter='set_category', getter='get_category') | ||||
| @@ -266,6 +226,28 @@ class LegalMonetaryTotal(model.Model): | ||||
|     def update_payable_amount(self, name, value): | ||||
|         self.payable_amount = self.tax_inclusive_amount + self.charge_total_amount | ||||
|  | ||||
|  | ||||
| class DIANExtension(model.Model): | ||||
|     __name__ = 'UBLExtension' | ||||
|  | ||||
|     _content = fields.Many2One(Element, name='ExtensionContent', namespace='ext') | ||||
|  | ||||
|     dian = fields.Many2One(dian.DianExtensions, name='DianExtensions', namespace='sts') | ||||
|  | ||||
|     def __default_get__(self, name, value): | ||||
|         return self.dian | ||||
|  | ||||
| class UBLExtension(model.Model): | ||||
|     __name__ = 'UBLExtension' | ||||
|  | ||||
|     content = fields.Many2One(Element, name='ExtensionContent', namespace='ext', default='') | ||||
|      | ||||
| class UBLExtensions(model.Model): | ||||
|     __name__ = 'UBLExtensions' | ||||
|  | ||||
|     dian = fields.Many2One(DIANExtension, namespace='ext', create=True) | ||||
|     extension = fields.Many2One(UBLExtension, namespace='ext', create=True) | ||||
|  | ||||
| class Invoice(model.Model): | ||||
|     __name__ = 'Invoice' | ||||
|     __namespace__ = { | ||||
| @@ -277,18 +259,25 @@ class Invoice(model.Model): | ||||
|         'xades': 'http://uri.etsi.org/01903/v1.3.2#', | ||||
|         'ds': 'http://www.w3.org/2000/09/xmldsig#' | ||||
|     } | ||||
|  | ||||
|  | ||||
|     _ubl_extensions = fields.Many2One(UBLExtensions, namespace='ext') | ||||
|     dian = fields.Virtual(getter='get_dian_extension') | ||||
|      | ||||
|     profile_id = fields.Many2One(Element, name='ProfileID', namespace='cbc', default='DIAN 2.1') | ||||
|     profile_execute_id = fields.Many2One(Element, name='ProfileExecuteID', namespace='cbc', default='2') | ||||
|      | ||||
|     id = fields.Many2One(ID, namespace='cbc') | ||||
|     issue = fields.Virtual(setter='set_issue') | ||||
|     issue_date = fields.Many2One(Date, name='IssueDate', namespace='cbc') | ||||
|     issue_time = fields.Many2One(Time, name='IssueTime', namespace='cbc') | ||||
|      | ||||
|     period = fields.Many2One(InvoicePeriod, namespace='cac') | ||||
|     period = fields.Many2One(Period, name='InvoicePeriod', namespace='cac') | ||||
|  | ||||
|     supplier = fields.Many2One(AccountingSupplierParty, namespace='cac') | ||||
|     customer = fields.Many2One(AccountingCustomerParty, namespace='cac') | ||||
|     lines = fields.One2Many(InvoiceLine, namespace='cac') | ||||
|     legal_monetary_total = fields.Many2One(LegalMonetaryTotal, namespace='cac') | ||||
|     lines = fields.One2Many(InvoiceLine, namespace='cac') | ||||
|      | ||||
|     taxtotal_01 = fields.Many2One(TaxTotal) | ||||
|     taxtotal_04 = fields.Many2One(TaxTotal) | ||||
| @@ -359,3 +348,6 @@ class Invoice(model.Model): | ||||
|             raise ValueError('expected type datetime') | ||||
|         self.issue_date = value.date() | ||||
|         self.issue_time = value | ||||
|  | ||||
|     def get_dian_extension(self, name, _value): | ||||
|         return self._ubl_extensions.dian | ||||
|   | ||||
							
								
								
									
										55
									
								
								facho/fe/model/common.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								facho/fe/model/common.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| import facho.model as model | ||||
| import facho.model.fields as fields | ||||
|  | ||||
| from datetime import date, datetime | ||||
|  | ||||
| __all__ = ['Element', 'Name', 'Date', 'Time', 'Period', 'ID'] | ||||
|  | ||||
| class Element(model.Model): | ||||
|     """ | ||||
|     Lo usuamos para elementos que solo manejan contenido | ||||
|     """ | ||||
|     __name__ = 'Element' | ||||
|      | ||||
| class Name(model.Model): | ||||
|     __name__ = 'Name' | ||||
|  | ||||
| class Date(model.Model): | ||||
|     __name__ = 'Date' | ||||
|  | ||||
|     def __default_set__(self, value): | ||||
|         if isinstance(value, str): | ||||
|             return value | ||||
|         if isinstance(value, date): | ||||
|             return value.isoformat() | ||||
|  | ||||
|     def __str__(self): | ||||
|         return str(self._value) | ||||
|  | ||||
| class Time(model.Model): | ||||
|     __name__ = 'Time' | ||||
|  | ||||
|     def __default_set__(self, value): | ||||
|         if isinstance(value, str): | ||||
|             return value | ||||
|         if isinstance(value, date): | ||||
|             return value.strftime('%H:%M:%S-05:00') | ||||
|  | ||||
|     def __str__(self): | ||||
|         return str(self._value) | ||||
|  | ||||
| class Period(model.Model): | ||||
|     __name__ = 'Period' | ||||
|  | ||||
|     start_date = fields.Many2One(Date, name='StartDate', namespace='cbc') | ||||
|  | ||||
|     end_date = fields.Many2One(Date, name='EndDate', namespace='cbc') | ||||
|  | ||||
| class ID(model.Model): | ||||
|     __name__ = 'ID' | ||||
|  | ||||
|     def __default_get__(self, name, value): | ||||
|         return self._value | ||||
|  | ||||
|     def __str__(self): | ||||
|         return str(self._value) | ||||
							
								
								
									
										37
									
								
								facho/fe/model/dian.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								facho/fe/model/dian.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| import facho.model as model | ||||
| import facho.model.fields as fields | ||||
| from .common import * | ||||
|  | ||||
| class SoftwareProvider(model.Model): | ||||
|     __name__ = 'SoftwareProvider' | ||||
|  | ||||
|     provider_id = fields.Many2One(Element, name='ProviderID', namespace='sts') | ||||
|     software_id = fields.Many2One(Element, name='SoftwareID', namespace='sts') | ||||
|  | ||||
| class InvoiceSource(model.Model): | ||||
|     __name__ = 'InvoiceSource' | ||||
|  | ||||
|     identification_code = fields.Many2One(Element, name='IdentificationCode', namespace='sts', default='CO') | ||||
|      | ||||
| class AuthorizedInvoices(model.Model): | ||||
|     __name__ = 'AuthorizedInvoices' | ||||
|  | ||||
|     prefix = fields.Many2One(Element, name='Prefix', namespace='sts') | ||||
|     from_range = fields.Many2One(Element, name='From', namespace='sts') | ||||
|     to_range = fields.Many2One(Element, name='To', namespace='sts') | ||||
|      | ||||
| class InvoiceControl(model.Model): | ||||
|     __name__ = 'InvoiceControl' | ||||
|  | ||||
|     authorization = fields.Many2One(Element, name='InvoiceAuthorization', namespace='sts') | ||||
|     period = fields.Many2One(Period, name='AuthorizationPeriod', namespace='sts') | ||||
|     invoices = fields.Many2One(AuthorizedInvoices, namespace='sts') | ||||
|      | ||||
| class DianExtensions(model.Model): | ||||
|     __name__ = 'DianExtensions' | ||||
|  | ||||
|     software_security_code = fields.Many2One(Element, name='SoftwareSecurityCode', namespace='sts') | ||||
|     software_provider = fields.Many2One(SoftwareProvider, namespace='sts') | ||||
|     source = fields.Many2One(InvoiceSource, namespace='sts') | ||||
|     control = fields.Many2One(InvoiceControl, namespace='sts') | ||||
|  | ||||
| @@ -45,7 +45,9 @@ class ModelBase(object, metaclass=ModelMeta): | ||||
|             if isinstance(v, fields.Attribute) or isinstance(v, fields.Many2One) or isinstance(v, fields.Function) or isinstance(v, fields.Amount): | ||||
|                 if hasattr(v, 'default') and v.default is not None: | ||||
|                     setattr(obj, key, v.default) | ||||
|                  | ||||
|                 if hasattr(v, 'create') and v.create == True: | ||||
|                     setattr(obj, key, '') | ||||
|  | ||||
|                 # register callbacks for changes | ||||
|                 (fun, on_change_fields) = on_change_fields_for_function() | ||||
|                 for field in on_change_fields: | ||||
|   | ||||
							
								
								
									
										31
									
								
								facho/model/fields/amount.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								facho/model/fields/amount.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| from .field import Field | ||||
| from collections import defaultdict | ||||
| import facho.fe.form as form | ||||
|  | ||||
| class Amount(Field): | ||||
|     def __init__(self, name=None, default=None, precision=6): | ||||
|         self.field_name = name | ||||
|         self.values = {} | ||||
|         self.default = default | ||||
|         self.precision = precision | ||||
|          | ||||
|     def __get__(self, model, cls): | ||||
|         if model is None: | ||||
|             return self | ||||
|         assert self.name is not None | ||||
|   | ||||
|         self.__init_value(model) | ||||
|         model._set_field(self.name, self) | ||||
|         return self.values[model] | ||||
|  | ||||
|     def __set__(self, model, value): | ||||
|         assert self.name is not None | ||||
|         self.__init_value(model) | ||||
|         model._set_field(self.name, self) | ||||
|         self.values[model] = form.Amount(value, precision=self.precision) | ||||
|  | ||||
|         self._changed_field(model, self.name, value) | ||||
|  | ||||
|     def __init_value(self, model): | ||||
|         if model not in self.values: | ||||
|             self.values[model] = form.Amount(self.default or 0) | ||||
| @@ -2,7 +2,7 @@ from .field import Field | ||||
| from collections import defaultdict | ||||
|  | ||||
| class Many2One(Field): | ||||
|     def __init__(self, model, name=None, setter=None, namespace=None, default=None, virtual=False): | ||||
|     def __init__(self, model, name=None, setter=None, namespace=None, default=None, virtual=False, create=False): | ||||
|         self.model = model | ||||
|         self.setter = setter | ||||
|         self.namespace = namespace | ||||
| @@ -10,7 +10,8 @@ class Many2One(Field): | ||||
|         self.default = default | ||||
|         self.virtual = virtual | ||||
|         self.relations = defaultdict(dict) | ||||
|          | ||||
|         self.create = create | ||||
|  | ||||
|     def __get__(self, inst, cls): | ||||
|         if inst is None: | ||||
|             return self | ||||
|   | ||||
							
								
								
									
										45
									
								
								facho/model/fields/virtual.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								facho/model/fields/virtual.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| from .field import Field | ||||
|  | ||||
| # Un campo virtual | ||||
| # no participa del renderizado | ||||
| # pero puede interactura con este | ||||
| class Virtual(Field): | ||||
|     def __init__(self, | ||||
|                  setter=None, | ||||
|                  getter='bob', | ||||
|                  default=None, | ||||
|                  update_internal=False): | ||||
|         self.default = default | ||||
|         self.setter = setter | ||||
|         self.getter = getter | ||||
|         self.values = {} | ||||
|         self.update_internal = update_internal | ||||
|         self.virtual = True | ||||
|  | ||||
|     def __get__(self, inst, cls): | ||||
|         if inst is None: | ||||
|             return self | ||||
|         assert self.name is not None | ||||
|  | ||||
|         value = self.default | ||||
|         try: | ||||
|             value = self.values[inst] | ||||
|         except KeyError: | ||||
|             pass | ||||
|  | ||||
|         try: | ||||
|             self.values[inst] = getattr(inst, self.getter)(self.name, value) | ||||
|         except AttributeError: | ||||
|             self.values[inst] = value | ||||
|  | ||||
|         return self.values[inst] | ||||
|      | ||||
|     def __set__(self, inst, value): | ||||
|         if self.update_internal: | ||||
|             inst._value = value | ||||
|  | ||||
|         if self.setter is None: | ||||
|             self.values[inst] = value | ||||
|         else: | ||||
|             self.values[inst] = self._call(inst, self.setter, self.name, value) | ||||
|         self._changed_field(inst, self.name, value)         | ||||
		Reference in New Issue
	
	Block a user