line/splitline: optimize value-update on create/write

This commit is contained in:
Frederik Jaeckel 2023-01-15 23:05:43 +01:00
parent 82ae7d7bca
commit 3b289b7944
4 changed files with 97 additions and 34 deletions

68
line.py
View file

@ -836,22 +836,6 @@ class Line(SecondCurrencyMixin, Workflow, ModelSQL, ModelView):
raise ValueError('invalid "bookingtype"') raise ValueError('invalid "bookingtype"')
return result return result
@classmethod
def update_amount_by_splitlines(cls, lines):
""" update amounts from split-lines
"""
Line2 = Pool().get('cashbook.line')
to_write = []
for line in lines:
to_write.extend([
[line],
{
'amount': sum([x.amount for x in line.splitlines]),
}])
if len(to_write) > 0:
Line2.write(*to_write)
@classmethod @classmethod
def validate(cls, lines): def validate(cls, lines):
""" deny date before 'start_date' of cashbook """ deny date before 'start_date' of cashbook
@ -945,16 +929,25 @@ class Line(SecondCurrencyMixin, Workflow, ModelSQL, ModelView):
)) ))
@classmethod @classmethod
def copy(cls, lines, default=None): def update_values_by_splitlines(cls, lines):
""" reset values """ update amounts from split-lines
""" """
if default is None: to_write = []
default = {} for line in lines:
else: amount = sum([x.amount for x in line.splitlines])
default = default.copy() if amount != line.amount:
default.setdefault('number', None) to_write.extend([ [line], {'amount': amount,} ])
default.setdefault('state', cls.default_state()) return to_write
return super(Line, cls).copy(moves, default=default)
@classmethod
def add_values_from_splitlines(cls, values):
""" add values for create to line by settings on splitlines
"""
if ('splitlines' in values.keys()) and ('amount' not in values.keys()):
for action in values['splitlines']:
if action[0] == 'create':
values['amount'] = sum([x.get('amount', None) for x in action[1]])
return values
@classmethod @classmethod
def add_2nd_unit_values(cls, values): def add_2nd_unit_values(cls, values):
@ -966,12 +959,31 @@ class Line(SecondCurrencyMixin, Workflow, ModelSQL, ModelView):
values.update(cls.add_2nd_currency(values, Cashbook(cashbook).currency)) values.update(cls.add_2nd_currency(values, Cashbook(cashbook).currency))
return values return values
@classmethod
def get_fields_write_update(cls):
""" get fields to update on write
"""
return ['amount', 'bookingtype']
@classmethod
def copy(cls, lines, default=None):
""" reset values
"""
if default is None:
default = {}
else:
default = default.copy()
default.setdefault('number', None)
default.setdefault('state', cls.default_state())
return super(Line, cls).copy(moves, default=default)
@classmethod @classmethod
def create(cls, vlist): def create(cls, vlist):
""" add debit/credit """ add debit/credit
""" """
vlist = [x.copy() for x in vlist] vlist = [x.copy() for x in vlist]
for values in vlist: for values in vlist:
values.update(cls.add_values_from_splitlines(values))
values.update(cls.get_debit_credit(values)) values.update(cls.get_debit_credit(values))
values.update(cls.clear_by_bookingtype(values)) values.update(cls.clear_by_bookingtype(values))
values.update(cls.add_2nd_unit_values(values)) values.update(cls.add_2nd_unit_values(values))
@ -989,7 +1001,6 @@ class Line(SecondCurrencyMixin, Workflow, ModelSQL, ModelView):
'descr': values.get('description', '-'), 'descr': values.get('description', '-'),
}, },
)) ))
return super(Line, cls).create(vlist) return super(Line, cls).create(vlist)
@classmethod @classmethod
@ -1021,13 +1032,14 @@ class Line(SecondCurrencyMixin, Workflow, ModelSQL, ModelView):
)) ))
# update debit / credit # update debit / credit
if len(set(values.keys()).intersection(set({'amount', 'bookingtype'}))) > 0: fields_update = cls.get_fields_write_update()
if len(set(values.keys()).intersection(set(fields_update))) > 0:
for line in lines: for line in lines:
values2 = {} values2 = {}
values2.update(values) values2.update(values)
values2.update(cls.clear_by_bookingtype(values, line)) values2.update(cls.clear_by_bookingtype(values, line))
values2.update(cls.get_debit_credit({ values2.update(cls.get_debit_credit({
x:values.get(x, getattr(line, x)) for x in ['amount', 'bookingtype'] x:values.get(x, getattr(line, x)) for x in fields_update
}, line=line)) }, line=line))
to_write.extend([lines, values2]) to_write.extend([lines, values2])
else : else :

