line: quantity_credit/debit + test

book: berechnet 'quantity' aus quantity_credit/debit
This commit is contained in:
Frederik Jaeckel 2022-12-30 23:55:00 +01:00
parent e0895f3e4c
commit e94a869166
6 changed files with 210 additions and 133 deletions

View file

@ -180,10 +180,11 @@ class Book(SymbolMixin, metaclass=PoolMeta):
).select( ).select(
tab_book.id, # 0 tab_book.id, # 0
Coalesce(Sum(Case( Coalesce(Sum(Case(
(tab_line.date <= query_date, tab_line.quantity), (tab_line.date <= query_date,
tab_line.quantity_credit - tab_line.quantity_debit),
else_ = Decimal('0.0'), else_ = Decimal('0.0'),
)), Decimal('0.0')).as_('quantity'), # 1 )), Decimal('0.0')).as_('quantity'), # 1
Sum(tab_line.quantity).as_('quantity_all'), # 2 Sum(tab_line.quantity_credit - tab_line.quantity_debit).as_('quantity_all'), # 2
Coalesce(tab_rate.rate, Decimal('0.0')).as_('rate'), # 3 Coalesce(tab_rate.rate, Decimal('0.0')).as_('rate'), # 3
tab_book.currency, # 4 tab_book.currency, # 4
tab_cur.digits.as_('currency_digits'), # 5 tab_cur.digits.as_('currency_digits'), # 5

69
line.py
View file

@ -9,27 +9,37 @@ from trytond.pool import PoolMeta
from trytond.pyson import Eval, Or, If from trytond.pyson import Eval, Or, If
from trytond.modules.cashbook.line import STATES, DEPENDS from trytond.modules.cashbook.line import STATES, DEPENDS
STATESQ = {
'required': Or(
Eval('feature', '') == 'asset',
Eval('booktransf_feature', '') == 'asset',
),
'invisible': ~Or(
Eval('feature', '') == 'asset',
Eval('booktransf_feature', '') == 'asset',
),
'readonly': Or(
STATES['readonly'],
Eval('bookingtype', '').in_(['spin', 'spout']),
),
}
DEPENDSQ = DEPENDS+['feature', 'booktransf_feature',
'quantity_digits', 'bookingtype']
class Line(metaclass=PoolMeta): class Line(metaclass=PoolMeta):
__name__ = 'cashbook.line' __name__ = 'cashbook.line'
quantity = fields.Numeric(string='Quantity', quantity = fields.Numeric(string='Quantity',
digits=(16, Eval('quantity_digits', 4)), digits=(16, Eval('quantity_digits', 4)),
states={ states=STATESQ, depends=DEPENDSQ)
'required': Or( quantity_credit = fields.Numeric(string='Quantity Credit',
Eval('feature', '') == 'asset', digits=(16, Eval('quantity_digits', 4)),
Eval('booktransf_feature', '') == 'asset', states=STATESQ, depends=DEPENDSQ)
), quantity_debit = fields.Numeric(string='Quantity Debit',
'invisible': ~Or( digits=(16, Eval('quantity_digits', 4)),
Eval('feature', '') == 'asset', states=STATESQ, depends=DEPENDSQ)
Eval('booktransf_feature', '') == 'asset',
),
'readonly': Or(
STATES['readonly'],
Eval('bookingtype', '').in_(['spin', 'spout']),
),
}, depends=DEPENDS+['feature', 'booktransf_feature',
'quantity_digits', 'bookingtype'])
quantity_digits = fields.Function(fields.Integer(string='Digits', quantity_digits = fields.Function(fields.Integer(string='Digits',
readonly=True, states={'invisible': True}), readonly=True, states={'invisible': True}),
'on_change_with_quantity_digits') 'on_change_with_quantity_digits')
@ -46,6 +56,35 @@ class Line(metaclass=PoolMeta):
}, depends=['currency_digits', 'quantity_digits', 'feature']), }, depends=['currency_digits', 'quantity_digits', 'feature']),
'on_change_with_asset_rate') 'on_change_with_asset_rate')
@classmethod
def get_debit_credit(cls, values):
""" compute quantity_debit/quantity_credit from quantity
"""
values2 = super(Line, cls).get_debit_credit(values)
if isinstance(values, dict):
type_ = values.get('bookingtype', None)
quantity = values.get('quantity', None)
else :
type_ = getattr(values, 'bookingtype', None)
quantity = getattr(values, 'quantity', None)
if type_:
if quantity is not None:
if type_ in ['in', 'mvin', 'spin']:
values2.update({
'quantity_debit': Decimal('0.0'),
'quantity_credit': quantity,
})
elif type_ in ['out', 'mvout', 'spout']:
values2.update({
'quantity_debit': quantity,
'quantity_credit': Decimal('0.0'),
})
else :
raise ValueError('invalid "bookingtype"')
return values2
@classmethod @classmethod
def get_counterpart_values(cls, line, values={}): def get_counterpart_values(cls, line, values={}):
""" add quantity to counterpart """ add quantity to counterpart

