formatting, line: test for delete of party
This commit is contained in:
parent
78f160bf0b
commit
619a17bcd6
16 changed files with 701 additions and 516 deletions
388
line.py
388
line.py
|
@ -45,26 +45,32 @@ STATES = {
|
|||
Eval('state_cashbook', '') != 'open',
|
||||
),
|
||||
}
|
||||
DEPENDS=['state', 'state_cashbook']
|
||||
DEPENDS = ['state', 'state_cashbook']
|
||||
|
||||
|
||||
class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
||||
'Cashbook Line'
|
||||
__name__ = 'cashbook.line'
|
||||
|
||||
cashbook = fields.Many2One(string='Cashbook', required=True, select=True,
|
||||
cashbook = fields.Many2One(
|
||||
string='Cashbook', required=True, select=True,
|
||||
model_name='cashbook.book', ondelete='CASCADE', readonly=True,
|
||||
domain=[('btype', '!=', None)])
|
||||
date = fields.Date(string='Date', required=True, select=True,
|
||||
date = fields.Date(
|
||||
string='Date', required=True, select=True,
|
||||
states=STATES, depends=DEPENDS)
|
||||
month = fields.Function(fields.Integer(string='Month', readonly=True),
|
||||
month = fields.Function(fields.Integer(
|
||||
string='Month', readonly=True),
|
||||
'on_change_with_month', searcher='search_month')
|
||||
number = fields.Char(string='Number', readonly=True)
|
||||
description = fields.Text(string='Description', select=True,
|
||||
description = fields.Text(
|
||||
string='Description', select=True,
|
||||
states=STATES, depends=DEPENDS)
|
||||
descr_short = fields.Function(fields.Char(string='Description', readonly=True),
|
||||
descr_short = fields.Function(fields.Char(
|
||||
string='Description', readonly=True),
|
||||
'on_change_with_descr_short', searcher='search_descr_short')
|
||||
category = fields.Many2One(string='Category', select=True,
|
||||
category = fields.Many2One(
|
||||
string='Category', select=True,
|
||||
model_name='cashbook.category', ondelete='RESTRICT',
|
||||
states={
|
||||
'readonly': Or(
|
||||
|
@ -80,18 +86,23 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
('cattype', '=', 'in'),
|
||||
('cattype', '=', 'out'),
|
||||
)])
|
||||
category_view = fields.Function(fields.Char(string='Category', readonly=True),
|
||||
category_view = fields.Function(fields.Char(
|
||||
string='Category', readonly=True),
|
||||
'on_change_with_category_view', searcher='search_category_view')
|
||||
feature = fields.Function(fields.Char(string='Feature', readonly=True,
|
||||
feature = fields.Function(fields.Char(
|
||||
string='Feature', readonly=True,
|
||||
states={'invisible': True}), 'on_change_with_feature')
|
||||
booktransf_feature = fields.Function(fields.Char(string='Feature', readonly=True,
|
||||
booktransf_feature = fields.Function(fields.Char(
|
||||
string='Feature', readonly=True,
|
||||
states={'invisible': True}), 'on_change_with_booktransf_feature')
|
||||
|
||||
bookingtype = fields.Selection(string='Type', required=True,
|
||||
bookingtype = fields.Selection(
|
||||
string='Type', required=True,
|
||||
help='Type of Booking', selection=sel_bookingtype, select=True,
|
||||
states=STATES, depends=DEPENDS)
|
||||
bookingtype_string = bookingtype.translated('bookingtype')
|
||||
amount = fields.Numeric(string='Amount', digits=(16, Eval('currency_digits', 2)),
|
||||
amount = fields.Numeric(
|
||||
string='Amount', digits=(16, Eval('currency_digits', 2)),
|
||||
required=True,
|
||||
states={
|
||||
'readonly': Or(
|
||||
|
@ -99,13 +110,16 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
Eval('bookingtype', '').in_(['spin', 'spout']),
|
||||
),
|
||||
}, depends=DEPENDS+['currency_digits', 'bookingtype'])
|
||||
debit = fields.Numeric(string='Debit', digits=(16, Eval('currency_digits', 2)),
|
||||
debit = fields.Numeric(
|
||||
string='Debit', digits=(16, Eval('currency_digits', 2)),
|
||||
required=True, readonly=True, depends=['currency_digits'])
|
||||
credit = fields.Numeric(string='Credit', digits=(16, Eval('currency_digits', 2)),
|
||||
credit = fields.Numeric(
|
||||
string='Credit', digits=(16, Eval('currency_digits', 2)),
|
||||
required=True, readonly=True, depends=['currency_digits'])
|
||||
|
||||
# party or cashbook as counterpart
|
||||
booktransf = fields.Many2One(string='Source/Dest',
|
||||
booktransf = fields.Many2One(
|
||||
string='Source/Dest',
|
||||
ondelete='RESTRICT', model_name='cashbook.book',
|
||||
domain=[
|
||||
('owner.id', '=', Eval('owner_cashbook', -1)),
|
||||
|
@ -117,28 +131,35 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
'invisible': ~Eval('bookingtype', '').in_(['mvin', 'mvout']),
|
||||
'required': Eval('bookingtype', '').in_(['mvin', 'mvout']),
|
||||
}, depends=DEPENDS+['bookingtype', 'owner_cashbook', 'cashbook'])
|
||||
party = fields.Many2One(string='Party', model_name='party.party',
|
||||
party = fields.Many2One(
|
||||
string='Party', model_name='party.party',
|
||||
ondelete='RESTRICT',
|
||||
states={
|
||||
'readonly': STATES['readonly'],
|
||||
'invisible': ~Eval('bookingtype', '').in_(['in', 'out', 'spin', 'spout']),
|
||||
'invisible': ~Eval('bookingtype', '').in_(
|
||||
['in', 'out', 'spin', 'spout']),
|
||||
}, depends=DEPENDS+['bookingtype'])
|
||||
payee = fields.Function(fields.Reference(string='Payee', readonly=True,
|
||||
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,
|
||||
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',
|
||||
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)
|
||||
splitlines = fields.One2Many(string='Split booking lines',
|
||||
splitlines = fields.One2Many(
|
||||
string='Split booking lines',
|
||||
model_name='cashbook.split',
|
||||
help='Rows with different categories form the total sum of the booking',
|
||||
states={
|
||||
|
@ -150,7 +171,8 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
'required': Eval('bookingtype' '').in_(['spin', 'spout']),
|
||||
}, field='line', depends=DEPENDS+['bookingtype'])
|
||||
|
||||
reconciliation = fields.Many2One(string='Reconciliation', readonly=True,
|
||||
reconciliation = fields.Many2One(
|
||||
string='Reconciliation', readonly=True,
|
||||
model_name='cashbook.recon', ondelete='SET NULL',
|
||||
domain=[('cashbook.id', '=', Eval('cashbook'))],
|
||||
depends=['cashbook'],
|
||||
|
@ -158,24 +180,31 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
'invisible': ~Bool(Eval('reconciliation')),
|
||||
})
|
||||
|
||||
balance = fields.Function(fields.Numeric(string='Balance',
|
||||
balance = fields.Function(fields.Numeric(
|
||||
string='Balance',
|
||||
digits=(16, Eval('currency_digits', 2)),
|
||||
help='Balance of the cash book up to the current line, if the default sorting applies.',
|
||||
help='Balance of the cash book up to the current line, ' +
|
||||
'if the default sorting applies.',
|
||||
readonly=True, depends=['currency_digits']),
|
||||
'on_change_with_balance')
|
||||
|
||||
currency = fields.Function(fields.Many2One(model_name='currency.currency',
|
||||
currency = fields.Function(fields.Many2One(
|
||||
model_name='currency.currency',
|
||||
string="Currency", readonly=True), 'on_change_with_currency')
|
||||
currency_digits = fields.Function(fields.Integer(string='Currency Digits',
|
||||
currency_digits = fields.Function(fields.Integer(
|
||||
string='Currency Digits',
|
||||
readonly=True), 'on_change_with_currency_digits')
|
||||
|
||||
state = fields.Selection(string='State', required=True, readonly=True,
|
||||
state = fields.Selection(
|
||||
string='State', required=True, readonly=True,
|
||||
select=True, selection=sel_linetype)
|
||||
state_string = state.translated('state')
|
||||
state_cashbook = fields.Function(fields.Selection(string='State of Cashbook',
|
||||
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,
|
||||
owner_cashbook = fields.Function(fields.Many2One(
|
||||
string='Owner', readonly=True,
|
||||
states={'invisible': True}, model_name='res.user'),
|
||||
'on_change_with_owner_cashbook')
|
||||
|
||||
|
@ -230,8 +259,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
return super().view_attributes() + [
|
||||
('/tree', 'visual',
|
||||
If(Eval('balance', 0) < 0, 'warning',
|
||||
If(Eval('date', Date()) > Date(), 'muted', '')
|
||||
)),
|
||||
If(Eval('date', Date()) > Date(), 'muted', ''))),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
|
@ -247,13 +275,16 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
tab_book2 = Book2.__table__() # transfer-target
|
||||
cursor = Transaction().connection.cursor()
|
||||
|
||||
query = tab_line.join(tab_book,
|
||||
query = tab_line.join(
|
||||
tab_book,
|
||||
condition=tab_line.cashbook == tab_book.id,
|
||||
).join(tab_book2,
|
||||
condition=tab_line.booktransf== tab_book2.id,
|
||||
).select(tab_line.id,
|
||||
where=tab_line.bookingtype.in_(['mvin', 'mvout']) & \
|
||||
(tab_line.amount_2nd_currency == None) & \
|
||||
).join(
|
||||
tab_book2,
|
||||
condition=tab_line.booktransf == tab_book2.id,
|
||||
).select(
|
||||
tab_line.id,
|
||||
where=tab_line.bookingtype.in_(['mvin', 'mvout']) &
|
||||
(tab_line.amount_2nd_currency == None) &
|
||||
(tab_book.currency != tab_book2.currency)
|
||||
)
|
||||
lines = Line2.search([('id', 'in', query)])
|
||||
|
@ -270,9 +301,9 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
|
||||
for line in to_write:
|
||||
qu1 = tab_line.update(
|
||||
columns = [tab_line.amount_2nd_currency],
|
||||
values = [line['amount_2nd_currency']],
|
||||
where = tab_line.id == line['id'],
|
||||
columns=[tab_line.amount_2nd_currency],
|
||||
values=[line['amount_2nd_currency']],
|
||||
where=tab_line.id == line['id'],
|
||||
)
|
||||
cursor.execute(*qu1)
|
||||
|
||||
|
@ -288,19 +319,18 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
to_delete_line = []
|
||||
for line in lines:
|
||||
if line.reference:
|
||||
if Transaction().context.get('line.allow.wfedit', False) == False:
|
||||
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,
|
||||
))
|
||||
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,
|
||||
}):
|
||||
'line.allow.wfedit': True}):
|
||||
Line2.wfedit(to_delete_line)
|
||||
Line2.delete(to_delete_line)
|
||||
|
||||
|
@ -323,11 +353,10 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
('state', 'in', ['check', 'done']),
|
||||
('cashbook.id', '=', line.cashbook.id),
|
||||
('date_from', '<', line.date),
|
||||
('date_to', '>', line.date),
|
||||
]) > 0:
|
||||
('date_to', '>', line.date)]) > 0:
|
||||
raise UserError(gettext(
|
||||
'cashbook.msg_line_err_write_to_reconciled',
|
||||
datetxt = Report.format_date(line.date),
|
||||
datetxt=Report.format_date(line.date),
|
||||
))
|
||||
# deny if date is at reconciliation limits and two
|
||||
# reconciliations exist
|
||||
|
@ -336,12 +365,10 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
('cashbook.id', '=', line.cashbook.id),
|
||||
['OR',
|
||||
('date_from', '=', line.date),
|
||||
('date_to', '=', line.date),
|
||||
]
|
||||
]) > 1:
|
||||
('date_to', '=', line.date)]]) > 1:
|
||||
raise UserError(gettext(
|
||||
'cashbook.msg_line_err_write_to_reconciled',
|
||||
datetxt = Report.format_date(line.date),
|
||||
datetxt=Report.format_date(line.date),
|
||||
))
|
||||
|
||||
if line.reference is None:
|
||||
|
@ -356,25 +383,28 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
if sp_line.splittype != 'tr':
|
||||
continue
|
||||
|
||||
values = cls.get_counterpart_values(line,
|
||||
splitline = sp_line,
|
||||
values = {
|
||||
'cashbook': sp_line.booktransf.id,
|
||||
'description': sp_line.description,
|
||||
'amount': sp_line.amount \
|
||||
if sp_line.currency.id == sp_line.booktransf.currency.id \
|
||||
values = cls.get_counterpart_values(
|
||||
line, splitline=sp_line,
|
||||
values={
|
||||
'cashbook': sp_line.booktransf.id,
|
||||
'description': sp_line.description,
|
||||
'amount': sp_line.amount
|
||||
if sp_line.currency.id == sp_line.
|
||||
booktransf.currency.id
|
||||
else sp_line.amount_2nd_currency,
|
||||
'amount_2nd_currency': sp_line.amount \
|
||||
if sp_line.currency.id != sp_line.booktransf.currency.id \
|
||||
'amount_2nd_currency': sp_line.amount
|
||||
if sp_line.currency.id != sp_line.
|
||||
booktransf.currency.id
|
||||
else None,
|
||||
'bookingtype': 'mvin' \
|
||||
if line.bookingtype.endswith('out') else 'mvout',
|
||||
'bookingtype': 'mvin'
|
||||
if line.bookingtype.endswith('out')
|
||||
else 'mvout',
|
||||
})
|
||||
values.update(cls.get_debit_credit(values))
|
||||
to_create_line.append(values)
|
||||
|
||||
# add number to line
|
||||
if line.cashbook.number_atcheck == True:
|
||||
if line.cashbook.number_atcheck is True:
|
||||
if len(line.number or '') == 0:
|
||||
to_write_line.extend([
|
||||
[line],
|
||||
|
@ -459,11 +489,12 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
'desc': (self.description or '-')[:40],
|
||||
'amount': Report.format_number(credit - debit, None),
|
||||
'symbol': getattr(self.currency, 'symbol', '-'),
|
||||
'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),
|
||||
}
|
||||
'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
|
||||
def order_state(tables):
|
||||
|
@ -477,8 +508,8 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
Case(
|
||||
(tab_line.state == 'edit', 1),
|
||||
(tab_line.state.in_(['check', 'recon', 'done']), 0),
|
||||
else_ = 2),
|
||||
where=tab_line.id==table.id
|
||||
else_=2),
|
||||
where=tab_line.id == table.id
|
||||
)
|
||||
return [query]
|
||||
|
||||
|
@ -490,10 +521,9 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
Category = Pool().get('cashbook.category')
|
||||
tab_cat = Category.__table__()
|
||||
|
||||
tab2 = tab_cat.select(tab_cat.name,
|
||||
where=tab_cat.id==table.category
|
||||
)
|
||||
|
||||
tab2 = tab_cat.select(
|
||||
tab_cat.name,
|
||||
where=tab_cat.id == table.category)
|
||||
return [tab2]
|
||||
|
||||
@staticmethod
|
||||
|
@ -509,8 +539,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
"""
|
||||
return ['OR',
|
||||
('party.rec_name',) + tuple(clause[1:]),
|
||||
('booktransf.rec_name',) + tuple(clause[1:]),
|
||||
]
|
||||
('booktransf.rec_name',) + tuple(clause[1:])]
|
||||
|
||||
@classmethod
|
||||
def search_category_view(cls, name, clause):
|
||||
|
@ -529,10 +558,12 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
Operator = fields.SQL_OPERATORS[clause[1]]
|
||||
|
||||
dt1 = IrDate.today()
|
||||
query = tab_line.select(tab_line.id,
|
||||
query = tab_line.select(
|
||||
tab_line.id,
|
||||
where=Operator(
|
||||
Literal(12 * dt1.year + dt1.month) - \
|
||||
(Literal(12) * DatePart('year', tab_line.date) + DatePart('month', tab_line.date)),
|
||||
Literal(12 * dt1.year + dt1.month) -
|
||||
(Literal(12) * DatePart('year', tab_line.date) +
|
||||
DatePart('month', tab_line.date)),
|
||||
clause[2]),
|
||||
)
|
||||
return [('id', 'in', query)]
|
||||
|
@ -553,9 +584,11 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
def on_change_splitlines(self):
|
||||
""" update amount if splitlines change
|
||||
"""
|
||||
self.amount = sum([x.amount for x in self.splitlines if x.amount is not None])
|
||||
self.amount = sum([
|
||||
x.amount for x in self.splitlines if x.amount is not None])
|
||||
|
||||
@fields.depends('bookingtype', 'category', 'splitlines', 'booktransf',\
|
||||
@fields.depends(
|
||||
'bookingtype', 'category', 'splitlines', 'booktransf',
|
||||
'currency2nd')
|
||||
def on_change_bookingtype(self):
|
||||
""" clear category if not valid type
|
||||
|
@ -567,19 +600,20 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
|
||||
if self.bookingtype:
|
||||
if self.category:
|
||||
if not self.bookingtype in types.get(self.category.cattype, ''):
|
||||
if self.bookingtype not in types.get(self.category.cattype, ''):
|
||||
self.category = None
|
||||
|
||||
if self.bookingtype.startswith('sp'): # split booking
|
||||
self.category = None
|
||||
self.booktransf = None
|
||||
for spline in self.splitlines:
|
||||
if not self.bookingtype in types.get(getattr(spline.category, 'cattype', '-'), ''):
|
||||
if self.bookingtype not in types.get(
|
||||
getattr(spline.category, 'cattype', '-'), ''):
|
||||
spline.category = None
|
||||
elif self.bookingtype.startswith('mv'): # transfer
|
||||
elif self.bookingtype.startswith('mv'): # transfer
|
||||
self.splitlines = []
|
||||
self.category = None
|
||||
else : # category
|
||||
else: # category
|
||||
self.splitlines = []
|
||||
self.booktransf = None
|
||||
self.currency2nd = self.on_change_with_currency2nd()
|
||||
|
@ -627,9 +661,9 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
if self.category:
|
||||
cfg1 = Configuration.get_singleton()
|
||||
|
||||
if getattr(cfg1, 'catnamelong', True) == True:
|
||||
if getattr(cfg1, 'catnamelong', True) is True:
|
||||
return self.category.rec_name
|
||||
else :
|
||||
else:
|
||||
return self.category.name
|
||||
|
||||
@fields.depends('date')
|
||||
|
@ -673,7 +707,9 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
return 2
|
||||
|
||||
@classmethod
|
||||
def get_balance_of_line(cls, line, field_name='amount', credit_name='credit', debit_name='debit'):
|
||||
def get_balance_of_line(
|
||||
cls, line, field_name='amount', credit_name='credit',
|
||||
debit_name='debit'):
|
||||
""" get balance of current line,
|
||||
try to speed up by usage of last reconcilitaion
|
||||
"""
|
||||
|
@ -699,8 +735,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
('date', '<=', line2.date),
|
||||
['OR',
|
||||
('reconciliation', '=', None),
|
||||
('reconciliation.id', '!=', recons[0]),
|
||||
],
|
||||
('reconciliation.id', '!=', recons[0])],
|
||||
])
|
||||
end_value = getattr(recons[0], 'end_%s' % field_name)
|
||||
return (query2, end_value)
|
||||
|
@ -719,13 +754,14 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
query.append(
|
||||
('reconciliation.id', '=', line.reconciliation.id),
|
||||
)
|
||||
balance = getattr(line.reconciliation, 'start_%s' % field_name)
|
||||
else :
|
||||
balance = getattr(
|
||||
line.reconciliation, 'start_%s' % field_name)
|
||||
else:
|
||||
(query2, balance2) = get_from_last_recon(line)
|
||||
query.extend(query2)
|
||||
if balance2 is not None:
|
||||
balance = balance2
|
||||
else :
|
||||
else:
|
||||
(query2, balance2) = get_from_last_recon(line)
|
||||
query.extend(query2)
|
||||
if balance2 is not None:
|
||||
|
@ -743,18 +779,16 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
break
|
||||
return balance
|
||||
|
||||
@fields.depends('id', 'date', 'cashbook', \
|
||||
'_parent_cashbook.id', 'reconciliation', \
|
||||
'_parent_reconciliation.start_amount',\
|
||||
'_parent_reconciliation.state')
|
||||
@fields.depends(
|
||||
'id', 'date', 'cashbook', '_parent_cashbook.id', 'reconciliation',
|
||||
'_parent_reconciliation.start_amount', '_parent_reconciliation.state')
|
||||
def on_change_with_balance(self, name=None):
|
||||
""" compute balance until current line, with current sort order,
|
||||
try to use a reconciliation as start to speed up calculation
|
||||
"""
|
||||
Line2 = Pool().get('cashbook.line')
|
||||
return Line2.get_balance_of_line(self,
|
||||
field_name='amount',
|
||||
credit_name='credit',
|
||||
return Line2.get_balance_of_line(
|
||||
self, field_name='amount', credit_name='credit',
|
||||
debit_name='debit')
|
||||
|
||||
@classmethod
|
||||
|
@ -764,12 +798,14 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
values2 = {}
|
||||
values2.update(values)
|
||||
|
||||
bookingtype = values2.get('bookingtype', getattr(line, 'bookingtype', None))
|
||||
bookingtype = values2.get(
|
||||
'bookingtype', getattr(line, 'bookingtype', None))
|
||||
if (bookingtype in ['in', 'out', 'mvin', 'mvout']) and \
|
||||
('splitlines' not in values2.keys()):
|
||||
if line:
|
||||
if len(line.splitlines) > 0:
|
||||
values2['splitlines'] = [('delete', [x.id for x in line.splitlines])]
|
||||
values2['splitlines'] = [
|
||||
('delete', [x.id for x in line.splitlines])]
|
||||
|
||||
if bookingtype in ['in', 'out']:
|
||||
values2['booktransf'] = None
|
||||
|
@ -788,7 +824,8 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
transfer booking
|
||||
"""
|
||||
line_currency = getattr(line.currency, 'id', None)
|
||||
booktransf_currency = getattr(getattr(line.booktransf, 'currency', {}), 'id', None)
|
||||
booktransf_currency = getattr(getattr(
|
||||
line.booktransf, 'currency', {}), 'id', None)
|
||||
|
||||
result = {
|
||||
'cashbook': getattr(line.booktransf, 'id', None),
|
||||
|
@ -797,13 +834,11 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
'description': line.description,
|
||||
'booktransf': line.cashbook.id,
|
||||
'reference': line.id,
|
||||
'amount': line.amount \
|
||||
if line_currency == booktransf_currency \
|
||||
else line.amount_2nd_currency,
|
||||
'amount_2nd_currency': line.amount \
|
||||
if line_currency != booktransf_currency \
|
||||
else None,
|
||||
}
|
||||
'amount': line.amount
|
||||
if line_currency == booktransf_currency
|
||||
else line.amount_2nd_currency,
|
||||
'amount_2nd_currency': line.amount
|
||||
if line_currency != booktransf_currency else None}
|
||||
# update values from 'values'
|
||||
result.update(values)
|
||||
return result
|
||||
|
@ -813,10 +848,12 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
""" compute debit/credit from amount
|
||||
"""
|
||||
if isinstance(values, dict):
|
||||
type_ = values.get('bookingtype', getattr(line, 'bookingtype', None))
|
||||
type_ = values.get(
|
||||
'bookingtype', getattr(line, 'bookingtype', None))
|
||||
amount = values.get('amount', None)
|
||||
else :
|
||||
type_ = getattr(values, 'bookingtype', getattr(line, 'bookingtype', None))
|
||||
else:
|
||||
type_ = getattr(
|
||||
values, 'bookingtype', getattr(line, 'bookingtype', None))
|
||||
amount = getattr(values, 'amount', None)
|
||||
|
||||
result = {}
|
||||
|
@ -824,15 +861,11 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
if amount is not None:
|
||||
if type_ in ['in', 'mvin', 'spin']:
|
||||
result.update({
|
||||
'debit': Decimal('0.0'),
|
||||
'credit': amount,
|
||||
})
|
||||
'debit': Decimal('0.0'), 'credit': amount})
|
||||
elif type_ in ['out', 'mvout', 'spout']:
|
||||
result.update({
|
||||
'debit': amount,
|
||||
'credit': Decimal('0.0'),
|
||||
})
|
||||
else :
|
||||
'debit': amount, 'credit': Decimal('0.0')})
|
||||
else:
|
||||
raise ValueError('invalid "bookingtype"')
|
||||
return result
|
||||
|
||||
|
@ -851,30 +884,27 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
if line.date < line.cashbook.start_date:
|
||||
raise UserError(gettext(
|
||||
'cashbook.msg_line_date_before_book',
|
||||
datebook = Report.format_date(line.cashbook.start_date),
|
||||
recname = line.rec_name,
|
||||
))
|
||||
datebook=Report.format_date(line.cashbook.start_date),
|
||||
recname=line.rec_name))
|
||||
|
||||
# line: category <--> bookingtype?
|
||||
if line.category:
|
||||
if not line.bookingtype in types[line.category.cattype]:
|
||||
if line.bookingtype not in types[line.category.cattype]:
|
||||
raise UserError(gettext(
|
||||
'cashbook.msg_line_invalid_category',
|
||||
recname = line.rec_name,
|
||||
booktype = line.bookingtype_string,
|
||||
))
|
||||
recname=line.rec_name,
|
||||
booktype=line.bookingtype_string))
|
||||
|
||||
# splitline: category <--> bookingtype?
|
||||
for spline in line.splitlines:
|
||||
if spline.splittype != 'cat':
|
||||
continue
|
||||
if not line.bookingtype in types[spline.category.cattype]:
|
||||
if line.bookingtype not in types[spline.category.cattype]:
|
||||
raise UserError(gettext(
|
||||
'cashbook.msg_line_split_invalid_category',
|
||||
recname = line.rec_name,
|
||||
splitrecname = spline.rec_name,
|
||||
booktype = line.bookingtype_string,
|
||||
))
|
||||
recname=line.rec_name,
|
||||
splitrecname=spline.rec_name,
|
||||
booktype=line.bookingtype_string))
|
||||
|
||||
@classmethod
|
||||
def check_permission_write(cls, lines, values={}):
|
||||
|
@ -885,29 +915,28 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
if line.cashbook.state != 'open':
|
||||
raise UserError(gettext(
|
||||
'cashbook.msg_book_deny_write',
|
||||
bookname = line.cashbook.rec_name,
|
||||
state_txt = line.cashbook.state_string,
|
||||
))
|
||||
bookname=line.cashbook.rec_name,
|
||||
state_txt=line.cashbook.state_string))
|
||||
|
||||
# deny write if reconciliation is 'check' or 'done'
|
||||
if line.reconciliation:
|
||||
if line.reconciliation.state == 'done':
|
||||
raise UserError(gettext(
|
||||
'cashbook.msg_line_deny_write_by_reconciliation',
|
||||
recname = line.rec_name,
|
||||
reconame = line.reconciliation.rec_name,
|
||||
))
|
||||
recname=line.rec_name,
|
||||
reconame=line.reconciliation.rec_name))
|
||||
|
||||
# deny write if line is not 'Edit'
|
||||
if line.state != 'edit':
|
||||
# allow state-update, if its the only action
|
||||
if not ((len(set({'state', 'reconciliation', 'number'}).intersection(values.keys())) > 0) \
|
||||
and (len(values.keys()) == 1)):
|
||||
if not ((len(set({
|
||||
'state', 'reconciliation', 'number'
|
||||
}).intersection(values.keys())) > 0)
|
||||
and (len(values.keys()) == 1)):
|
||||
raise UserError(gettext(
|
||||
'cashbook.msg_line_deny_write',
|
||||
recname = line.rec_name,
|
||||
state_txt = line.state_string,
|
||||
))
|
||||
recname=line.rec_name,
|
||||
state_txt=line.state_string))
|
||||
|
||||
@classmethod
|
||||
def check_permission_delete(cls, lines):
|
||||
|
@ -917,16 +946,14 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
if line.cashbook.state == 'closed':
|
||||
raise UserError(gettext(
|
||||
'cashbook.msg_line_deny_delete1',
|
||||
linetxt = line.rec_name,
|
||||
bookname = line.cashbook.rec_name,
|
||||
bookstate = line.cashbook.state_string,
|
||||
))
|
||||
linetxt=line.rec_name,
|
||||
bookname=line.cashbook.rec_name,
|
||||
bookstate=line.cashbook.state_string))
|
||||
if line.state != 'edit':
|
||||
raise UserError(gettext(
|
||||
'cashbook.msg_line_deny_delete2',
|
||||
linetxt = line.rec_name,
|
||||
linestate = line.state_string,
|
||||
))
|
||||
linetxt=line.rec_name,
|
||||
linestate=line.state_string))
|
||||
|
||||
@classmethod
|
||||
def update_values_by_splitlines(cls, lines):
|
||||
|
@ -936,7 +963,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
for line in lines:
|
||||
amount = sum([x.amount for x in line.splitlines])
|
||||
if amount != line.amount:
|
||||
to_write.extend([ [line], {'amount': amount,} ])
|
||||
to_write.extend([[line], {'amount': amount}])
|
||||
return to_write
|
||||
|
||||
@classmethod
|
||||
|
@ -946,7 +973,8 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
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]])
|
||||
values['amount'] = sum([
|
||||
x.get('amount', None) for x in action[1]])
|
||||
return values
|
||||
|
||||
@classmethod
|
||||
|
@ -956,7 +984,8 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
Cashbook = Pool().get('cashbook.book')
|
||||
cashbook = values.get('cashbook', None)
|
||||
if cashbook:
|
||||
values.update(cls.add_2nd_currency(values, Cashbook(cashbook).currency))
|
||||
values.update(cls.add_2nd_currency(
|
||||
values, Cashbook(cashbook).currency))
|
||||
return values
|
||||
|
||||
@classmethod
|
||||
|
@ -975,7 +1004,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
default = default.copy()
|
||||
default.setdefault('number', None)
|
||||
default.setdefault('state', cls.default_state())
|
||||
return super(Line, cls).copy(moves, default=default)
|
||||
return super(Line, cls).copy(lines, default=default)
|
||||
|
||||
@classmethod
|
||||
def create(cls, vlist):
|
||||
|
@ -988,7 +1017,8 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
values.update(cls.clear_by_bookingtype(values))
|
||||
values.update(cls.add_2nd_unit_values(values))
|
||||
|
||||
# deny add to reconciliation if state is not 'check', 'recon' or 'done'
|
||||
# deny add to reconciliation if state is
|
||||
# not 'check', 'recon' or 'done'
|
||||
if values.get('reconciliation', None):
|
||||
if not values.get('state', '-') in ['check', 'done', 'recon']:
|
||||
date_txt = '-'
|
||||
|
@ -996,11 +1026,9 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
date_txt = Report.format_date(values.get('date', None))
|
||||
raise UserError(gettext(
|
||||
'cashbook.msg_line_deny_recon_by_state',
|
||||
recname = '%(date)s|%(descr)s' % {
|
||||
recname='%(date)s|%(descr)s' % {
|
||||
'date': date_txt,
|
||||
'descr': values.get('description', '-'),
|
||||
},
|
||||
))
|
||||
'descr': values.get('description', '-')}))
|
||||
return super(Line, cls).create(vlist)
|
||||
|
||||
@classmethod
|
||||
|
@ -1015,21 +1043,21 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
|
||||
for line in lines:
|
||||
if line.reconciliation:
|
||||
# deny state-change to 'edit' if line is linked to reconciliation
|
||||
# deny state-change to 'edit' if line is
|
||||
# linked to reconciliation
|
||||
if values.get('state', '-') == 'edit':
|
||||
raise UserError(gettext(
|
||||
'cashbook.msg_line_deny_stateedit_with_recon',
|
||||
recname = line.rec_name,
|
||||
))
|
||||
recname=line.rec_name))
|
||||
|
||||
# deny add to reconciliation if state is not 'check', 'recon' or 'done'
|
||||
# deny add to reconciliation if state is
|
||||
# not 'check', 'recon' or 'done'
|
||||
if values.get('reconciliation', None):
|
||||
for line in lines:
|
||||
if not line.state in ['check', 'done', 'recon']:
|
||||
if line.state not in ['check', 'done', 'recon']:
|
||||
raise UserError(gettext(
|
||||
'cashbook.msg_line_deny_recon_by_state',
|
||||
recname = line.rec_name
|
||||
))
|
||||
recname=line.rec_name))
|
||||
|
||||
# update debit / credit
|
||||
fields_update = cls.get_fields_write_update()
|
||||
|
@ -1043,13 +1071,15 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
updt_fields = []
|
||||
updt_fields.extend(values.keys())
|
||||
if 'bookingtype' in values.keys():
|
||||
updt_fields.extend([x for x in fields_update if x not in values.keys()])
|
||||
updt_fields.extend([
|
||||
x for x in fields_update
|
||||
if x not in values.keys()])
|
||||
|
||||
values2.update(cls.get_debit_credit({
|
||||
x:values.get(x, getattr(line, x)) for x in updt_fields
|
||||
}, line=line))
|
||||
x: values.get(x, getattr(line, x))
|
||||
for x in updt_fields}, line=line))
|
||||
to_write.extend([lines, values2])
|
||||
else :
|
||||
else:
|
||||
to_write.extend([lines, values])
|
||||
|
||||
super(Line, cls).write(*to_write)
|
||||
|
@ -1068,23 +1098,27 @@ class LineContext(ModelView):
|
|||
'Line Context'
|
||||
__name__ = 'cashbook.line.context'
|
||||
|
||||
date_from = fields.Date(string='Start Date', depends=['date_to'],
|
||||
date_from = fields.Date(
|
||||
string='Start Date', depends=['date_to'],
|
||||
help='Limits the date range for the displayed entries.',
|
||||
domain=[
|
||||
If(Eval('date_to') & Eval('date_from'),
|
||||
('date_from', '<=', Eval('date_to')),
|
||||
()),
|
||||
])
|
||||
date_to = fields.Date(string='End Date', depends=['date_from'],
|
||||
date_to = fields.Date(
|
||||
string='End Date', depends=['date_from'],
|
||||
help='Limits the date range for the displayed entries.',
|
||||
domain=[
|
||||
If(Eval('date_to') & Eval('date_from'),
|
||||
('date_from', '<=', Eval('date_to')),
|
||||
()),
|
||||
])
|
||||
checked = fields.Boolean(string='Checked',
|
||||
checked = fields.Boolean(
|
||||
string='Checked',
|
||||
help='Show account lines in Checked-state.')
|
||||
done = fields.Boolean(string='Done',
|
||||
done = fields.Boolean(
|
||||
string='Done',
|
||||
help='Show account lines in Done-state.')
|
||||
|
||||
@classmethod
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue