Files
account-financial-tools/account_constraints/model/account_move_line.py

149 lines
6.4 KiB
Python

# -*- coding: utf-8 -*-
##############################################################################
#
# Author Joel Grand-Guillaume. Copyright 2012 Camptocamp SA
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, api, exceptions, _
class AccountMoveLine(models.Model):
_inherit = 'account.move.line'
@api.multi
def _authorized_reconcile(self, vals):
""" Check if only reconcile_id and/or reconcile_partial_id are altered.
We cannot change other vals, but we should be able to write or unlink
those field (e.g. when you want to manually unreconcile an entry
generated by an invoice).
"""
if not vals:
return False
rec_keys = set(["reconcile_id", "reconcile_partial_id"])
write_keys = set(vals)
return rec_keys.issuperset(write_keys)
@api.multi
def _check_invoice_related_move(self, vals=None):
for line in self:
if line.invoice:
if self._authorized_reconcile(vals):
return True
err_msg = (_('Invoice name (id): %s (%s)') %
(line.invoice.name, line.invoice.id))
raise exceptions.Warning(
_('You cannot do this on an entry generated by an invoice.'
'You must '
'change the related invoice directly.\n%s.') % err_msg)
return True
@api.multi
def _check_statement_related_move(self, vals=None):
for line in self:
if line.statement_id:
if self._authorized_reconcile(vals):
return True
err_msg = (_('Bank statement name (id): %s (%s)') %
(line.statement_id.name, line.statement_id.id))
raise exceptions.Warning(
_('You cannot do this on an entry generated by a bank'
' statement. '
'You must change the related bank statement'
' directly.\n%s.') % err_msg)
return True
@api.cr_uid_ids_context
def unlink(self, cr, uid, ids, context=None, check=True):
""" Add the following checks:
- Is the move related to an invoice
- Is the move related to a bank statement
- Is other values than reconcile_partial_id and/or reconcile_id
modified
In that case, we forbid the move to be deleted even if draft. We
should never delete directly a move line related or generated by
another object. This is mandatory if you use the module setting
all moves in draft (module: account_default_draft_move)
"""
if not context.get('from_parent_object', False):
self._check_invoice_related_move(cr, uid, ids)
self._check_statement_related_move(cr, uid, ids)
return super(AccountMoveLine, self).unlink(cr, uid, ids,
context=context,
check=check)
@api.cr_uid_ids_context
def write(self, cr, uid, ids, vals, context=None, check=True,
update_check=True):
""" Add the following checks:
- Is the move related to an invoice
- Is the move related to a bank statement
- Is other values than reconcile_partial_id and/or reconcile_id
modified
In that case, we forbid the move to be modified even if draft.
We should never update directly a move line related or generated
by another object. This is mandatory if you use the module
setting all moves in draft (module: account_default_draft_move)
"""
if not context.get('from_parent_object', False):
self._check_invoice_related_move(cr, uid, ids, vals)
self._check_statement_related_move(cr, uid, ids, vals)
return super(AccountMoveLine, self).write(cr, uid, ids, vals,
context=context,
check=check,
update_check=update_check)
@api.constrains('currency_id', 'amount_currency')
def _check_currency_and_amount(self):
for l in self:
# we check zero amount line
if not (l.debit and l.credit):
continue
if bool(l.currency_id) != bool(l.amount_currency):
raise exceptions.Warning(
_("You cannot create journal items with a secondary "
"currency without recording both 'currency' and "
"'amount currency' field."))
return True
@api.constrains('amount_currency')
def _check_currency_amount(self):
for l in self:
# If account have a second currency, don't apply constraint
if l.account_id.currency_id:
continue
if l.amount_currency:
if ((l.amount_currency > 0.0 and l.credit > 0.0) or
(l.amount_currency < 0.0 and l.debit > 0.0)):
raise exceptions.Warning(
_("The amount expressed in the secondary currency "
"must be positive when journal item are debit and "
"negatif when journal item are credit."))
return True
@api.constrains('currency_id')
def _check_currency_company(self):
for l in self:
if l.currency_id.id == l.company_id.currency_id.id:
raise exceptions.Warning(
_("You can't provide a secondary currency if the same "
"than the company one."))
return True