View file

@ -122,6 +122,14 @@ msgctxt "field:cashbook.line,quantity:"
msgid "Quantity" msgid "Quantity"
msgstr "Anzahl" msgstr "Anzahl"
msgctxt "field:cashbook.line,quantity_credit:"
msgid "Quantity Credit"
msgstr "Anzahlgutschrift"
msgctxt "field:cashbook.line,quantity_debit:"
msgid "Quantity Debit"
msgstr "Anzahllastschrift"
msgctxt "field:cashbook.line,quantity_symbol:" msgctxt "field:cashbook.line,quantity_symbol:"
msgid "Symbol" msgid "Symbol"
msgstr "Symbol" msgstr "Symbol"

View file

@ -110,6 +110,14 @@ msgctxt "field:cashbook.line,quantity:"
msgid "Quantity" msgid "Quantity"
msgstr "Quantity" msgstr "Quantity"
msgctxt "field:cashbook.line,quantity_credit:"
msgid "Quantity Credit"
msgstr "Quantity Credit"
msgctxt "field:cashbook.line,quantity_debit:"
msgid "Quantity Debit"
msgstr "Quantity Debit"
msgctxt "field:cashbook.line,quantity_symbol:" msgctxt "field:cashbook.line,quantity_symbol:"
msgid "Symbol" msgid "Symbol"
msgstr "Symbol" msgstr "Symbol"

View file

