diff --git a/__init__.py b/__init__.py index 163c612..a5cbea0 100644 --- a/__init__.py +++ b/__init__.py @@ -8,6 +8,7 @@ from .types import Type from .book import Book from .reconciliation import Reconciliation from .line import Line +from .splitline import SplitLine def register(): @@ -15,5 +16,6 @@ def register(): Type, Book, Line, + SplitLine, Reconciliation, module='cashbook_investment', type_='model') diff --git a/line.py b/line.py index c5252e4..bb31fac 100644 --- a/line.py +++ b/line.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# This file is part of the cashbook-module from m-ds for Tryton. +# This file is part of the cashbook-module from m-ds.de for Tryton. # The COPYRIGHT file at the top level of this repository contains the # full copyright notices and license terms. @@ -78,6 +78,14 @@ class Line(SecondUomMixin, metaclass=PoolMeta): } return recname + @classmethod + def get_fields_write_update(cls): + """ add 'quantity' to updatefields + """ + result = super(Line, cls).get_fields_write_update() + result.append('quantity') + return result + @classmethod def get_debit_credit(cls, values, line=None): """ compute quantity_debit/quantity_credit from quantity @@ -223,6 +231,35 @@ class Line(SecondUomMixin, metaclass=PoolMeta): linetxt = line.rec_name, )) + @classmethod + def update_values_by_splitlines(cls, lines): + """ add quantity to line + """ + to_write = super(Line, cls).update_values_by_splitlines(lines) + + for line in lines: + cnt1 = sum([1 for x in line.splitlines if x.quantity is not None]) + quantity = sum([x.quantity or Decimal('0.0') for x in line.splitlines]) + if (cnt1 > 0) and (quantity != line.quantity): + to_write.extend([ [line], {'quantity': quantity,} ]) + return to_write + + @classmethod + def add_values_from_splitlines(cls, values): + """ add values for create to line by settings on splitlines + """ + values = super(Line, cls).add_values_from_splitlines(values) + + if ('splitlines' in values.keys()) and ('quantity' not in values.keys()): + for action in values['splitlines']: + quantity = None + if action[0] == 'create': + cnt1 = sum([1 for x in action[1] if x.get('quantity', None) is not None]) + quantity = sum([x.get('quantity', Decimal('0.0')) for x in action[1]]) + if cnt1 > 0: + values['quantity'] = quantity + return values + @classmethod def add_2nd_unit_values(cls, values): """ extend create-values @@ -236,24 +273,4 @@ class Line(SecondUomMixin, metaclass=PoolMeta): values.update(cls.add_2nd_quantity(values, Cashbook(cashbook).quantity_uom)) return values - @classmethod - def write(cls, *args): - """ add or update quanity_debit/credit - """ - actions = iter(args) - to_write = [] - for lines, values in zip(actions, actions): - # update debit / credit - if len(set(values.keys()).intersection(set({'quantity', 'bookingtype'}))) > 0: - for line in lines: - values2 = {} - values2.update(values) - values2.update(cls.get_debit_credit({ - x:values.get(x, getattr(line, x)) for x in ['quantity', 'bookingtype'] - }, line=line)) - to_write.extend([lines, values2]) - else : - to_write.extend([lines, values]) - super(Line, cls).write(*to_write) - # end Line diff --git a/line.xml b/line.xml index 536f01c..104fa08 100644 --- a/line.xml +++ b/line.xml @@ -1,5 +1,5 @@ - diff --git a/locale/de.po b/locale/de.po index c7567ee..dcf188f 100644 --- a/locale/de.po +++ b/locale/de.po @@ -123,6 +123,42 @@ msgid "Rate per unit of investment based on current stock exchange price." msgstr "Kurs pro Einheit der Investition anhand des aktuellen Börsenkurses." +################## +# cashbook.split # +################## +msgctxt "field:cashbook.split,quantity_digits:" +msgid "Digits" +msgstr "Dezimalstellen" + +msgctxt "field:cashbook.split,quantity:" +msgid "Quantity" +msgstr "Anzahl" + +msgctxt "field:cashbook.split,quantity_uom:" +msgid "Symbol" +msgstr "Symbol" + +msgctxt "field:cashbook.split,quantity_2nd_uom:" +msgid "Quantity Second UOM" +msgstr "Anzahl in Fremdeinheit" + +msgctxt "field:cashbook.split,quantity2nd:" +msgid "2nd UOM" +msgstr "Fremdeinheit" + +msgctxt "field:cashbook.split,quantity2nd_digits:" +msgid "2nd UOM Digits" +msgstr "Dezimalstellen Fremdeinheit" + +msgctxt "field:cashbook.split,factor_2nd_uom:" +msgid "Conversion factor" +msgstr "Umrechnungsfaktor" + +msgctxt "help:cashbook.split,factor_2nd_uom:" +msgid "Conversion factor between the units of the participating cash books." +msgstr "Umrechnungsfaktor zwischen den Einheiten der teilnehmenden Kassenbücher." + + ################# # cashbook.line # ################# diff --git a/locale/en.po b/locale/en.po index 5b835d4..8a39673 100644 --- a/locale/en.po +++ b/locale/en.po @@ -114,6 +114,38 @@ msgctxt "help:cashbook.book,current_rate:" msgid "Rate per unit of investment based on current stock exchange price." msgstr "Rate per unit of investment based on current stock exchange price." +msgctxt "field:cashbook.split,quantity_digits:" +msgid "Digits" +msgstr "Digits" + +msgctxt "field:cashbook.split,quantity:" +msgid "Quantity" +msgstr "Quantity" + +msgctxt "field:cashbook.split,quantity_uom:" +msgid "Symbol" +msgstr "Symbol" + +msgctxt "field:cashbook.split,quantity_2nd_uom:" +msgid "Quantity Second UOM" +msgstr "Quantity Second UOM" + +msgctxt "field:cashbook.split,quantity2nd:" +msgid "2nd UOM" +msgstr "2nd UOM" + +msgctxt "field:cashbook.split,quantity2nd_digits:" +msgid "2nd UOM Digits" +msgstr "2nd UOM Digits" + +msgctxt "field:cashbook.split,factor_2nd_uom:" +msgid "Conversion factor" +msgstr "Conversion factor" + +msgctxt "help:cashbook.split,factor_2nd_uom:" +msgid "Conversion factor between the units of the participating cash books." +msgstr "Conversion factor between the units of the participating cash books." + msgctxt "field:cashbook.line,quantity_digits:" msgid "Digits" msgstr "Digits" diff --git a/mixin.py b/mixin.py index a662493..97be83c 100644 --- a/mixin.py +++ b/mixin.py @@ -82,10 +82,10 @@ class SecondUomMixin(object): )) values['quantity_2nd_uom'] = Decimal(UOM.compute_qty( - from_uom, - float(quantity), - booktransf.quantity_uom, - round=False, + from_uom, + float(quantity), + booktransf.quantity_uom, + round=False, )).quantize(Decimal( Decimal(1) / 10 ** booktransf.quantity_digits) ) diff --git a/splitline.py b/splitline.py new file mode 100644 index 0000000..2f775c3 --- /dev/null +++ b/splitline.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +# This file is part of the cashbook-module from m-ds.de for Tryton. +# The COPYRIGHT file at the top level of this repository contains the +# full copyright notices and license terms. + + +from trytond.pool import PoolMeta, Pool +from trytond.model import fields +from trytond.pyson import Eval, Or +from .mixin import SecondUomMixin + + +STATES = { + 'readonly': Or( + Eval('state', '') != 'edit', + Eval('state_cashbook', '') != 'open', + ), + 'required': Eval('feature', '') == 'asset', + 'invisible': Eval('feature', '') != 'asset', + } +DEPENDS=['state', 'state_cashbook', 'feature'] + + +class SplitLine(SecondUomMixin, metaclass=PoolMeta): + __name__ = 'cashbook.split' + + quantity = fields.Numeric(string='Quantity', + digits=(16, Eval('quantity_digits', 4)), + states=STATES, depends=DEPENDS+['quantity_digits']) + quantity_digits = fields.Function(fields.Integer(string='Digits', + readonly=True, states={'invisible': True}), + 'on_change_with_quantity_digits') + quantity_uom = fields.Function(fields.Many2One(string='Symbol', + readonly=True, model_name='product.uom'), + 'on_change_with_quantity_uom') + + @fields.depends('line', '_parent_line.cashbook') + def on_change_with_quantity_uom(self, name=None): + """ get quantity-unit of asset + """ + if self.line: + if self.line.cashbook.quantity_uom: + return self.cashbook.quantity_uom.id + + @fields.depends('line', '_parent_line.cashbook') + def on_change_with_quantity_digits(self, name=None): + """ get digits from cashbook + """ + if self.line: + return self.line.cashbook.quantity_digits + return 4 + + @classmethod + def add_2nd_unit_values(cls, values): + """ extend create-values + """ + Line2 = Pool().get('cashbook.line') + + values = super(SplitLine, cls).add_2nd_unit_values(values) + line = Line2(values.get('line', None)) + + if line: + values.update(cls.add_2nd_quantity(values, line.cashbook.quantity_uom)) + return values + +# end SplitLine diff --git a/splitline.xml b/splitline.xml new file mode 100644 index 0000000..97c97ea --- /dev/null +++ b/splitline.xml @@ -0,0 +1,20 @@ + + + + + + + cashbook.split + + split_list + + + cashbook.split + + split_form + + + + diff --git a/tests/test_book.py b/tests/test_book.py index 15ae56b..d76acdb 100644 --- a/tests/test_book.py +++ b/tests/test_book.py @@ -1185,4 +1185,72 @@ class CbInvTestCase(CashbookTestCase, InvestmentTestCase): }, ]) + @with_transaction() + def test_assetbook_split_in_category(self): + """ splitbooking incoming with asset + """ + pool = Pool() + Book = pool.get('cashbook.book') + BType = pool.get('cashbook.type') + Asset = pool.get('investment.asset') + ProdTempl = pool.get('product.template') + Uom = pool.get('product.uom') + + types = self.prep_type() + BType.write(*[ + [types], + { + 'feature': 'asset', + }]) + category = self.prep_category(cattype='in') + + company = self.prep_company() + party = self.prep_party() + asset = self.prep_asset_item( + company=company, + product = self.prep_asset_product(name='Product 1')) + self.assertEqual(asset.symbol, 'usd/u') + + book, = Book.create([{ + 'start_date': date(2022, 4, 1), + 'name': 'Book 1', + 'btype': types.id, + 'company': company.id, + 'currency': company.currency.id, + 'number_sequ': self.prep_sequence().id, + 'asset': asset.id, + 'quantity_uom': asset.uom.id, + 'quantity_digits': 2, + }]) + + Book.write(*[ + [book], + { + 'lines': [('create', [{ + 'bookingtype': 'spin', + 'splitlines': [('create', [{ + 'amount': Decimal('5.0'), + 'splittype': 'cat', + 'description': 'from category', + 'category': category.id, + 'quantity': Decimal('1.5'), + }, { + 'amount': Decimal('6.0'), + 'splittype': 'cat', + 'description': 'from cashbook', + 'category': category.id, + 'quantity': Decimal('2.5'), + }])], + }])], + }]) + + self.assertEqual(book.rec_name, 'Book 1 | 11.00 usd | Open | 4.00 u') + self.assertEqual(book.balance_all, Decimal('11.0')) + self.assertEqual(len(book.lines), 1) + + self.assertEqual(book.lines[0].amount, Decimal('11.0')) + self.assertEqual(book.lines[0].quantity, Decimal('4.0')) + self.assertEqual(book.lines[0].quantity_uom.symbol, 'u') + self.assertEqual(book.lines[0].rec_name, '01/15/2023|Rev/Sp|11.00 usd|- [-]|4.00 u') + # end CbInvTestCase diff --git a/tryton.cfg b/tryton.cfg index 7e0dd85..937fdf1 100644 --- a/tryton.cfg +++ b/tryton.cfg @@ -8,3 +8,4 @@ xml: book.xml line.xml reconciliation.xml + splitline.xml diff --git a/view/line_list.xml b/view/line_list.xml index d66b4b3..e292813 100644 --- a/view/line_list.xml +++ b/view/line_list.xml @@ -1,5 +1,5 @@ - diff --git a/view/split_form.xml b/view/split_form.xml new file mode 100644 index 0000000..f0e457c --- /dev/null +++ b/view/split_form.xml @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/view/split_list.xml b/view/split_list.xml new file mode 100644 index 0000000..a2a4280 --- /dev/null +++ b/view/split_list.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + +