line: spalte 'empfänger', Feld 'reference' + tests

This commit is contained in:
Frederik Jaeckel 2022-08-16 14:16:14 +02:00
parent 30b91cf518
commit 5fdbb0ce89
10 changed files with 510 additions and 42 deletions

119
line.py
View file

@ -17,6 +17,11 @@ from sql.conditionals import Case
from .book import sel_state_book
sel_payee = [
('cashbook.book', 'Cashbook'),
('party.party', 'Party')
]
sel_linetype = [
('edit', 'Edit'),
('check', 'Checked'),
@ -51,13 +56,15 @@ class Line(Workflow, ModelSQL, ModelView):
'on_change_with_month', searcher='search_month')
description = fields.Text(string='Description',
states=STATES, depends=DEPENDS)
category = fields.Many2One(string='Category', required=True,
category = fields.Many2One(string='Category',
model_name='cashbook.category', ondelete='RESTRICT',
states={
'readonly': Or(
STATES['readonly'],
Bool(Eval('bookingtype')) == False,
),
'required': Eval('bookingtype', '').in_(['in', 'out']),
'invisible': ~Eval('bookingtype', '').in_(['in', 'out']),
}, depends=DEPENDS+['bookingtype'],
domain=[
If(
@ -78,14 +85,18 @@ class Line(Workflow, ModelSQL, ModelView):
credit = fields.Numeric(string='Credit', digits=(16, Eval('currency_digits', 2)),
required=True, readonly=True, depends=['currency_digits'])
booktransf = fields.Many2One(string='Transfer Cashbook',
# party or cashbook as counterpart
booktransf = fields.Many2One(string='Source/Dest',
ondelete='RESTRICT', model_name='cashbook.book',
domain=[('cashbook.owner.id', '=', Eval('context',{}).get('user', -1))],
domain=[
('owner.id', '=', Eval('owner_cashbook', -1)),
('id', '!=', Eval('cashbook', -1)),
],
states={
'readonly': STATES['readonly'],
'invisible': ~Eval('bookingtype', '').in_(['mvin', 'mvout']),
'required': Eval('bookingtype', '').in_(['mvin', 'mvout']),
}, depends=DEPENDS+['bookingtype'])
}, depends=DEPENDS+['bookingtype', 'owner_cashbook', 'cashbook'])
party = fields.Many2One(string='Party', model_name='party.party',
ondelete='RESTRICT',
states={
@ -93,6 +104,20 @@ class Line(Workflow, ModelSQL, ModelView):
'invisible': ~Eval('bookingtype', '').in_(['in', 'out']),
'required': Eval('bookingtype', '').in_(['in', 'out']),
}, depends=DEPENDS+['bookingtype'])
payee = fields.Function(fields.Reference(string='Payee', readonly=True,
selection=sel_payee), 'on_change_with_payee', searcher='search_payee')
# link to lines created by this record
reference = fields.Many2One(string='Reference', readonly=True, select=True,
states={
'invisible': ~Bool(Eval('reference')),
}, model_name='cashbook.line', ondelete='CASCADE',
help='The current row was created by and is controlled by the reference row.')
references = fields.One2Many(string='References', model_name='cashbook.line',
help='The rows are created and managed by the current record.',
states={
'invisible': ~Bool(Eval('references')),
}, field='reference', readonly=True)
reconciliation = fields.Many2One(string='Reconciliation', readonly=True,
model_name='cashbook.recon', ondelete='SET NULL',
@ -116,6 +141,9 @@ class Line(Workflow, ModelSQL, ModelView):
state_cashbook = fields.Function(fields.Selection(string='State of Cashbook',
readonly=True, states={'invisible': True}, selection=sel_state_book),
'on_change_with_state_cashbook', searcher='search_state_cashbook')
owner_cashbook = fields.Function(fields.Many2One(string='Owner', readonly=True,
states={'invisible': True}, model_name='res.user'),
'on_change_with_owner_cashbook')
#image = fields.Binary...
@ -138,7 +166,8 @@ class Line(Workflow, ModelSQL, ModelView):
cls._buttons.update({
'wfedit': {
'invisible': Eval('state', '') != 'check',
'depends': ['state'],
'readonly': Bool(Eval('reference')),
'depends': ['state', 'reference'],
},
'wfcheck': {
'invisible': Eval('state') != 'edit',
@ -156,7 +185,27 @@ class Line(Workflow, ModelSQL, ModelView):
def wfedit(cls, lines):
""" edit line
"""
pass
pool = Pool()
Line2 = pool.get('cashbook.line')
to_delete_line = []
for line in lines:
if line.reference:
if Transaction().context.get('line.allow.wfedit', False) == False:
raise UserError(gettext(
'cashbook.msg_line_denywf_by_reference',
recname = line.reference.rec_name,
cbook = line.reference.cashbook.rec_name,
))
# delete references
to_delete_line.extend(list(line.references))
if len(to_delete_line) > 0:
with Transaction().set_context({
'line.allow.wfedit': True,
}):
Line2.wfedit(to_delete_line)
Line2.delete(to_delete_line)
@classmethod
@ModelView.button
@ -166,7 +215,9 @@ class Line(Workflow, ModelSQL, ModelView):
"""
pool = Pool()
Recon = pool.get('cashbook.recon')
Line2 = pool.get('cashbook.line')
to_create_line = []
for line in lines:
# deny if date is in range of existing reconciliation
# allow cashbook-line at range-limits
@ -194,6 +245,23 @@ class Line(Workflow, ModelSQL, ModelView):
'cashbook.msg_line_err_write_to_reconciled',
datetxt = Report.format_date(line.date),
))
# in case of 'mvin' or 'mvout' - create counterpart
if (line.bookingtype in ['mvout', 'mvin']) and (line.reference is None):
to_create_line.append({
'cashbook': line.booktransf.id,
'bookingtype': 'mvin' if line.bookingtype == 'mvout' else 'mvout',
'date': line.date,
'description': line.description,
'amount': line.amount,
'credit': line.debit,
'debit': line.credit,
'booktransf': line.cashbook.id,
'reference': line.id,
})
if len(to_create_line) > 0:
new_lines = Line2.create(to_create_line)
Line2.wfcheck(new_lines)
@classmethod
@ModelView.button
@ -232,12 +300,17 @@ class Line(Workflow, ModelSQL, ModelView):
def get_rec_name(self, name):
""" short + name
"""
return '%(date)s|%(amount)s %(symbol)s|%(desc)s [%(category)s]' % {
credit = self.credit if self.credit is not None else Decimal('0.0')
debit = self.debit if self.debit is not None else Decimal('0.0')
return '%(date)s|%(type)s|%(amount)s %(symbol)s|%(desc)s [%(category)s]' % {
'date': Report.format_date(self.date),
'desc': (self.description or '-')[:40],
'amount': Report.format_number(self.amount or 0.0, None),
'amount': Report.format_number(credit - debit, None),
'symbol': getattr(self.currency, 'symbol', '-'),
'category': self.category_view,
'category': self.category_view \
if self.bookingtype in ['in', 'out'] \
else getattr(self.booktransf, 'rec_name', '-'),
'type': gettext('cashbook.msg_line_bookingtype_%s' % self.bookingtype),
}
@staticmethod
@ -271,6 +344,27 @@ class Line(Workflow, ModelSQL, ModelView):
return [tab2]
@fields.depends('party', 'booktransf', 'bookingtype')
def on_change_with_payee(self, name=None):
""" get party or cashbook
"""
if self.bookingtype:
if self.bookingtype in ['in', 'out']:
if self.party:
return 'party.party,%d' % self.party.id
elif self.bookingtype in ['mvin', 'mvout']:
if self.booktransf:
return 'cashbook.book,%d' % self.booktransf.id
@classmethod
def search_payee(cls, names, clause):
""" search in payee for party or cashbook
"""
return ['OR',
('party.rec_name',) + tuple(clause[1:]),
('booktransf.rec_name',) + tuple(clause[1:]),
]
@fields.depends('category')
def on_change_with_category_view(self, name=None):
""" show optimizef form of category for list-view
@ -320,6 +414,13 @@ class Line(Workflow, ModelSQL, ModelView):
)
return [('id', 'in', query)]
@fields.depends('cashbook', '_parent_cashbook.owner')
def on_change_with_owner_cashbook(self, name=None):
""" get current owner
"""
if self.cashbook:
return self.cashbook.owner.id
@fields.depends('cashbook', '_parent_cashbook.state')
def on_change_with_state_cashbook(self, name=None):
""" get state of cashbook