@ -55,6 +55,7 @@ class CbInvTestCase(CashbookTestCase, InvestmentTestCase):
""" """
pool = Pool() pool = Pool()
Book = pool.get('cashbook.book') Book = pool.get('cashbook.book')
Line = pool.get('cashbook.line')
BType = pool.get('cashbook.type') BType = pool.get('cashbook.type')
Asset = pool.get('investment.asset') Asset = pool.get('investment.asset')
@ -129,17 +130,24 @@ class CbInvTestCase(CashbookTestCase, InvestmentTestCase):
self.assertEqual(book.lines[0].amount, Decimal('2.5')) self.assertEqual(book.lines[0].amount, Decimal('2.5'))
self.assertEqual(book.lines[0].quantity, Decimal('1.453')) self.assertEqual(book.lines[0].quantity, Decimal('1.453'))
self.assertEqual(book.lines[0].quantity_credit, Decimal('1.453'))
self.assertEqual(book.lines[0].quantity_debit, Decimal('0.0'))
self.assertEqual(book.lines[0].quantity_digits, 3) self.assertEqual(book.lines[0].quantity_digits, 3)
self.assertEqual(book.lines[0].quantity_uom.symbol, 'u') self.assertEqual(book.lines[0].quantity_uom.symbol, 'u')
self.assertEqual(book.lines[1].amount, Decimal('4.0')) self.assertEqual(book.lines[1].amount, Decimal('4.0'))
self.assertEqual(book.lines[1].quantity, Decimal('3.3')) self.assertEqual(book.lines[1].quantity, Decimal('3.3'))
self.assertEqual(book.lines[1].quantity_credit, Decimal('3.3'))
self.assertEqual(book.lines[1].quantity_debit, Decimal('0.0'))
self.assertEqual(book.lines[1].quantity_digits, 3) self.assertEqual(book.lines[1].quantity_digits, 3)
self.assertEqual(book.lines[1].quantity_uom.symbol, 'u') self.assertEqual(book.lines[1].quantity_uom.symbol, 'u')
self.assertEqual(book.symbol, '€/u') self.assertEqual(book.symbol, '€/u')
self.assertEqual(book.asset.rec_name, 'Product 1 | 2.8000 usd/u | 05/02/2022') self.assertEqual(book.asset.rec_name, 'Product 1 | 2.8000 usd/u | 05/02/2022')
# wf --> check
Line.wfcheck(book.lines)
# check quantities at cashbook # check quantities at cashbook
with Transaction().set_context({ with Transaction().set_context({
'qdate': date(2022, 5, 5), 'qdate': date(2022, 5, 5),
@ -466,6 +474,7 @@ class CbInvTestCase(CashbookTestCase, InvestmentTestCase):
@with_transaction() @with_transaction()
def test_assetbook_check_bookingtype_mvout(self): def test_assetbook_check_bookingtype_mvout(self):
""" create cashbook + line, bookingtype 'mvout' """ create cashbook + line, bookingtype 'mvout'
transfer from cash to depot (buy asset, pay from cash)
""" """
pool = Pool() pool = Pool()
Book = pool.get('cashbook.book') Book = pool.get('cashbook.book')
@ -537,7 +546,10 @@ class CbInvTestCase(CashbookTestCase, InvestmentTestCase):
self.assertEqual(len(book.lines), 1) self.assertEqual(len(book.lines), 1)
self.assertEqual(book.lines[0].rec_name, '05/01/2022|to|-1.00 usd|Transfer Out [Asset-Book | 1.00 usd | Open]') self.assertEqual(book.lines[0].rec_name, '05/01/2022|to|-1.00 usd|Transfer Out [Asset-Book | 1.00 usd | Open]')
self.assertEqual(book.lines[0].state, 'check') self.assertEqual(book.lines[0].state, 'check')
self.assertEqual(book.lines[0].bookingtype, 'mvout')
self.assertEqual(book.lines[0].quantity, Decimal('1.5')) self.assertEqual(book.lines[0].quantity, Decimal('1.5'))
self.assertEqual(book.lines[0].quantity_credit, Decimal('0.0'))
self.assertEqual(book.lines[0].quantity_debit, Decimal('1.5'))
self.assertEqual(len(book.lines[0].references), 1) self.assertEqual(len(book.lines[0].references), 1)
self.assertEqual(book.lines[0].reference, None) self.assertEqual(book.lines[0].reference, None)
self.assertEqual(book.lines[0].references[0].id, book2.lines[0].id) self.assertEqual(book.lines[0].references[0].id, book2.lines[0].id)
@ -546,6 +558,10 @@ class CbInvTestCase(CashbookTestCase, InvestmentTestCase):
self.assertEqual(book2.lines[0].rec_name, '05/01/2022|from|1.00 usd|Transfer Out [Book 1 | -1.00 usd | Open]') self.assertEqual(book2.lines[0].rec_name, '05/01/2022|from|1.00 usd|Transfer Out [Book 1 | -1.00 usd | Open]')
self.assertEqual(book2.lines[0].state, 'check') self.assertEqual(book2.lines[0].state, 'check')
self.assertEqual(book2.lines[0].quantity, Decimal('1.5')) self.assertEqual(book2.lines[0].quantity, Decimal('1.5'))
self.assertEqual(book2.lines[0].quantity_credit, Decimal('1.5'))
self.assertEqual(book2.lines[0].quantity_debit, Decimal('0.0'))
self.assertEqual(book2.lines[0].bookingtype, 'mvin')
self.assertEqual(book2.lines[0].asset_rate, Decimal('0.6667'))
self.assertEqual(book2.lines[0].reference.rec_name, '05/01/2022|to|-1.00 usd|Transfer Out [Asset-Book | 1.00 usd | Open]') self.assertEqual(book2.lines[0].reference.rec_name, '05/01/2022|to|-1.00 usd|Transfer Out [Asset-Book | 1.00 usd | Open]')
self.assertEqual(len(book2.lines[0].references), 0) self.assertEqual(len(book2.lines[0].references), 0)

View file

@ -10,6 +10,11 @@ full copyright notices and license terms. -->
<label name="asset_rate"/> <label name="asset_rate"/>
<field name="asset_rate" symbol="cashbook"/> <field name="asset_rate" symbol="cashbook"/>
<label name="quantity_credit" />
<field name="quantity_credit" symbol="quantity_uom"/>
<label name="quantity_debit"/>
<field name="quantity_debit" symbol="quantity_uom"/>
<field name="quantity_digits"/> <field name="quantity_digits"/>
<newline/> <newline/>
</xpath> </xpath>