View file

@ -59,14 +59,12 @@ class SecondCurrencyMixin:
Cashbook = pool.get('cashbook.book') Cashbook = pool.get('cashbook.book')
IrDate = pool.get('ir.date') IrDate = pool.get('ir.date')
#cashbook = values.get('cashbook', None)
booktransf = values.get('booktransf', None) booktransf = values.get('booktransf', None)
amount = values.get('amount', None) amount = values.get('amount', None)
amount_2nd_currency = values.get('amount_2nd_currency', None) amount_2nd_currency = values.get('amount_2nd_currency', None)
if (amount is not None) and (booktransf is not None): if (amount is not None) and (booktransf is not None):
if amount_2nd_currency is None: if amount_2nd_currency is None:
#cashbook = Cashbook(cashbook)
booktransf = Cashbook(booktransf) booktransf = Cashbook(booktransf)
if from_currency.id != booktransf.currency.id: if from_currency.id != booktransf.currency.id:
with Transaction().set_context({ with Transaction().set_context({

View file

@ -239,8 +239,9 @@ class SplitLine(SecondCurrencyMixin, ModelSQL, ModelView):
if not record.line in to_update_line: if not record.line in to_update_line:
to_update_line.append(record.line) to_update_line.append(record.line)
if len(to_update_line) > 0: to_write = Line2.update_values_by_splitlines(to_update_line)
Line2.update_amount_by_splitlines(to_update_line) if len(to_write) > 0:
Line2.write(*to_write)
return records return records
@classmethod @classmethod
@ -261,8 +262,9 @@ class SplitLine(SecondCurrencyMixin, ModelSQL, ModelView):
to_update_line.append(record.line) to_update_line.append(record.line)
super(SplitLine, cls).write(*args) super(SplitLine, cls).write(*args)
if len(to_update_line) > 0: to_write = Line2.update_values_by_splitlines(to_update_line)
Line2.update_amount_by_splitlines(to_update_line) if len(to_write) > 0:
Line2.write(*to_write)
@classmethod @classmethod
def delete(cls, splitlines): def delete(cls, splitlines):

View file

@ -16,6 +16,57 @@ class SplitLineTestCase(ModuleTestCase):
'Test split line module' 'Test split line module'
module = 'cashbook' module = 'cashbook'
@with_transaction()
def test_splitline_in_category(self):
""" add book, check splitbooking - incoming
"""
pool = Pool()
Book = pool.get('cashbook.book')
Line = pool.get('cashbook.line')
types = self.prep_type()
category1 = self.prep_category(cattype='in')
company = self.prep_company()
party = self.prep_party()
book, = Book.create([{
'name': 'Book 1',
'btype': types.id,
'company': company.id,
'currency': company.currency.id,
'number_sequ': self.prep_sequence().id,
'start_date': date(2022, 5, 1),
}])
self.assertEqual(book.rec_name, 'Book 1 | 0.00 usd | Open')
self.assertEqual(len(book.lines), 0)
Book.write(*[
[book],
{
'lines': [('create', [{
'bookingtype': 'spin',
'date': date(2022, 5, 1),
'splitlines': [('create', [{
'amount': Decimal('5.0'),
'splittype': 'cat',
'description': 'from category',
'category': category1.id,
}, {
'amount': Decimal('6.0'),
'splittype': 'cat',
'description': 'from cashbook',
'category': category1.id,
}])],
}])],
}])
self.assertEqual(len(book.lines), 1)
self.assertEqual(book.lines[0].rec_name, '05/01/2022|Rev/Sp|11.00 usd|- [-]')
self.assertEqual(book.lines[0].category, None)
self.assertEqual(len(book.lines[0].splitlines), 2)
self.assertEqual(book.lines[0].splitlines[0].rec_name,
'Rev/Sp|5.00 usd|from category [Cat1]')
self.assertEqual(book.lines[0].splitlines[1].rec_name,
'Rev/Sp|6.00 usd|from cashbook [Cat1]')
@with_transaction() @with_transaction()
def test_splitline_category_and_transfer(self): def test_splitline_category_and_transfer(self):
""" add book, line, two split-lines, """ add book, line, two split-lines,