diff --git a/facho/fe/model/__init__.py b/facho/fe/model/__init__.py index f144d32..74aaf01 100644 --- a/facho/fe/model/__init__.py +++ b/facho/fe/model/__init__.py @@ -2,6 +2,9 @@ import facho.model as model import facho.model.fields as fields from datetime import date, datetime +class Name(model.Model): + __name__ = 'Name' + class Date(model.Model): __name__ = 'Date' @@ -51,23 +54,60 @@ class InvoicedQuantity(model.Model): code = fields.Attribute('unitCode', default='NAR') -class PriceAmount(model.Model): - __name__ = 'PriceAmount' +class Amount(model.Model): + __name__ = 'Amount' currency = fields.Attribute('currencyID', default='COP') class Price(model.Model): __name__ = 'Price' - amount = fields.Many2One(PriceAmount) + amount = fields.Many2One(Amount, name='PriceAmount') def __default_set__(self, value): self.amount = value +class Percent(model.Model): + __name__ = 'Percent' + +class TaxScheme(model.Model): + __name__ = 'TaxScheme' + + id = fields.Many2One(ID) + name= fields.Many2One(Name) + +class TaxCategory(model.Model): + __name__ = 'TaxCategory' + + percent = fields.Many2One(Percent, default='19.0') + tax_scheme = fields.Many2One(TaxScheme) + +class TaxSubTotal(model.Model): + __name__ = 'TaxSubTotal' + + taxable_amount = fields.Many2One(Amount, name='TaxableAmount') + tax_amount = fields.Many2One(Amount, name='TaxAmount') + tax_category = fields.Many2One(TaxCategory) + + percent = fields.Virtual(setter='set_percent') + + def set_percent(self, name, value): + self.tax_category.percent = value + # TODO(bit4bit) hacer variable + self.tax_category.tax_scheme.id = '01' + self.tax_category.tax_scheme.name = 'IVA' + +class TaxTotal(model.Model): + __name__ = 'TaxTotal' + + tax_amount = fields.Many2One(Amount, name='TaxAmount') + subtotals = fields.One2Many(TaxSubTotal) + class InvoiceLine(model.Model): __name__ = 'InvoiceLine' quantity = fields.Many2One(InvoicedQuantity) + taxtotal = fields.Many2One(TaxTotal) price = fields.Many2One(Price) class Invoice(model.Model): diff --git a/facho/model/__init__.py b/facho/model/__init__.py index 9a45981..e70b903 100644 --- a/facho/model/__init__.py +++ b/facho/model/__init__.py @@ -38,10 +38,11 @@ class ModelBase(object, metaclass=ModelMeta): # forzamos registros de campos al modelo # al instanciar for (key, v) in type(obj).__dict__.items(): + if isinstance(v, fields.Attribute) or isinstance(v, fields.Many2One) or isinstance(v, fields.Function): if hasattr(v, 'default') and v.default is not None: setattr(obj, key, v.default) - + # register callbacks for changes (fun, on_change_fields) = on_change_fields_for_function() for field in on_change_fields: @@ -97,7 +98,7 @@ class ModelBase(object, metaclass=ModelMeta): content = "" - for name, value in self._fields.items(): + for value in self._fields.values(): if hasattr(value, 'to_xml'): content += value.to_xml() elif isinstance(value, str): diff --git a/facho/model/fields/one2many.py b/facho/model/fields/one2many.py index 182a1b0..112a92f 100644 --- a/facho/model/fields/one2many.py +++ b/facho/model/fields/one2many.py @@ -19,7 +19,6 @@ class _RelationProxy(): # algo burdo, se usa __dict__ para saltarnos el __getattr__ y generar un fallo por recursion for fun in self.__dict__['_inst']._on_change_fields[self.__dict__['_attribute']]: fun(self.__dict__['_inst'], self.__dict__['_attribute'], value) - return setattr(self._obj, attr, value) class _Relation(): diff --git a/tests/test_model_invoice.py b/tests/test_model_invoice.py index d85c87b..6e6b49e 100644 --- a/tests/test_model_invoice.py +++ b/tests/test_model_invoice.py @@ -21,6 +21,10 @@ def test_simple_invoice(): line = invoice.lines.create() line.quantity = form.Quantity(1, '94') + subtotal = line.taxtotal.subtotals.create() + subtotal.percent = 19.0 + # TODO(bit4bit) el orden de los elementos + # en el xml lo debe determinar la declaracion en los modelos line.price = form.Amount(5_000) - assert '3232000001292019-01-16T10:53:10-05:0010:5310-05:007000853718001994361.05000.0' == invoice.to_xml() + assert '3232000001292019-01-16T10:53:10-05:0010:5310-05:007000853718001994361.019.001IVA5000.0' == invoice.to_xml()