From 03c552a29cb895f68046f28861c0d2c21d4c337a Mon Sep 17 00:00:00 2001 From: Frederik Jaeckel Date: Sat, 21 Jan 2023 18:46:00 +0100 Subject: [PATCH] line: rec_name with quantity, optimize get_counterpart_values(), splitline: rec_name with quantity, optimize list/form, add tests --- line.py | 29 +- locale/de.po | 4 +- splitline.py | 18 +- tests/test_book.py | 883 +++++++++++++++++++++++++++++++++++++++++++- view/split_form.xml | 7 +- view/split_list.xml | 8 +- 6 files changed, 927 insertions(+), 22 deletions(-) diff --git a/line.py b/line.py index 5752c71..f9a4487 100644 --- a/line.py +++ b/line.py @@ -90,9 +90,11 @@ class Line(SecondUomMixin, metaclass=PoolMeta): """ recname = super(Line, self).get_rec_name(name) if self.cashbook.feature == 'asset': + credit = self.quantity_credit if self.quantity_credit is not None else Decimal('0.0') + debit = self.quantity_debit if self.quantity_debit is not None else Decimal('0.0') recname += '|%(quantity)s %(uom_symbol)s' % { - 'quantity': Report.format_number(self.quantity or 0.0, None, - digits=self.quantity_digits), + 'quantity': Report.format_number(credit - debit, + lang=None, digits=self.quantity_digits), 'uom_symbol': self.quantity_uom.symbol, } return recname @@ -109,13 +111,17 @@ class Line(SecondUomMixin, metaclass=PoolMeta): def get_debit_credit(cls, values, line=None): """ compute quantity_debit/quantity_credit from quantity """ - Cashbook = Pool().get('cashbook.book') + pool = Pool() + Cashbook = pool.get('cashbook.book') + Line2 = pool.get('cashbook.line') result = super(Line, cls).get_debit_credit(values, line) if line: cashbook = line.cashbook else: id_cashbook = values.get('cashbook', None) + if id_cashbook is None: + id_cashbook = Line2.default_cashbook() cashbook = None if id_cashbook: cashbook = Cashbook.browse([id_cashbook])[0] @@ -158,9 +164,22 @@ class Line(SecondUomMixin, metaclass=PoolMeta): if getattr(splitline, 'quantity', None) is not None: # we add values to the counterpart of a splitbooking-line + asset_books = sum([ + 1 if splitline.feature == 'asset' else 0, + 1 if getattr(splitline.booktransf, 'feature', '-') == 'asset' else 0, + ]) + diff_uom = False + if asset_books == 2: + diff_uom = (splitline.quantity_uom != splitline.booktransf.quantity_uom) and \ + (splitline.quantity_uom is not None) and \ + (splitline.booktransf.quantity_uom is not None) + result.update({ - 'quantity': splitline.quantity, - 'quantity_2nd_uom': None, + 'quantity': splitline.quantity_2nd_uom \ + if (asset_books == 2) and (diff_uom == True) \ + else splitline.quantity, + 'quantity_2nd_uom': splitline.quantity \ + if (asset_books == 2) and (diff_uom == True) else None, }) elif booktransf_uom is None: # counterpart-cashbook has no uom -> no quantity diff --git a/locale/de.po b/locale/de.po index ab2b952..9017a1d 100644 --- a/locale/de.po +++ b/locale/de.po @@ -172,11 +172,11 @@ msgstr "Anzahl" msgctxt "field:cashbook.line,quantity_credit:" msgid "Quantity Credit" -msgstr "Anzahl Haben" +msgstr "Einnahme Anzahl" msgctxt "field:cashbook.line,quantity_debit:" msgid "Quantity Debit" -msgstr "Anzahl Soll" +msgstr "Ausgabe Anzahl" msgctxt "field:cashbook.line,quantity_symbol:" msgid "Symbol" diff --git a/splitline.py b/splitline.py index 3ac08c5..efeca8b 100644 --- a/splitline.py +++ b/splitline.py @@ -7,6 +7,7 @@ from trytond.pool import PoolMeta, Pool from trytond.model import fields from trytond.pyson import Eval, Or, And +from trytond.report import Report from trytond.modules.cashbook.line import STATES from .mixin import SecondUomMixin from .line import STATESQ1, DEPENDSQ1 @@ -34,13 +35,28 @@ class SplitLine(SecondUomMixin, metaclass=PoolMeta): readonly=True, model_name='product.uom'), 'on_change_with_quantity_uom') - @fields.depends('line', '_parent_line.cashbook') + def get_rec_name(self, name): + """ add quantities - if its a asset-cashbook + """ + recname = super(SplitLine, self).get_rec_name(name) + if self.line.cashbook.feature == 'asset': + recname += '|%(quantity)s %(uom_symbol)s' % { + 'quantity': Report.format_number(self.quantity or 0.0, None, + digits=self.quantity_digits), + 'uom_symbol': self.quantity_uom.symbol, + } + return recname + + @fields.depends('line', '_parent_line.cashbook', 'booktransf', '_parent_booktransf.quantity_uom') 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 + if self.booktransf: + if self.booktransf.quantity_uom: + return self.booktransf.quantity_uom.id @fields.depends('line', '_parent_line.cashbook') def on_change_with_quantity_digits(self, name=None): diff --git a/tests/test_book.py b/tests/test_book.py index 9a93626..463b2d0 100644 --- a/tests/test_book.py +++ b/tests/test_book.py @@ -779,7 +779,7 @@ class CbInvTestCase(CashbookTestCase, InvestmentTestCase): self.assertEqual(book2.rec_name, 'Asset-Book | -1.00 usd | Open | -1.5000 u') self.assertEqual(len(book2.lines), 1) self.assertEqual(book2.lines[0].rec_name, - '05/01/2022|to|-1.00 usd|Transfer In [Book 1 | 1.00 usd | Open]|1.5000 u') + '05/01/2022|to|-1.00 usd|Transfer In [Book 1 | 1.00 usd | Open]|-1.5000 u') self.assertEqual(book2.lines[0].state, 'check') self.assertEqual(book2.lines[0].bookingtype, 'mvout') self.assertEqual(book2.lines[0].feature, 'asset') @@ -904,7 +904,7 @@ class CbInvTestCase(CashbookTestCase, InvestmentTestCase): self.assertEqual(book2.rec_name, 'Asset-Book 1 | -1.00 usd | Open | -1.5000 u') self.assertEqual(len(book2.lines), 1) self.assertEqual(book2.lines[0].rec_name, - '05/01/2022|to|-1.00 usd|Transfer In [Asset-Book 2 | 1.00 usd | Open | 1.5000 u]|1.5000 u') + '05/01/2022|to|-1.00 usd|Transfer In [Asset-Book 2 | 1.00 usd | Open | 1.5000 u]|-1.5000 u') self.assertEqual(book2.lines[0].state, 'check') self.assertEqual(book2.lines[0].bookingtype, 'mvout') self.assertEqual(book2.lines[0].feature, 'asset') @@ -1068,7 +1068,7 @@ class CbInvTestCase(CashbookTestCase, InvestmentTestCase): self.assertEqual(book2.rec_name, 'Asset-Book 1 | -1.00 usd | Open | -42.5243 g') self.assertEqual(len(book2.lines), 1) self.assertEqual(book2.lines[0].rec_name, - '05/01/2022|to|-1.00 usd|Transfer In [Asset-Book 2 | 1.00 usd | Open | 1.5000 oz]|42.5243 g') + '05/01/2022|to|-1.00 usd|Transfer In [Asset-Book 2 | 1.00 usd | Open | 1.5000 oz]|-42.5243 g') self.assertEqual(book2.lines[0].state, 'check') self.assertEqual(book2.lines[0].bookingtype, 'mvout') self.assertEqual(book2.lines[0].feature, 'asset') @@ -1392,18 +1392,887 @@ class CbInvTestCase(CashbookTestCase, InvestmentTestCase): 'Book 2 | -6.00 usd | Open | -2.50 u') self.assertEqual(len(books[0].lines[0].references), 1) self.assertEqual(books[0].lines[0].references[0].rec_name, - '05/01/2022|to|-6.00 usd|from cashbook [Book 1 | 11.00 usd | Open | 4.00 u]|2.50 u') + '05/01/2022|to|-6.00 usd|from cashbook [Book 1 | 11.00 usd | Open | 4.00 u]|-2.50 u') self.assertEqual(books[0].lines[0].reference, None) self.assertEqual(books[1].rec_name, 'Book 2 | -6.00 usd | Open | -2.50 u') self.assertEqual(books[1].balance_all, Decimal('-6.0')) self.assertEqual(len(books[1].lines), 1) self.assertEqual(books[1].lines[0].rec_name, - '05/01/2022|to|-6.00 usd|from cashbook [Book 1 | 11.00 usd | Open | 4.00 u]|2.50 u') + '05/01/2022|to|-6.00 usd|from cashbook [Book 1 | 11.00 usd | Open | 4.00 u]|-2.50 u') + + @with_transaction() + def test_assetbook_split_in_catergory_asset_diff_unit(self): + """ splitbooking incoming to asset-cahbook, + from category and asset-cashbook with different + unit + """ + pool = Pool() + Book = pool.get('cashbook.book') + Line = pool.get('cashbook.line') + 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')) + + # set product to ounce + ounce, = Uom.search([('symbol', '=', 'oz')]) + gram, = Uom.search([('symbol', '=', 'g')]) + + ProdTempl.write(*[ + [asset.product.template], + { + 'default_uom': ounce.id, + 'name': 'Aurum', + }]) + + Asset.write(*[ + [asset], + { + 'uom': ounce.id, + 'rates': [('create', [{ + 'date': date(2022, 5, 1), + 'rate': Decimal('1750.0'), + }, ])], + }]) + self.assertEqual(asset.rec_name, 'Aurum | 1,750.0000 usd/oz | 05/01/2022') + + (usd, euro) = self.prep_2nd_currency(company) + self.assertEqual(company.currency.rec_name, 'Euro') + self.assertEqual(asset.symbol, 'usd/oz') + + books = Book.create([{ + 'start_date': date(2022, 4, 1), + 'name': 'Book ounce|usd', + 'btype': types.id, + 'company': company.id, + 'currency': usd.id, + 'number_sequ': self.prep_sequence().id, + 'asset': asset.id, + 'quantity_uom': ounce.id, + 'quantity_digits': 3, + }, { + 'start_date': date(2022, 4, 1), + 'name': 'Book gram|euro', + 'btype': types.id, + 'company': company.id, + 'currency': euro.id, + 'number_sequ': self.prep_sequence().id, + 'asset': asset.id, + 'quantity_uom': gram.id, + 'quantity_digits': 3, + }]) + self.assertEqual(books[0].rec_name, 'Book ounce|usd | 0.00 usd | Open | 0.000 oz') + self.assertEqual(books[0].balance_all, Decimal('0.0')) + self.assertEqual(len(books[0].lines), 0) + self.assertEqual(books[1].rec_name, 'Book gram|euro | 0.00 € | Open | 0.000 g') + self.assertEqual(books[1].balance_all, Decimal('0.0')) + self.assertEqual(len(books[1].lines), 0) + + Book.write(*[ + [books[0]], + { + 'lines': [('create', [{ + 'bookingtype': 'spin', + 'date': date(2022, 5, 1), + 'splitlines': [('create', [{ + 'amount': Decimal('5.0'), + 'splittype': 'cat', + 'description': 'from category', + 'category': category.id, + 'quantity': Decimal('1.5'), + }, { + 'amount': Decimal('6.0'), + 'splittype': 'tr', + 'description': 'from cashbook', + 'booktransf': books[1].id, + 'quantity': Decimal('2.5'), + }])], + }])], + }]) + + self.assertEqual(books[0].rec_name, 'Book ounce|usd | 11.00 usd | Open | 4.000 oz') + self.assertEqual(books[0].balance_all, Decimal('11.0')) + self.assertEqual(len(books[0].lines), 1) + self.assertEqual(books[0].lines[0].rec_name, + '05/01/2022|Rev/Sp|11.00 usd|- [-]|4.000 oz') + self.assertEqual(len(books[0].lines[0].splitlines), 2) + self.assertEqual(books[0].lines[0].splitlines[0].rec_name, + 'Rev/Sp|5.00 usd|from category [Cat1]|1.500 oz') + self.assertEqual(books[0].lines[0].splitlines[1].rec_name, + 'Rev/Sp|6.00 usd|from cashbook [Book gram|euro | 0.00 € | Open | 0.000 g]|2.500 oz') + self.assertEqual(books[0].lines[0].splitlines[1].quantity, Decimal('2.5')) + self.assertEqual(books[0].lines[0].splitlines[1].quantity_2nd_uom, Decimal('70.874')) + + self.assertEqual(books[1].rec_name, 'Book gram|euro | 0.00 € | Open | 0.000 g') + self.assertEqual(books[1].balance_all, Decimal('0.0')) + self.assertEqual(len(books[1].lines), 0) + + Line.wfcheck([books[0].lines[0]]) + + self.assertEqual(books[0].rec_name, 'Book ounce|usd | 11.00 usd | Open | 4.000 oz') + self.assertEqual(books[0].balance_all, Decimal('11.0')) + self.assertEqual(len(books[0].lines), 1) + self.assertEqual(books[0].lines[0].rec_name, + '05/01/2022|Rev/Sp|11.00 usd|- [-]|4.000 oz') + self.assertEqual(len(books[0].lines[0].splitlines), 2) + self.assertEqual(books[0].lines[0].splitlines[0].rec_name, + 'Rev/Sp|5.00 usd|from category [Cat1]|1.500 oz') + self.assertEqual(books[0].lines[0].splitlines[1].rec_name, + 'Rev/Sp|6.00 usd|from cashbook [Book gram|euro | -5.71 € | Open | -70.874 g]|2.500 oz') + + self.assertEqual(books[1].rec_name, 'Book gram|euro | -5.71 € | Open | -70.874 g') + self.assertEqual(books[1].balance_all, Decimal('-5.71')) + self.assertEqual(len(books[1].lines), 1) + self.assertEqual(books[1].lines[0].rec_name, + '05/01/2022|to|-5.71 €|from cashbook [Book ounce|usd | 11.00 usd | Open | 4.000 oz]|-70.874 g') + + @with_transaction() + def test_assetbook_split_in_catergory_asset_diff_unit_diff_cat(self): + """ splitbooking incoming to asset-cahbook, + from category and asset-cashbook with different + unit and different uom-category + """ + pool = Pool() + Book = pool.get('cashbook.book') + Line = pool.get('cashbook.line') + 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() + asset1 = self.prep_asset_item( + company=company, + product = self.prep_asset_product(name='Product 1')) + asset2 = self.prep_asset_item( + company=company, + product = self.prep_asset_product(name='Product Liter')) + + # set product to ounce + ounce, = Uom.search([('symbol', '=', 'oz')]) + liter, = Uom.search([('symbol', '=', 'l')]) + + ProdTempl.write(*[ + [asset1.product.template], + { + 'default_uom': ounce.id, + 'name': 'Aurum', + }, + [asset2.product.template], + { + 'default_uom': liter.id, + 'name': 'Liquid', + }, + ]) + + Asset.write(*[ + [asset1], + { + 'uom': ounce.id, + 'rates': [('create', [{ + 'date': date(2022, 5, 1), + 'rate': Decimal('1750.0'), + }, ])], + }, + [asset2], + { + 'uom': liter.id, + 'rates': [('create', [{ + 'date': date(2022, 5, 1), + 'rate': Decimal('10.0'), + }, ])], + }, + ]) + self.assertEqual(asset1.rec_name, 'Aurum | 1,750.0000 usd/oz | 05/01/2022') + self.assertEqual(asset2.rec_name, 'Liquid | 10.0000 usd/l | 05/01/2022') + + (usd, euro) = self.prep_2nd_currency(company) + self.assertEqual(company.currency.rec_name, 'Euro') + self.assertEqual(asset1.symbol, 'usd/oz') + self.assertEqual(asset2.symbol, 'usd/l') + + books = Book.create([{ + 'start_date': date(2022, 4, 1), + 'name': 'Book ounce|usd', + 'btype': types.id, + 'company': company.id, + 'currency': usd.id, + 'number_sequ': self.prep_sequence().id, + 'asset': asset1.id, + 'quantity_uom': ounce.id, + 'quantity_digits': 3, + }, { + 'start_date': date(2022, 4, 1), + 'name': 'Book liter|euro', + 'btype': types.id, + 'company': company.id, + 'currency': euro.id, + 'number_sequ': self.prep_sequence().id, + 'asset': asset2.id, + 'quantity_uom': liter.id, + 'quantity_digits': 3, + }]) + self.assertEqual(books[0].rec_name, 'Book ounce|usd | 0.00 usd | Open | 0.000 oz') + self.assertEqual(books[0].balance_all, Decimal('0.0')) + self.assertEqual(len(books[0].lines), 0) + self.assertEqual(books[1].rec_name, 'Book liter|euro | 0.00 € | Open | 0.000 l') + self.assertEqual(books[1].balance_all, Decimal('0.0')) + self.assertEqual(len(books[1].lines), 0) + + self.assertRaisesRegex(UserError, + r"Cannot transfer quantities between cashbooks with different unit-categories \(Weight != Volume\).", + Book.write, + *[ + [books[0]], + { + 'lines': [('create', [{ + 'bookingtype': 'spin', + 'date': date(2022, 5, 1), + 'splitlines': [('create', [{ + 'amount': Decimal('5.0'), + 'splittype': 'cat', + 'description': 'from category', + 'category': category.id, + 'quantity': Decimal('1.5'), + }, { + 'amount': Decimal('6.0'), + 'splittype': 'tr', + 'description': 'from cashbook', + 'booktransf': books[1].id, + 'quantity': Decimal('2.5'), + }])], + }])], + }, + ]) + + @with_transaction() + def test_assetbook_split_out_category(self): + """ splitbooking outgoing 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='out') + + 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': 'spout', + 'date': date(2022, 5, 1), + 'splitlines': [('create', [{ + 'amount': Decimal('5.0'), + 'splittype': 'cat', + 'description': 'to category', + 'category': category.id, + 'quantity': Decimal('1.5'), + }, { + 'amount': Decimal('6.0'), + 'splittype': 'cat', + 'description': 'to category', + '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].splitline_has_quantity, False) + self.assertEqual(book.lines[0].rec_name, '05/01/2022|Exp/Sp|-11.00 usd|- [-]|-4.00 u') + + self.assertEqual(len(book.lines[0].splitlines), 2) + self.assertEqual(book.lines[0].splitlines[0].rec_name, + 'Exp/Sp|5.00 usd|to category [Cat1]|1.50 u') + self.assertEqual(book.lines[0].splitlines[1].rec_name, + 'Exp/Sp|6.00 usd|to category [Cat1]|2.50 u') + + @with_transaction() + def test_assetbook_split_out_category_and_assetbook(self): + """ splitbooking outgoing, + from asset-cashbook to asset-cahbook and to category + """ + pool = Pool() + Book = pool.get('cashbook.book') + Line = pool.get('cashbook.line') + 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='out') + + 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') + + books = 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, + }, { + 'start_date': date(2022, 4, 1), + 'name': 'Book 2', + '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(*[ + [books[0]], + { + 'lines': [('create', [{ + 'bookingtype': 'spout', + 'date': date(2022, 5, 1), + 'splitlines': [('create', [{ + 'amount': Decimal('5.0'), + 'splittype': 'cat', + 'description': 'to category', + 'category': category.id, + 'quantity': Decimal('1.5'), + }, { + 'amount': Decimal('6.0'), + 'splittype': 'tr', + 'description': 'to cashbook', + 'booktransf': books[1].id, + 'quantity': Decimal('2.5'), + }])], + }])], + }]) + + self.assertEqual(books[0].rec_name, 'Book 1 | -11.00 usd | Open | -4.00 u') + self.assertEqual(books[0].balance_all, Decimal('-11.0')) + + self.assertEqual(len(books[0].lines), 1) + self.assertEqual(books[0].lines[0].rec_name, + '05/01/2022|Exp/Sp|-11.00 usd|- [-]|-4.00 u') + self.assertEqual(books[0].lines[0].splitline_has_quantity, True) + + self.assertEqual(len(books[0].lines[0].splitlines), 2) + self.assertEqual(books[0].lines[0].splitlines[0].rec_name, + 'Exp/Sp|5.00 usd|to category [Cat1]|1.50 u') + self.assertEqual(books[0].lines[0].splitlines[1].rec_name, + 'Exp/Sp|6.00 usd|to cashbook [Book 2 | 0.00 usd | Open | 0.00 u]|2.50 u') + + self.assertEqual(len(books[0].lines[0].references), 0) + self.assertEqual(books[0].lines[0].reference, None) + + self.assertEqual(books[1].rec_name, 'Book 2 | 0.00 usd | Open | 0.00 u') + self.assertEqual(books[1].balance_all, Decimal('0.0')) + self.assertEqual(len(books[1].lines), 0) + + Line.wfcheck([books[0].lines[0]]) + + self.assertEqual(books[0].rec_name, 'Book 1 | -11.00 usd | Open | -4.00 u') + self.assertEqual(books[0].balance_all, Decimal('-11.0')) + self.assertEqual(len(books[0].lines), 1) + + self.assertEqual(books[0].lines[0].rec_name, + '05/01/2022|Exp/Sp|-11.00 usd|- [-]|-4.00 u') + self.assertEqual(books[0].lines[0].splitline_has_quantity, True) + + self.assertEqual(len(books[0].lines[0].splitlines), 2) + self.assertEqual(books[0].lines[0].splitlines[0].rec_name, + 'Exp/Sp|5.00 usd|to category [Cat1]|1.50 u') + self.assertEqual(books[0].lines[0].splitlines[1].rec_name, + 'Exp/Sp|6.00 usd|to cashbook [Book 2 | 6.00 usd | Open | 2.50 u]|2.50 u') + self.assertEqual(books[0].lines[0].splitlines[1].amount, Decimal('6.0')) + self.assertEqual(books[0].lines[0].splitlines[1].amount_2nd_currency, None) + self.assertEqual(books[0].lines[0].splitlines[1].quantity, Decimal('2.5')) + self.assertEqual(books[0].lines[0].splitlines[1].quantity2nd, None) + self.assertEqual(books[0].lines[0].splitlines[1].booktransf.rec_name, + 'Book 2 | 6.00 usd | Open | 2.50 u') + self.assertEqual(len(books[0].lines[0].references), 1) + self.assertEqual(books[0].lines[0].references[0].rec_name, + '05/01/2022|from|6.00 usd|to cashbook [Book 1 | -11.00 usd | Open | -4.00 u]|2.50 u') + self.assertEqual(books[0].lines[0].reference, None) + + self.assertEqual(books[1].rec_name, 'Book 2 | 6.00 usd | Open | 2.50 u') + self.assertEqual(books[1].balance_all, Decimal('6.0')) + self.assertEqual(len(books[1].lines), 1) + self.assertEqual(books[1].lines[0].rec_name, + '05/01/2022|from|6.00 usd|to cashbook [Book 1 | -11.00 usd | Open | -4.00 u]|2.50 u') + + @with_transaction() + def test_assetbook_split_out_category_and_assetbook2(self): + """ splitbooking outgoing, + from cashbook to asset-cahbook and to category + """ + pool = Pool() + Book = pool.get('cashbook.book') + Line = pool.get('cashbook.line') + BType = pool.get('cashbook.type') + Asset = pool.get('investment.asset') + ProdTempl = pool.get('product.template') + Uom = pool.get('product.uom') + + types_asset = self.prep_type() + BType.write(*[ + [types_asset], + { + 'feature': 'asset', + 'name': 'Asset', + 'short': 'as', + }]) + types_cash = self.prep_type() + self.assertEqual(types_cash.rec_name, 'CAS - Cash') + self.assertEqual(types_asset.rec_name, 'as - Asset') + category = self.prep_category(cattype='out') + + 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') + + books = Book.create([{ + 'start_date': date(2022, 4, 1), + 'name': 'Book Cash', + 'btype': types_cash.id, + 'company': company.id, + 'currency': company.currency.id, + 'number_sequ': self.prep_sequence().id, + }, { + 'start_date': date(2022, 4, 1), + 'name': 'Book Asset', + 'btype': types_asset.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(*[ + [books[0]], + { + 'lines': [('create', [{ + 'bookingtype': 'spout', + 'date': date(2022, 5, 1), + 'splitlines': [('create', [{ + 'amount': Decimal('5.0'), + 'splittype': 'cat', + 'description': 'to category', + 'category': category.id, + }, { + 'amount': Decimal('6.0'), + 'splittype': 'tr', + 'description': 'to cashbook', + 'booktransf': books[1].id, + 'quantity': Decimal('2.5'), + }])], + }])], + }]) + + self.assertEqual(books[0].rec_name, 'Book Cash | -11.00 usd | Open') + self.assertEqual(books[0].balance_all, Decimal('-11.0')) + + self.assertEqual(len(books[0].lines), 1) + self.assertEqual(books[0].lines[0].rec_name, + '05/01/2022|Exp/Sp|-11.00 usd|- [-]') + self.assertEqual(books[0].lines[0].quantity, Decimal('2.5')) + self.assertEqual(books[0].lines[0].quantity_credit, None) + self.assertEqual(books[0].lines[0].quantity_debit, None) + self.assertEqual(books[0].lines[0].quantity_2nd_uom, None) + self.assertEqual(books[0].lines[0].splitline_has_quantity, True) + + self.assertEqual(len(books[0].lines[0].splitlines), 2) + self.assertEqual(books[0].lines[0].splitlines[0].rec_name, + 'Exp/Sp|5.00 usd|to category [Cat1]') + self.assertEqual(books[0].lines[0].splitlines[0].quantity, None) + self.assertEqual(books[0].lines[0].splitlines[0].quantity_2nd_uom, None) + self.assertEqual(books[0].lines[0].splitlines[1].rec_name, + 'Exp/Sp|6.00 usd|to cashbook [Book Asset | 0.00 usd | Open | 0.00 u]') + self.assertEqual(books[0].lines[0].splitlines[1].quantity, Decimal('2.5')) + self.assertEqual(books[0].lines[0].splitlines[1].quantity_2nd_uom, None) + + self.assertEqual(len(books[0].lines[0].references), 0) + self.assertEqual(books[0].lines[0].reference, None) + + self.assertEqual(books[1].rec_name, 'Book Asset | 0.00 usd | Open | 0.00 u') + self.assertEqual(books[1].balance_all, Decimal('0.0')) + self.assertEqual(len(books[1].lines), 0) + + Line.wfcheck([books[0].lines[0]]) + + self.assertEqual(books[0].rec_name, 'Book Cash | -11.00 usd | Open') + self.assertEqual(books[0].balance_all, Decimal('-11.0')) + self.assertEqual(len(books[0].lines), 1) + + self.assertEqual(books[0].lines[0].rec_name, + '05/01/2022|Exp/Sp|-11.00 usd|- [-]') + self.assertEqual(books[0].lines[0].splitline_has_quantity, True) + self.assertEqual(books[0].lines[0].quantity, Decimal('2.5')) + self.assertEqual(books[0].lines[0].quantity_credit, None) + self.assertEqual(books[0].lines[0].quantity_debit, None) + self.assertEqual(books[0].lines[0].quantity_2nd_uom, None) + + self.assertEqual(len(books[0].lines[0].splitlines), 2) + self.assertEqual(books[0].lines[0].splitlines[0].rec_name, + 'Exp/Sp|5.00 usd|to category [Cat1]') + self.assertEqual(books[0].lines[0].splitlines[1].rec_name, + 'Exp/Sp|6.00 usd|to cashbook [Book Asset | 6.00 usd | Open | 2.50 u]') + self.assertEqual(books[0].lines[0].splitlines[1].amount, Decimal('6.0')) + self.assertEqual(books[0].lines[0].splitlines[1].amount_2nd_currency, None) + self.assertEqual(books[0].lines[0].splitlines[1].quantity, Decimal('2.5')) + self.assertEqual(books[0].lines[0].splitlines[1].quantity2nd, None) + self.assertEqual(books[0].lines[0].splitlines[1].booktransf.rec_name, + 'Book Asset | 6.00 usd | Open | 2.50 u') + self.assertEqual(len(books[0].lines[0].references), 1) + self.assertEqual(books[0].lines[0].references[0].rec_name, + '05/01/2022|from|6.00 usd|to cashbook [Book Cash | -11.00 usd | Open]|2.50 u') + self.assertEqual(books[0].lines[0].reference, None) + + self.assertEqual(books[1].rec_name, 'Book Asset | 6.00 usd | Open | 2.50 u') + self.assertEqual(books[1].balance_all, Decimal('6.0')) + self.assertEqual(len(books[1].lines), 1) + self.assertEqual(books[1].lines[0].rec_name, + '05/01/2022|from|6.00 usd|to cashbook [Book Cash | -11.00 usd | Open]|2.50 u') + + @with_transaction() + def test_assetbook_split_out_catergory_asset_diff_unit(self): + """ splitbooking outgoing to asset-cahbook, + to category and asset-cashbook with different + unit + """ + pool = Pool() + Book = pool.get('cashbook.book') + Line = pool.get('cashbook.line') + 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='out') + + company = self.prep_company() + party = self.prep_party() + asset = self.prep_asset_item( + company=company, + product = self.prep_asset_product(name='Product 1')) + + # set product to ounce + ounce, = Uom.search([('symbol', '=', 'oz')]) + gram, = Uom.search([('symbol', '=', 'g')]) + + ProdTempl.write(*[ + [asset.product.template], + { + 'default_uom': ounce.id, + 'name': 'Aurum', + }]) + + Asset.write(*[ + [asset], + { + 'uom': ounce.id, + 'rates': [('create', [{ + 'date': date(2022, 5, 1), + 'rate': Decimal('1750.0'), + }, ])], + }]) + self.assertEqual(asset.rec_name, 'Aurum | 1,750.0000 usd/oz | 05/01/2022') + + (usd, euro) = self.prep_2nd_currency(company) + self.assertEqual(company.currency.rec_name, 'Euro') + self.assertEqual(asset.symbol, 'usd/oz') + + books = Book.create([{ + 'start_date': date(2022, 4, 1), + 'name': 'Book ounce|usd', + 'btype': types.id, + 'company': company.id, + 'currency': usd.id, + 'number_sequ': self.prep_sequence().id, + 'asset': asset.id, + 'quantity_uom': ounce.id, + 'quantity_digits': 3, + }, { + 'start_date': date(2022, 4, 1), + 'name': 'Book gram|euro', + 'btype': types.id, + 'company': company.id, + 'currency': euro.id, + 'number_sequ': self.prep_sequence().id, + 'asset': asset.id, + 'quantity_uom': gram.id, + 'quantity_digits': 3, + }]) + self.assertEqual(books[0].rec_name, 'Book ounce|usd | 0.00 usd | Open | 0.000 oz') + self.assertEqual(books[0].balance_all, Decimal('0.0')) + self.assertEqual(len(books[0].lines), 0) + self.assertEqual(books[1].rec_name, 'Book gram|euro | 0.00 € | Open | 0.000 g') + self.assertEqual(books[1].balance_all, Decimal('0.0')) + self.assertEqual(len(books[1].lines), 0) + + Book.write(*[ + [books[0]], + { + 'lines': [('create', [{ + 'bookingtype': 'spout', + 'date': date(2022, 5, 1), + 'splitlines': [('create', [{ + 'amount': Decimal('5.0'), + 'splittype': 'cat', + 'description': 'to category', + 'category': category.id, + 'quantity': Decimal('1.5'), + }, { + 'amount': Decimal('6.0'), + 'splittype': 'tr', + 'description': 'to cashbook', + 'booktransf': books[1].id, + 'quantity': Decimal('2.5'), + }])], + }])], + }]) + + self.assertEqual(books[0].rec_name, 'Book ounce|usd | -11.00 usd | Open | -4.000 oz') + self.assertEqual(books[0].balance_all, Decimal('-11.0')) + self.assertEqual(len(books[0].lines), 1) + self.assertEqual(books[0].lines[0].rec_name, + '05/01/2022|Exp/Sp|-11.00 usd|- [-]|-4.000 oz') + self.assertEqual(len(books[0].lines[0].splitlines), 2) + self.assertEqual(books[0].lines[0].splitlines[0].rec_name, + 'Exp/Sp|5.00 usd|to category [Cat1]|1.500 oz') + self.assertEqual(books[0].lines[0].splitlines[1].rec_name, + 'Exp/Sp|6.00 usd|to cashbook [Book gram|euro | 0.00 € | Open | 0.000 g]|2.500 oz') + self.assertEqual(books[0].lines[0].splitlines[1].quantity, Decimal('2.5')) + self.assertEqual(books[0].lines[0].splitlines[1].quantity_2nd_uom, Decimal('70.874')) + + self.assertEqual(books[1].rec_name, 'Book gram|euro | 0.00 € | Open | 0.000 g') + self.assertEqual(books[1].balance_all, Decimal('0.0')) + self.assertEqual(len(books[1].lines), 0) + + Line.wfcheck([books[0].lines[0]]) + + self.assertEqual(books[0].rec_name, 'Book ounce|usd | -11.00 usd | Open | -4.000 oz') + self.assertEqual(books[0].balance_all, Decimal('-11.0')) + self.assertEqual(len(books[0].lines), 1) + self.assertEqual(books[0].lines[0].rec_name, + '05/01/2022|Exp/Sp|-11.00 usd|- [-]|-4.000 oz') + self.assertEqual(len(books[0].lines[0].splitlines), 2) + self.assertEqual(books[0].lines[0].splitlines[0].rec_name, + 'Exp/Sp|5.00 usd|to category [Cat1]|1.500 oz') + self.assertEqual(books[0].lines[0].splitlines[1].rec_name, + 'Exp/Sp|6.00 usd|to cashbook [Book gram|euro | 5.71 € | Open | 70.874 g]|2.500 oz') + + self.assertEqual(books[1].rec_name, 'Book gram|euro | 5.71 € | Open | 70.874 g') + self.assertEqual(books[1].balance_all, Decimal('5.71')) + self.assertEqual(len(books[1].lines), 1) + self.assertEqual(books[1].lines[0].rec_name, + '05/01/2022|from|5.71 €|to cashbook [Book ounce|usd | -11.00 usd | Open | -4.000 oz]|70.874 g') + + @with_transaction() + def test_assetbook_split_out_catergory_asset_diff_unit_diff_cat(self): + """ splitbooking outgoing to asset-cahbook, + to category and asset-cashbook with different + unit and different uom-category + """ + pool = Pool() + Book = pool.get('cashbook.book') + Line = pool.get('cashbook.line') + 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='out') + + company = self.prep_company() + party = self.prep_party() + asset1 = self.prep_asset_item( + company=company, + product = self.prep_asset_product(name='Product 1')) + asset2 = self.prep_asset_item( + company=company, + product = self.prep_asset_product(name='Product Liter')) + + # set product to ounce + ounce, = Uom.search([('symbol', '=', 'oz')]) + liter, = Uom.search([('symbol', '=', 'l')]) + + ProdTempl.write(*[ + [asset1.product.template], + { + 'default_uom': ounce.id, + 'name': 'Aurum', + }, + [asset2.product.template], + { + 'default_uom': liter.id, + 'name': 'Liquid', + }, + ]) + + Asset.write(*[ + [asset1], + { + 'uom': ounce.id, + 'rates': [('create', [{ + 'date': date(2022, 5, 1), + 'rate': Decimal('1750.0'), + }, ])], + }, + [asset2], + { + 'uom': liter.id, + 'rates': [('create', [{ + 'date': date(2022, 5, 1), + 'rate': Decimal('10.0'), + }, ])], + }, + ]) + self.assertEqual(asset1.rec_name, 'Aurum | 1,750.0000 usd/oz | 05/01/2022') + self.assertEqual(asset2.rec_name, 'Liquid | 10.0000 usd/l | 05/01/2022') + + (usd, euro) = self.prep_2nd_currency(company) + self.assertEqual(company.currency.rec_name, 'Euro') + self.assertEqual(asset1.symbol, 'usd/oz') + self.assertEqual(asset2.symbol, 'usd/l') + + books = Book.create([{ + 'start_date': date(2022, 4, 1), + 'name': 'Book ounce|usd', + 'btype': types.id, + 'company': company.id, + 'currency': usd.id, + 'number_sequ': self.prep_sequence().id, + 'asset': asset1.id, + 'quantity_uom': ounce.id, + 'quantity_digits': 3, + }, { + 'start_date': date(2022, 4, 1), + 'name': 'Book liter|euro', + 'btype': types.id, + 'company': company.id, + 'currency': euro.id, + 'number_sequ': self.prep_sequence().id, + 'asset': asset2.id, + 'quantity_uom': liter.id, + 'quantity_digits': 3, + }]) + self.assertEqual(books[0].rec_name, 'Book ounce|usd | 0.00 usd | Open | 0.000 oz') + self.assertEqual(books[0].balance_all, Decimal('0.0')) + self.assertEqual(len(books[0].lines), 0) + self.assertEqual(books[1].rec_name, 'Book liter|euro | 0.00 € | Open | 0.000 l') + self.assertEqual(books[1].balance_all, Decimal('0.0')) + self.assertEqual(len(books[1].lines), 0) + + self.assertRaisesRegex(UserError, + r"Cannot transfer quantities between cashbooks with different unit-categories \(Weight != Volume\).", + Book.write, + *[ + [books[0]], + { + 'lines': [('create', [{ + 'bookingtype': 'spout', + 'date': date(2022, 5, 1), + 'splitlines': [('create', [{ + 'amount': Decimal('5.0'), + 'splittype': 'cat', + 'description': 'from category', + 'category': category.id, + 'quantity': Decimal('1.5'), + }, { + 'amount': Decimal('6.0'), + 'splittype': 'tr', + 'description': 'from cashbook', + 'booktransf': books[1].id, + 'quantity': Decimal('2.5'), + }])], + }])], + }, + ]) # TODO: - # - splitbuchung mit unterschiedlichen einheiten einer kategorie - # - splitbuchung mit unterschiedlichen einheiten verschiedener kategorien # in/out-splitbuchung # end CbInvTestCase diff --git a/view/split_form.xml b/view/split_form.xml index f0e457c..0602d50 100644 --- a/view/split_form.xml +++ b/view/split_form.xml @@ -7,10 +7,13 @@ full copyright notices and license terms. --> diff --git a/view/split_list.xml b/view/split_list.xml index a2a4280..876e52d 100644 --- a/view/split_list.xml +++ b/view/split_list.xml @@ -4,11 +4,9 @@ The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. --> - - - - - + + +