[MERGE] merged the branch with the improvement of the reconciliation on bank statement (allow to reconcile with existing entries in the bank journal not yet linked to a statement)
This commit is contained in:
@@ -681,7 +681,7 @@ class account_account(osv.osv):
|
||||
return True
|
||||
|
||||
# For legal reason (forbiden to modify journal entries which belongs to a closed fy or period), Forbid to modify
|
||||
# the code of an account if journal entries have been already posted on this account. This cannot be simply
|
||||
# the code of an account if journal entries have been already posted on this account. This cannot be simply
|
||||
# 'configurable' since it can lead to a lack of confidence in Odoo and this is what we want to change.
|
||||
def _check_allow_code_change(self, cr, uid, ids, context=None):
|
||||
line_obj = self.pool.get('account.move.line')
|
||||
@@ -1273,6 +1273,7 @@ class account_move(osv.osv):
|
||||
'narration':fields.text('Internal Note'),
|
||||
'company_id': fields.related('journal_id','company_id',type='many2one',relation='res.company',string='Company', store=True, readonly=True),
|
||||
'balance': fields.float('balance', digits_compute=dp.get_precision('Account'), help="This is a field only used for internal purpose and shouldn't be displayed"),
|
||||
'statement_line_id': fields.many2one('account.bank.statement.line', 'Bank statement line reconciled with this entry', copy=False, readonly=True)
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
@@ -1635,7 +1636,7 @@ class account_move_reconcile(osv.osv):
|
||||
_defaults = {
|
||||
'name': lambda self,cr,uid,ctx=None: self.pool.get('ir.sequence').next_by_code(cr, uid, 'account.reconcile', context=ctx) or '/',
|
||||
}
|
||||
|
||||
|
||||
# You cannot unlink a reconciliation if it is a opening_reconciliation one,
|
||||
# you should use the generate opening entries wizard for that
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
@@ -1644,7 +1645,7 @@ class account_move_reconcile(osv.osv):
|
||||
raise osv.except_osv(_('Error!'), _('You cannot unreconcile journal items if they has been generated by the \
|
||||
opening/closing fiscal year process.'))
|
||||
return super(account_move_reconcile, self).unlink(cr, uid, ids, context=context)
|
||||
|
||||
|
||||
# Look in the line_id and line_partial_ids to ensure the partner is the same or empty
|
||||
# on all lines. We allow that only for opening/closing period
|
||||
def _check_same_partner(self, cr, uid, ids, context=None):
|
||||
@@ -1664,7 +1665,7 @@ class account_move_reconcile(osv.osv):
|
||||
_constraints = [
|
||||
(_check_same_partner, 'You can only reconcile journal items with the same partner.', ['line_id', 'line_partial_ids']),
|
||||
]
|
||||
|
||||
|
||||
def reconcile_partial_check(self, cr, uid, ids, type='auto', context=None):
|
||||
total = 0.0
|
||||
for rec in self.browse(cr, uid, ids, context=context):
|
||||
@@ -3027,7 +3028,7 @@ class wizard_multi_charts_accounts(osv.osv_memory):
|
||||
def _get_chart_parent_ids(self, cr, uid, chart_template, context=None):
|
||||
""" Returns the IDs of all ancestor charts, including the chart itself.
|
||||
(inverse of child_of operator)
|
||||
|
||||
|
||||
:param browse_record chart_template: the account.chart.template record
|
||||
:return: the IDS of all ancestor charts, including the chart itself.
|
||||
"""
|
||||
@@ -3091,7 +3092,7 @@ class wizard_multi_charts_accounts(osv.osv_memory):
|
||||
if model_data:
|
||||
chart_id = model_data[0]['res_id']
|
||||
chart = account_chart_template.browse(cr, uid, chart_id, context=context)
|
||||
chart_hierarchy_ids = self._get_chart_parent_ids(cr, uid, chart, context=context)
|
||||
chart_hierarchy_ids = self._get_chart_parent_ids(cr, uid, chart, context=context)
|
||||
if 'chart_template_id' in fields:
|
||||
res.update({'only_one_chart_template': len(ids) == 1,
|
||||
'chart_template_id': chart_id})
|
||||
@@ -3405,7 +3406,7 @@ class wizard_multi_charts_accounts(osv.osv_memory):
|
||||
for ref in (('product','list_price'),('product','standard_price'),('product','list0'),('purchase','list0')):
|
||||
try:
|
||||
tmp2 = obj_data.get_object_reference(cr, uid, *ref)
|
||||
if tmp2:
|
||||
if tmp2:
|
||||
self.pool[tmp2[0]].write(cr, uid, tmp2[1], {
|
||||
'currency_id': obj_wizard.currency_id.id
|
||||
})
|
||||
|
||||
@@ -19,12 +19,13 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.osv import fields, osv
|
||||
from openerp.osv import fields, osv, expression
|
||||
from openerp.tools.translate import _
|
||||
import openerp.addons.decimal_precision as dp
|
||||
from openerp.report import report_sxw
|
||||
from openerp.tools import float_compare, float_round
|
||||
|
||||
from operator import add
|
||||
import time
|
||||
|
||||
class account_bank_statement(osv.osv):
|
||||
@@ -108,7 +109,7 @@ class account_bank_statement(osv.osv):
|
||||
def _all_lines_reconciled(self, cr, uid, ids, name, args, context=None):
|
||||
res = {}
|
||||
for statement in self.browse(cr, uid, ids, context=context):
|
||||
res[statement.id] = all([line.journal_entry_id.id for line in statement.line_ids])
|
||||
res[statement.id] = all([line.journal_entry_ids.ids for line in statement.line_ids])
|
||||
return res
|
||||
|
||||
_order = "date desc, id desc"
|
||||
@@ -161,7 +162,7 @@ class account_bank_statement(osv.osv):
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'name': '/',
|
||||
'name': '/',
|
||||
'date': fields.date.context_today,
|
||||
'state': 'draft',
|
||||
'journal_id': _default_journal_id,
|
||||
@@ -215,6 +216,7 @@ class account_bank_statement(osv.osv):
|
||||
:return: dict of value to create() the account.move
|
||||
"""
|
||||
return {
|
||||
'statement_line_id': st_line.id,
|
||||
'journal_id': st_line.statement_id.journal_id.id,
|
||||
'period_id': st_line.statement_id.period_id.id,
|
||||
'date': st_line.date,
|
||||
@@ -240,28 +242,40 @@ class account_bank_statement(osv.osv):
|
||||
"""
|
||||
return st_line.partner_id and st_line.partner_id.id or False
|
||||
|
||||
def _prepare_bank_move_line(self, cr, uid, st_line, move_id, amount, company_currency_id, context=None):
|
||||
def _prepare_bank_move_line(self, cr, uid, st_line, move_id, amount, company_currency, context=None):
|
||||
"""Compute the args to build the dict of values to create the counter part move line from a
|
||||
statement line by calling the _prepare_move_line_vals.
|
||||
statement line by calling the _prepare_move_line_vals.
|
||||
|
||||
:param browse_record st_line: account.bank.statement.line record to create the move from.
|
||||
:param int/long move_id: ID of the account.move to link the move line
|
||||
:param float amount: amount of the move line
|
||||
:param int/long company_currency_id: ID of currency of the concerned company
|
||||
:param browse_record company_currency: res.currency record of the concerned company
|
||||
:return: dict of value to create() the bank account.move.line
|
||||
"""
|
||||
currency_obj = self.pool.get('res.currency')
|
||||
if context is None:
|
||||
context = {}
|
||||
ctx = context.copy()
|
||||
ctx['date'] = st_line.date
|
||||
account_id = self._get_counter_part_account(cr, uid, st_line, context=context)
|
||||
partner_id = self._get_counter_part_partner(cr, uid, st_line, context=context)
|
||||
debit = ((amount > 0) and amount) or 0.0
|
||||
credit = ((amount < 0) and -amount) or 0.0
|
||||
cur_id = False
|
||||
amt_cur = False
|
||||
if st_line.statement_id.currency.id != company_currency_id:
|
||||
amt_cur = st_line.amount
|
||||
cur_id = st_line.statement_id.currency.id
|
||||
elif st_line.currency_id and st_line.amount_currency:
|
||||
amt_cur = st_line.amount_currency
|
||||
cur_id = st_line.currency_id.id
|
||||
if st_line.statement_id.currency.id != company_currency.id or (st_line.currency_id and st_line.amount_currency):
|
||||
#the amount given is in foreign currency and needs to be converted at the ratio of the transaction
|
||||
st_line_currency_rate = st_line.currency_id and (st_line.amount_currency / st_line.amount) or 1
|
||||
if st_line.currency_id != company_currency:
|
||||
debit = currency_obj.round(cr, uid, company_currency, debit / st_line_currency_rate)
|
||||
credit = currency_obj.round(cr, uid, company_currency, credit / st_line_currency_rate)
|
||||
amt_cur = amount
|
||||
if st_line.statement_id.currency != company_currency:
|
||||
amt_cur = amount / st_line_currency_rate
|
||||
cur_id = st_line.statement_id.currency.id != company_currency.id and st_line.statement_id.currency.id or st_line.currency_id.id
|
||||
if st_line.statement_id.currency.id != company_currency.id and st_line.currency_id != company_currency:
|
||||
debit = currency_obj.compute(cr, uid, st_line.statement_id.currency.id, company_currency.id, debit, context=ctx)
|
||||
credit = currency_obj.compute(cr, uid, st_line.statement_id.currency.id, company_currency.id, credit, context=ctx)
|
||||
return self._prepare_move_line_vals(cr, uid, st_line, move_id, debit, credit,
|
||||
amount_currency=amt_cur, currency_id=cur_id, account_id=account_id,
|
||||
partner_id=partner_id, context=context)
|
||||
@@ -335,7 +349,7 @@ class account_bank_statement(osv.osv):
|
||||
for st_line in st.line_ids:
|
||||
if not st_line.amount:
|
||||
continue
|
||||
if st_line.account_id and not st_line.journal_entry_id.id:
|
||||
if st_line.account_id and not st_line.journal_entry_ids.ids:
|
||||
#make an account move as before
|
||||
vals = {
|
||||
'debit': st_line.amount < 0 and -st_line.amount or 0.0,
|
||||
@@ -344,9 +358,9 @@ class account_bank_statement(osv.osv):
|
||||
'name': st_line.name
|
||||
}
|
||||
self.pool.get('account.bank.statement.line').process_reconciliation(cr, uid, st_line.id, [vals], context=context)
|
||||
elif not st_line.journal_entry_id.id:
|
||||
elif not st_line.journal_entry_ids.ids:
|
||||
raise osv.except_osv(_('Error!'), _('All the account entries lines must be processed in order to close the statement.'))
|
||||
move_ids.append(st_line.journal_entry_id.id)
|
||||
move_ids += st_line.journal_entry_ids.ids
|
||||
if move_ids:
|
||||
self.pool.get('account.move').post(cr, uid, move_ids, context=context)
|
||||
self.message_post(cr, uid, [st.id], body=_('Statement %s confirmed, journal items were created.') % (st.name,), context=context)
|
||||
@@ -388,7 +402,7 @@ class account_bank_statement(osv.osv):
|
||||
for item in self.browse(cr, uid, ids, context=context):
|
||||
if item.state != 'draft':
|
||||
raise osv.except_osv(
|
||||
_('Invalid Action!'),
|
||||
_('Invalid Action!'),
|
||||
_('In order to delete a bank statement, you must first cancel it to delete related journal items.')
|
||||
)
|
||||
# Explicitly unlink bank statement lines
|
||||
@@ -413,7 +427,7 @@ class account_bank_statement(osv.osv):
|
||||
|
||||
def number_of_lines_reconciled(self, cr, uid, ids, context=None):
|
||||
bsl_obj = self.pool.get('account.bank.statement.line')
|
||||
return bsl_obj.search_count(cr, uid, [('statement_id', 'in', ids), ('journal_entry_id', '!=', False)], context=context)
|
||||
return bsl_obj.search_count(cr, uid, [('statement_id', 'in', ids), ('journal_entry_ids', '!=', [])], context=context)
|
||||
|
||||
def link_bank_to_partner(self, cr, uid, ids, context=None):
|
||||
for statement in self.browse(cr, uid, ids, context=context):
|
||||
@@ -430,9 +444,9 @@ class account_bank_statement_line(osv.osv):
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
for item in self.browse(cr, uid, ids, context=context):
|
||||
if item.journal_entry_id:
|
||||
if item.journal_entry_ids:
|
||||
raise osv.except_osv(
|
||||
_('Invalid Action!'),
|
||||
_('Invalid Action!'),
|
||||
_('In order to delete a bank statement line, you must first cancel it to delete related journal items.')
|
||||
)
|
||||
return super(account_bank_statement_line, self).unlink(cr, uid, ids, context=context)
|
||||
@@ -441,15 +455,17 @@ class account_bank_statement_line(osv.osv):
|
||||
account_move_obj = self.pool.get('account.move')
|
||||
move_ids = []
|
||||
for line in self.browse(cr, uid, ids, context=context):
|
||||
if line.journal_entry_id:
|
||||
move_ids.append(line.journal_entry_id.id)
|
||||
for aml in line.journal_entry_id.line_id:
|
||||
if aml.reconcile_id:
|
||||
move_lines = [l.id for l in aml.reconcile_id.line_id]
|
||||
move_lines.remove(aml.id)
|
||||
self.pool.get('account.move.reconcile').unlink(cr, uid, [aml.reconcile_id.id], context=context)
|
||||
if len(move_lines) >= 2:
|
||||
self.pool.get('account.move.line').reconcile_partial(cr, uid, move_lines, 'auto', context=context)
|
||||
if line.journal_entry_ids.ids :
|
||||
move_ids += line.journal_entry_ids.ids
|
||||
account_move_obj.write(cr, uid, move_ids, {'statement_line_id': False}, context=context)
|
||||
for move in account_move_obj.browse(cr, uid, move_ids, context=context):
|
||||
for aml in move.line_id:
|
||||
if aml.reconcile_id:
|
||||
move_lines = [l.id for l in aml.reconcile_id.line_id]
|
||||
move_lines.remove(aml.id)
|
||||
self.pool.get('account.move.reconcile').unlink(cr, uid, [aml.reconcile_id.id], context=context)
|
||||
if len(move_lines) >= 2:
|
||||
self.pool.get('account.move.line').reconcile_partial(cr, uid, move_lines, 'auto', context=context)
|
||||
if move_ids:
|
||||
account_move_obj.button_cancel(cr, uid, move_ids, context=context)
|
||||
account_move_obj.unlink(cr, uid, move_ids, context)
|
||||
@@ -575,10 +591,8 @@ class account_bank_statement_line(osv.osv):
|
||||
return []
|
||||
|
||||
# Look for a set of move line whose amount is <= to the line's amount
|
||||
if amount > 0: # Make sure we can't mix receivable and payable
|
||||
domain += [('account_id.type', '=', 'receivable')]
|
||||
else:
|
||||
domain += [('account_id.type', '=', 'payable')]
|
||||
domain += [('reconcile_id', '=', False)]
|
||||
domain += [('account_id.type', '=', (amount > 0 and 'receivable' or 'payable'))] # Make sure we can't mix receivable and payable
|
||||
if amount_field == 'amount_currency' and amount < 0:
|
||||
domain += [(amount_field, '<', 0), (amount_field, '>', (sign * amount))]
|
||||
else:
|
||||
@@ -608,29 +622,38 @@ class account_bank_statement_line(osv.osv):
|
||||
excluded_ids = []
|
||||
if additional_domain is None:
|
||||
additional_domain = []
|
||||
# Make domain
|
||||
domain = additional_domain + [
|
||||
('reconcile_id', '=', False),
|
||||
('state', '=', 'valid'),
|
||||
('account_id.reconcile', '=', True)
|
||||
]
|
||||
else:
|
||||
additional_domain = expression.normalize_domain(additional_domain)
|
||||
|
||||
# Domain to fetch reconciled move lines (use case where you register a payment before you get the bank statement)
|
||||
domain_rapprochement = ['&', ('statement_id', '=', False), ('account_id', 'in', [st_line.journal_id.default_credit_account_id.id, st_line.journal_id.default_debit_account_id.id])]
|
||||
|
||||
# Domain to fetch unreconciled move lines (the bank reconciliation process will create a payment journal entry to reconcile with)
|
||||
domain_reconciliation = [('reconcile_id', '=', False)]
|
||||
if st_line.partner_id.id:
|
||||
domain += [('partner_id', '=', st_line.partner_id.id)]
|
||||
domain_reconciliation = expression.AND([domain_reconciliation, [('account_id.type', 'in', ['payable', 'receivable'])]])
|
||||
else:
|
||||
domain_reconciliation = expression.AND([domain_reconciliation, [('account_id.reconcile', '=', True)]])
|
||||
|
||||
# Let's add what applies to both
|
||||
domain = expression.OR([domain_rapprochement, domain_reconciliation])
|
||||
domain = expression.AND([domain, [('state', '=', 'valid')]])
|
||||
if st_line.partner_id.id:
|
||||
domain = expression.AND([domain, [('partner_id', '=', st_line.partner_id.id)]])
|
||||
if excluded_ids:
|
||||
domain.append(('id', 'not in', excluded_ids))
|
||||
domain = expression.AND([domain, [('id', 'not in', excluded_ids)]])
|
||||
if str:
|
||||
domain += [
|
||||
str_domain = [
|
||||
'|', ('move_id.name', 'ilike', str),
|
||||
'|', ('move_id.ref', 'ilike', str),
|
||||
('date_maturity', 'like', str),
|
||||
'|', ('date_maturity', 'like', str),
|
||||
'&', ('name', '!=', '/'), ('name', 'ilike', str)
|
||||
]
|
||||
if not st_line.partner_id.id:
|
||||
domain.insert(-1, '|', )
|
||||
domain.append(('partner_id.name', 'ilike', str))
|
||||
if str != '/':
|
||||
domain.insert(-1, '|', )
|
||||
domain.append(('name', 'ilike', str))
|
||||
return domain
|
||||
str_domain = expression.OR([str_domain, [('partner_id.name', 'ilike', str)]])
|
||||
domain = expression.AND([domain, str_domain])
|
||||
|
||||
return expression.AND([additional_domain, domain])
|
||||
|
||||
def get_move_lines_for_reconciliation(self, cr, uid, st_line, excluded_ids=None, str=False, offset=0, limit=None, count=False, additional_domain=None, context=None):
|
||||
""" Find the move lines that could be used to reconcile a statement line. If count is true, only returns the count.
|
||||
@@ -642,7 +665,7 @@ class account_bank_statement_line(osv.osv):
|
||||
"""
|
||||
mv_line_pool = self.pool.get('account.move.line')
|
||||
domain = self._domain_move_lines_for_reconciliation(cr, uid, st_line, excluded_ids=excluded_ids, str=str, additional_domain=additional_domain, context=context)
|
||||
|
||||
|
||||
# Get move lines ; in case of a partial reconciliation, only consider one line
|
||||
filtered_lines = []
|
||||
reconcile_partial_ids = []
|
||||
@@ -708,7 +731,8 @@ class account_bank_statement_line(osv.osv):
|
||||
self.process_reconciliation(cr, uid, datum[0], datum[1], context=context)
|
||||
|
||||
def process_reconciliation(self, cr, uid, id, mv_line_dicts, context=None):
|
||||
""" Creates a move line for each item of mv_line_dicts and for the statement line. Reconcile a new move line with its counterpart_move_line_id if specified. Finally, mark the statement line as reconciled by putting the newly created move id in the column journal_entry_id.
|
||||
""" Creates a move line for each item of mv_line_dicts and for the statement line. Reconcile a new move line with its counterpart_move_line_id if specified.
|
||||
Finally, mark the statement line as reconciled by putting the reconciled moves ids in the column journal_entry_ids.
|
||||
|
||||
:param int id: id of the bank statement line
|
||||
:param list of dicts mv_line_dicts: move lines to create. If counterpart_move_line_id is specified, reconcile with it
|
||||
@@ -724,7 +748,7 @@ class account_bank_statement_line(osv.osv):
|
||||
currency_obj = self.pool.get('res.currency')
|
||||
|
||||
# Checks
|
||||
if st_line.journal_entry_id.id:
|
||||
if st_line.journal_entry_ids.ids:
|
||||
raise osv.except_osv(_('Error!'), _('The bank statement line was already reconciled.'))
|
||||
for mv_line_dict in mv_line_dicts:
|
||||
for field in ['debit', 'credit', 'amount_currency']:
|
||||
@@ -735,118 +759,125 @@ class account_bank_statement_line(osv.osv):
|
||||
if mv_line.reconcile_id:
|
||||
raise osv.except_osv(_('Error!'), _('A selected move line was already reconciled.'))
|
||||
|
||||
# Create the move
|
||||
move_name = (st_line.statement_id.name or st_line.name) + "/" + str(st_line.sequence)
|
||||
move_vals = bs_obj._prepare_move(cr, uid, st_line, move_name, context=context)
|
||||
move_id = am_obj.create(cr, uid, move_vals, context=context)
|
||||
# When the move line is already paid (fully reconciled move), we just link them to the bank statement
|
||||
to_reconcile_mv_line_ids = [x['counterpart_move_line_id'] for x in mv_line_dicts if x.get('already_paid', False)]
|
||||
if to_reconcile_mv_line_ids:
|
||||
aml_obj.write(cr, uid, to_reconcile_mv_line_ids, {'statement_id': st_line.statement_id.id}, context=context)
|
||||
for aml in aml_obj.browse(cr, uid, to_reconcile_mv_line_ids, context=context):
|
||||
am_obj.write(cr, uid, aml.move_id.id, {'statement_line_id': st_line.id}, context=context)
|
||||
|
||||
# Create the move line for the statement line
|
||||
if st_line.statement_id.currency.id != company_currency.id:
|
||||
if st_line.currency_id == company_currency:
|
||||
amount = st_line.amount_currency
|
||||
else:
|
||||
ctx = context.copy()
|
||||
ctx['date'] = st_line.date
|
||||
amount = currency_obj.compute(cr, uid, st_line.statement_id.currency.id, company_currency.id, st_line.amount, context=ctx)
|
||||
else:
|
||||
amount = st_line.amount
|
||||
bank_st_move_vals = bs_obj._prepare_bank_move_line(cr, uid, st_line, move_id, amount, company_currency.id, context=context)
|
||||
aml_obj.create(cr, uid, bank_st_move_vals, context=context)
|
||||
# Complete the dicts
|
||||
st_line_currency = st_line.currency_id or statement_currency
|
||||
st_line_currency_rate = st_line.currency_id and (st_line.amount_currency / st_line.amount) or False
|
||||
to_create = []
|
||||
for mv_line_dict in mv_line_dicts:
|
||||
if mv_line_dict.get('is_tax_line'):
|
||||
continue
|
||||
mv_line_dict['ref'] = move_name
|
||||
mv_line_dict['move_id'] = move_id
|
||||
mv_line_dict['period_id'] = st_line.statement_id.period_id.id
|
||||
mv_line_dict['journal_id'] = st_line.journal_id.id
|
||||
mv_line_dict['company_id'] = st_line.company_id.id
|
||||
mv_line_dict['statement_id'] = st_line.statement_id.id
|
||||
if mv_line_dict.get('counterpart_move_line_id'):
|
||||
mv_line = aml_obj.browse(cr, uid, mv_line_dict['counterpart_move_line_id'], context=context)
|
||||
mv_line_dict['partner_id'] = mv_line.partner_id.id or st_line.partner_id.id
|
||||
mv_line_dict['account_id'] = mv_line.account_id.id
|
||||
if mv_line.currency_id:
|
||||
ctx = context.copy()
|
||||
ctx['date'] = mv_line.date
|
||||
mv_line_dict['amount_currency'] = currency_obj.compute(cr, uid, company_currency.id, mv_line.currency_id.id, mv_line_dict['debit'] - mv_line_dict['credit'], context=ctx)
|
||||
mv_line_dict['currency_id'] = mv_line.currency_id.id
|
||||
if st_line_currency.id != company_currency.id:
|
||||
ctx = context.copy()
|
||||
ctx['date'] = st_line.date
|
||||
mv_line_dict['amount_currency'] = mv_line_dict['debit'] - mv_line_dict['credit']
|
||||
mv_line_dict['currency_id'] = st_line_currency.id
|
||||
if st_line.currency_id and statement_currency.id == company_currency.id and st_line_currency_rate:
|
||||
debit_at_current_rate = self.pool.get('res.currency').round(cr, uid, company_currency, mv_line_dict['debit'] / st_line_currency_rate)
|
||||
credit_at_current_rate = self.pool.get('res.currency').round(cr, uid, company_currency, mv_line_dict['credit'] / st_line_currency_rate)
|
||||
elif st_line.currency_id and st_line_currency_rate:
|
||||
debit_at_current_rate = currency_obj.compute(cr, uid, statement_currency.id, company_currency.id, mv_line_dict['debit'] / st_line_currency_rate, context=ctx)
|
||||
credit_at_current_rate = currency_obj.compute(cr, uid, statement_currency.id, company_currency.id, mv_line_dict['credit'] / st_line_currency_rate, context=ctx)
|
||||
else:
|
||||
debit_at_current_rate = currency_obj.compute(cr, uid, st_line_currency.id, company_currency.id, mv_line_dict['debit'], context=ctx)
|
||||
credit_at_current_rate = currency_obj.compute(cr, uid, st_line_currency.id, company_currency.id, mv_line_dict['credit'], context=ctx)
|
||||
# Otherwise, we create a move line. Either matching an existing journal entry (eg. invoice), in which
|
||||
# case we reconcile the existing and the new move lines together, or being a write-off.
|
||||
to_create_mv_line_dicts = [x for x in mv_line_dicts if not x.get('already_paid', False)]
|
||||
if to_create_mv_line_dicts:
|
||||
|
||||
# Create the move
|
||||
move_name = (st_line.statement_id.name or st_line.name) + "/" + str(st_line.sequence)
|
||||
move_vals = bs_obj._prepare_move(cr, uid, st_line, move_name, context=context)
|
||||
move_id = am_obj.create(cr, uid, move_vals, context=context)
|
||||
|
||||
# Create the move line for the statement line
|
||||
st_line_amount = reduce(add, [x['credit'] - x['debit'] for x in to_create_mv_line_dicts])
|
||||
bank_st_move_vals = bs_obj._prepare_bank_move_line(cr, uid, st_line, move_id, st_line_amount, company_currency, context=context)
|
||||
aml_obj.create(cr, uid, bank_st_move_vals, context=context)
|
||||
|
||||
# Complete the dicts
|
||||
st_line_currency = st_line.currency_id or statement_currency
|
||||
st_line_currency_rate = st_line.currency_id and (st_line.amount_currency / st_line.amount) or 1
|
||||
to_create = []
|
||||
for mv_line_dict in to_create_mv_line_dicts:
|
||||
mv_line_dict.pop('already_paid', None)
|
||||
mv_line_dict['ref'] = move_name
|
||||
mv_line_dict['move_id'] = move_id
|
||||
mv_line_dict['period_id'] = st_line.statement_id.period_id.id
|
||||
mv_line_dict['journal_id'] = st_line.journal_id.id
|
||||
mv_line_dict['company_id'] = st_line.company_id.id
|
||||
mv_line_dict['statement_id'] = st_line.statement_id.id
|
||||
if mv_line_dict.get('counterpart_move_line_id'):
|
||||
#post an account line that use the same currency rate than the counterpart (to balance the account) and post the difference in another line
|
||||
ctx['date'] = mv_line.date
|
||||
debit_at_old_rate = currency_obj.compute(cr, uid, st_line_currency.id, company_currency.id, mv_line_dict['debit'], context=ctx)
|
||||
credit_at_old_rate = currency_obj.compute(cr, uid, st_line_currency.id, company_currency.id, mv_line_dict['credit'], context=ctx)
|
||||
mv_line_dict['credit'] = credit_at_old_rate
|
||||
mv_line_dict['debit'] = debit_at_old_rate
|
||||
if debit_at_old_rate - debit_at_current_rate:
|
||||
currency_diff = debit_at_current_rate - debit_at_old_rate
|
||||
to_create.append(self.get_currency_rate_line(cr, uid, st_line, -currency_diff, move_id, context=context))
|
||||
if credit_at_old_rate - credit_at_current_rate:
|
||||
currency_diff = credit_at_current_rate - credit_at_old_rate
|
||||
to_create.append(self.get_currency_rate_line(cr, uid, st_line, currency_diff, move_id, context=context))
|
||||
else:
|
||||
mv_line_dict['debit'] = debit_at_current_rate
|
||||
mv_line_dict['credit'] = credit_at_current_rate
|
||||
elif statement_currency.id != company_currency.id:
|
||||
#statement is in foreign currency but the transaction is in company currency
|
||||
prorata_factor = (mv_line_dict['debit'] - mv_line_dict['credit']) / st_line.amount_currency
|
||||
mv_line_dict['amount_currency'] = prorata_factor * st_line.amount
|
||||
if mv_line_dict.get('counterpart_move_line_id'):
|
||||
counterpart_line = aml_obj.browse(cr, uid, mv_line_dict['counterpart_move_line_id'], context=context)
|
||||
if counterpart_line.currency_id and counterpart_line.currency_id.id == statement_currency.id:
|
||||
#post an account line that use the same currency rate than the counterpart (to balance the account) and post the difference in another line
|
||||
mv_line = aml_obj.browse(cr, uid, mv_line_dict['counterpart_move_line_id'], context=context)
|
||||
mv_line_dict['partner_id'] = mv_line.partner_id.id or st_line.partner_id.id
|
||||
mv_line_dict['account_id'] = mv_line.account_id.id
|
||||
if mv_line.currency_id:
|
||||
ctx = context.copy()
|
||||
ctx['date'] = mv_line.date
|
||||
debit_at_old_rate = mv_line_dict['amount_currency'] > 0 and currency_obj.compute(cr, uid, statement_currency.id, company_currency.id, mv_line_dict['amount_currency'], context=ctx) or 0.0
|
||||
credit_at_old_rate = mv_line_dict['amount_currency'] < 0 and currency_obj.compute(cr, uid, statement_currency.id, company_currency.id, -mv_line_dict['amount_currency'], context=ctx) or 0.0
|
||||
if debit_at_old_rate - mv_line_dict['debit']:
|
||||
currency_diff = mv_line_dict['debit'] - debit_at_old_rate
|
||||
to_create.append(self.get_currency_rate_line(cr, uid, st_line, -currency_diff, move_id, context=context))
|
||||
if credit_at_old_rate - mv_line_dict['credit']:
|
||||
currency_diff = mv_line_dict['credit'] - credit_at_old_rate
|
||||
to_create.append(self.get_currency_rate_line(cr, uid, st_line, currency_diff, move_id, context=context))
|
||||
mv_line_dict['debit'] = debit_at_old_rate
|
||||
mv_line_dict['amount_currency'] = currency_obj.compute(cr, uid, company_currency.id, mv_line.currency_id.id, mv_line_dict['debit'] - mv_line_dict['credit'], context=ctx)
|
||||
mv_line_dict['currency_id'] = mv_line.currency_id.id
|
||||
if st_line_currency.id != company_currency.id:
|
||||
ctx = context.copy()
|
||||
ctx['date'] = st_line.date
|
||||
mv_line_dict['amount_currency'] = mv_line_dict['debit'] - mv_line_dict['credit']
|
||||
mv_line_dict['currency_id'] = st_line_currency.id
|
||||
if st_line.currency_id and statement_currency.id == company_currency.id:
|
||||
#statement is in company currency but the transaction is in foreign currency
|
||||
debit_at_current_rate = self.pool.get('res.currency').round(cr, uid, company_currency, mv_line_dict['debit'] / st_line_currency_rate)
|
||||
credit_at_current_rate = self.pool.get('res.currency').round(cr, uid, company_currency, mv_line_dict['credit'] / st_line_currency_rate)
|
||||
elif st_line.currency_id:
|
||||
#statement is in foreign currency and the transaction is in another one
|
||||
debit_at_current_rate = currency_obj.compute(cr, uid, statement_currency.id, company_currency.id, mv_line_dict['debit'] / st_line_currency_rate, context=ctx)
|
||||
credit_at_current_rate = currency_obj.compute(cr, uid, statement_currency.id, company_currency.id, mv_line_dict['credit'] / st_line_currency_rate, context=ctx)
|
||||
else:
|
||||
#statement is in foreign currency and no extra currency is given for the transaction
|
||||
debit_at_current_rate = currency_obj.compute(cr, uid, st_line_currency.id, company_currency.id, mv_line_dict['debit'] / st_line_currency_rate, context=ctx)
|
||||
credit_at_current_rate = currency_obj.compute(cr, uid, st_line_currency.id, company_currency.id, mv_line_dict['credit'] / st_line_currency_rate, context=ctx)
|
||||
if mv_line_dict.get('counterpart_move_line_id'):
|
||||
#post an account line that use the same currency rate than the counterpart (to balance the account) and post the difference in another line
|
||||
ctx['date'] = mv_line.date
|
||||
debit_at_old_rate = currency_obj.compute(cr, uid, st_line_currency.id, company_currency.id, mv_line_dict['debit'], context=ctx)
|
||||
credit_at_old_rate = currency_obj.compute(cr, uid, st_line_currency.id, company_currency.id, mv_line_dict['credit'], context=ctx)
|
||||
mv_line_dict['credit'] = credit_at_old_rate
|
||||
to_create.append(mv_line_dict)
|
||||
# Create move lines
|
||||
move_line_pairs_to_reconcile = []
|
||||
for mv_line_dict in to_create:
|
||||
counterpart_move_line_id = None # NB : this attribute is irrelevant for aml_obj.create() and needs to be removed from the dict
|
||||
if mv_line_dict.get('counterpart_move_line_id'):
|
||||
counterpart_move_line_id = mv_line_dict['counterpart_move_line_id']
|
||||
del mv_line_dict['counterpart_move_line_id']
|
||||
new_aml_id = aml_obj.create(cr, uid, mv_line_dict, context=context)
|
||||
if counterpart_move_line_id != None:
|
||||
move_line_pairs_to_reconcile.append([new_aml_id, counterpart_move_line_id])
|
||||
# Reconcile
|
||||
for pair in move_line_pairs_to_reconcile:
|
||||
aml_obj.reconcile_partial(cr, uid, pair, context=context)
|
||||
# Mark the statement line as reconciled
|
||||
self.write(cr, uid, id, {'journal_entry_id': move_id}, context=context)
|
||||
mv_line_dict['debit'] = debit_at_old_rate
|
||||
if debit_at_old_rate - debit_at_current_rate:
|
||||
currency_diff = debit_at_current_rate - debit_at_old_rate
|
||||
to_create.append(self.get_currency_rate_line(cr, uid, st_line, -currency_diff, move_id, context=context))
|
||||
if credit_at_old_rate - credit_at_current_rate:
|
||||
currency_diff = credit_at_current_rate - credit_at_old_rate
|
||||
to_create.append(self.get_currency_rate_line(cr, uid, st_line, currency_diff, move_id, context=context))
|
||||
else:
|
||||
mv_line_dict['debit'] = debit_at_current_rate
|
||||
mv_line_dict['credit'] = credit_at_current_rate
|
||||
elif statement_currency.id != company_currency.id:
|
||||
#statement is in foreign currency but the transaction is in company currency
|
||||
prorata_factor = (mv_line_dict['debit'] - mv_line_dict['credit']) / st_line.amount_currency
|
||||
mv_line_dict['amount_currency'] = prorata_factor * st_line.amount
|
||||
if mv_line_dict.get('counterpart_move_line_id'):
|
||||
counterpart_line = aml_obj.browse(cr, uid, mv_line_dict['counterpart_move_line_id'], context=context)
|
||||
if counterpart_line.currency_id and counterpart_line.currency_id.id == statement_currency.id:
|
||||
#post an account line that use the same currency rate than the counterpart (to balance the account) and post the difference in another line
|
||||
ctx = context.copy()
|
||||
ctx['date'] = mv_line.date
|
||||
debit_at_old_rate = mv_line_dict['amount_currency'] > 0 and currency_obj.compute(cr, uid, statement_currency.id, company_currency.id, mv_line_dict['amount_currency'], context=ctx) or 0.0
|
||||
credit_at_old_rate = mv_line_dict['amount_currency'] < 0 and currency_obj.compute(cr, uid, statement_currency.id, company_currency.id, -mv_line_dict['amount_currency'], context=ctx) or 0.0
|
||||
if debit_at_old_rate - mv_line_dict['debit']:
|
||||
currency_diff = mv_line_dict['debit'] - debit_at_old_rate
|
||||
to_create.append(self.get_currency_rate_line(cr, uid, st_line, -currency_diff, move_id, context=context))
|
||||
if credit_at_old_rate - mv_line_dict['credit']:
|
||||
currency_diff = mv_line_dict['credit'] - credit_at_old_rate
|
||||
to_create.append(self.get_currency_rate_line(cr, uid, st_line, currency_diff, move_id, context=context))
|
||||
mv_line_dict['debit'] = debit_at_old_rate
|
||||
mv_line_dict['credit'] = credit_at_old_rate
|
||||
to_create.append(mv_line_dict)
|
||||
|
||||
# Create move lines
|
||||
move_line_pairs_to_reconcile = []
|
||||
for mv_line_dict in to_create:
|
||||
counterpart_move_line_id = None # NB : this attribute is irrelevant for aml_obj.create() and needs to be removed from the dict
|
||||
if mv_line_dict.get('counterpart_move_line_id'):
|
||||
counterpart_move_line_id = mv_line_dict['counterpart_move_line_id']
|
||||
del mv_line_dict['counterpart_move_line_id']
|
||||
new_aml_id = aml_obj.create(cr, uid, mv_line_dict, context=context)
|
||||
if counterpart_move_line_id != None:
|
||||
move_line_pairs_to_reconcile.append([new_aml_id, counterpart_move_line_id])
|
||||
|
||||
# Reconcile
|
||||
for pair in move_line_pairs_to_reconcile:
|
||||
aml_obj.reconcile_partial(cr, uid, pair, context=context)
|
||||
|
||||
# FIXME : if it wasn't for the multicompany security settings in account_security.xml, the method would just
|
||||
# return [('journal_entry_id', '=', False)]
|
||||
# return [('journal_entry_ids', '!=', True)]
|
||||
# Unfortunately, that spawns a "no access rights" error ; it shouldn't.
|
||||
def _needaction_domain_get(self, cr, uid, context=None):
|
||||
user = self.pool.get("res.users").browse(cr, uid, uid)
|
||||
return ['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id]), ('journal_entry_id', '=', False)]
|
||||
return ['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id]), ('journal_entry_ids', '=', False)]
|
||||
|
||||
_order = "statement_id desc, sequence"
|
||||
_name = "account.bank.statement.line"
|
||||
@@ -866,7 +897,7 @@ class account_bank_statement_line(osv.osv):
|
||||
'note': fields.text('Notes'),
|
||||
'sequence': fields.integer('Sequence', select=True, help="Gives the sequence order when displaying a list of bank statement lines."),
|
||||
'company_id': fields.related('statement_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True),
|
||||
'journal_entry_id': fields.many2one('account.move', 'Journal Entry', copy=False),
|
||||
'journal_entry_ids': fields.one2many('account.move', 'statement_line_id', 'Journal Entries', copy=False, readonly=True),
|
||||
'amount_currency': fields.float('Amount Currency', help="The amount expressed in an optional other currency if it is a multi-currency entry.", digits_compute=dp.get_precision('Account')),
|
||||
'currency_id': fields.many2one('res.currency', 'Currency', help="The optional other currency if it is a multi-currency entry."),
|
||||
}
|
||||
|
||||
@@ -758,7 +758,7 @@ class account_move_line(osv.osv):
|
||||
return super(account_move_line, self).search(cr, uid, args, offset, limit, order, context, count)
|
||||
|
||||
def prepare_move_lines_for_reconciliation_widget(self, cr, uid, lines, target_currency=False, target_date=False, context=None):
|
||||
""" Returns move lines formatted for the manual/bank reconciliation widget
|
||||
""" Returns move lines formatted for the bank reconciliation widget
|
||||
|
||||
:param target_currency: curreny you want the move line debit/credit converted into
|
||||
:param target_date: date to use for the monetary conversion
|
||||
@@ -783,6 +783,8 @@ class account_move_line(osv.osv):
|
||||
'id': line.id,
|
||||
'name': line.name != '/' and line.move_id.name + ': ' + line.name or line.move_id.name,
|
||||
'ref': line.move_id.ref,
|
||||
# For reconciliation between statement transactions and already registered payments (eg. checks)
|
||||
'already_paid': line.account_id.type == 'liquidity',
|
||||
'account_code': line.account_id.code,
|
||||
'account_name': line.account_id.name,
|
||||
'account_type': line.account_id.type,
|
||||
@@ -806,6 +808,11 @@ class account_move_line(osv.osv):
|
||||
amount = -amount
|
||||
amount_currency = -amount_currency
|
||||
|
||||
# For already reconciled lines, don't use amount_residual(_currency)
|
||||
if line.account_id.type == 'liquidity':
|
||||
amount = abs(debit - credit)
|
||||
amount_currency = line.amount_currency
|
||||
|
||||
# Get right debit / credit:
|
||||
target_currency = target_currency or company_currency
|
||||
line_currency = line.currency_id or company_currency
|
||||
|
||||
@@ -600,21 +600,21 @@
|
||||
<notebook>
|
||||
<page string="Transactions" name="statement_line_ids">
|
||||
<field name="line_ids" context="{'date':date}">
|
||||
<tree editable="bottom" string="Statement lines" colors="grey:journal_entry_id!=False">
|
||||
<tree editable="bottom" string="Statement lines">
|
||||
<field name="sequence" readonly="1" invisible="1"/>
|
||||
<field name="journal_entry_id" invisible="1"/>
|
||||
<field name="date" attrs="{'readonly' : [('journal_entry_id', '!=', False)] }"/>
|
||||
<field name="name" attrs="{'readonly' : [('journal_entry_id', '!=', False)] }"/>
|
||||
<field name="ref" attrs="{'readonly' : [('journal_entry_id', '!=', False)] }"/>
|
||||
<field name="journal_entry_ids" invisible="1"/>
|
||||
<field name="date" attrs="{'readonly' : [('journal_entry_ids', '!=', [])] }"/>
|
||||
<field name="name" attrs="{'readonly' : [('journal_entry_ids', '!=', [])] }"/>
|
||||
<field name="ref" attrs="{'readonly' : [('journal_entry_ids', '!=', [])] }"/>
|
||||
<field name="partner_id" domain="[
|
||||
'&',
|
||||
'|',('parent_id','=',False),('is_company','=',True),
|
||||
'|',('customer','=',True),('supplier','=',True)]"
|
||||
context="{'default_supplier': 1}"
|
||||
attrs="{'readonly' : [('journal_entry_id', '!=', False)] }"/>
|
||||
<field name="amount" attrs="{'readonly' : [('journal_entry_id', '!=', False)] }"/>
|
||||
<field name="amount_currency" groups="base.group_multi_currency" attrs="{'readonly' : [('journal_entry_id', '!=', False)] }"/>
|
||||
<field name="currency_id" groups="base.group_multi_currency" attrs="{'readonly' : [('journal_entry_id', '!=', False)] }"/>
|
||||
attrs="{'readonly' : [('journal_entry_ids', '!=', [])] }"/>
|
||||
<field name="amount" attrs="{'readonly' : [('journal_entry_ids', '!=', [])] }"/>
|
||||
<field name="amount_currency" groups="base.group_multi_currency" attrs="{'readonly' : [('journal_entry_ids', '!=', [])] }"/>
|
||||
<field name="currency_id" groups="base.group_multi_currency" attrs="{'readonly' : [('journal_entry_ids', '!=', [])] }"/>
|
||||
<field name="bank_account_id" groups="base.group_no_one"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
||||
@@ -167,10 +167,20 @@
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line table.details td:first-child {
|
||||
padding-right: 10px;
|
||||
font-weight: bold; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line table.details tr.one_line_info td {
|
||||
padding-top: 10px;
|
||||
text-align: center;
|
||||
color: #44c; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match table {
|
||||
width: 100%; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match table tr {
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tbody tr, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match table tbody tr {
|
||||
cursor: pointer; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tbody tr.created_line, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match table tbody tr.created_line {
|
||||
cursor: default !important; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tbody tr.created_line .line_remove_button, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match table tbody tr.created_line .line_remove_button {
|
||||
cursor: pointer; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr.already_reconciled, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match table tr.already_reconciled {
|
||||
color: #44c; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view td, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match table td {
|
||||
padding: 1px 8px;
|
||||
vertical-align: middle; }
|
||||
@@ -198,7 +208,7 @@
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr .glyphicon:not(.line_info_button), .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match table tr .glyphicon:not(.line_info_button) {
|
||||
visibility: hidden;
|
||||
color: #555; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr:hover .glyphicon, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr.active .glyphicon, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match table tr:hover .glyphicon, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match table tr.active .glyphicon {
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr:hover .glyphicon, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr:focus .glyphicon, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr.active .glyphicon, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match table tr:hover .glyphicon, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match table tr:focus .glyphicon, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match table tr.active .glyphicon {
|
||||
visibility: visible; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr .do_partial_reconcile_button, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match table tr .do_partial_reconcile_button {
|
||||
color: #f0ad4e;
|
||||
|
||||
@@ -3,6 +3,7 @@ $mainTableBordersPadding: 3px;
|
||||
$lightBorder: 1px solid #bbb;
|
||||
$accountingBorder: 1px solid #000;
|
||||
$initialLineBackground: #f0f0f0;
|
||||
$infoColor: #44c;
|
||||
// Warning, this value is also specified in the instance.web.account.abstractReconciliation widget
|
||||
$aestetic_animation_speed: 300ms;
|
||||
|
||||
@@ -273,16 +274,28 @@ $aestetic_animation_speed: 300ms;
|
||||
padding-right: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
tr.one_line_info {
|
||||
td {
|
||||
padding-top: 10px;
|
||||
text-align: center;
|
||||
color: $infoColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* arrays of move lines */
|
||||
.accounting_view, .match table {
|
||||
width: 100%;
|
||||
|
||||
tr {
|
||||
tbody tr {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
tr.already_reconciled {
|
||||
color: $infoColor;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 1px 8px;
|
||||
vertical-align: middle;
|
||||
@@ -334,7 +347,7 @@ $aestetic_animation_speed: 300ms;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
tr:hover .glyphicon, tr.active .glyphicon {
|
||||
tr:hover .glyphicon, tr:focus .glyphicon, tr.active .glyphicon {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ openerp.account = function (instance) {
|
||||
this._super();
|
||||
var self = this;
|
||||
// Retreive statement infos and reconciliation data from the model
|
||||
var lines_filter = [['journal_entry_id', '=', false], ['account_id', '=', false]];
|
||||
var lines_filter = [['journal_entry_ids', '=', false], ['account_id', '=', false]];
|
||||
var deferred_promises = [];
|
||||
|
||||
// Working on specified statement(s)
|
||||
@@ -688,6 +688,7 @@ openerp.account = function (instance) {
|
||||
this.presets = this.getParent().presets;
|
||||
this.is_valid = true;
|
||||
this.is_consistent = true; // Used to prevent bad server requests
|
||||
this.is_rapprochement; // matching a statement line with an already reconciled journal item
|
||||
this.can_fetch_more_move_lines; // Tell if we can show more move lines
|
||||
this.filter = "";
|
||||
// In rare cases like when deleting a statement line's partner we don't want the server to
|
||||
@@ -1047,12 +1048,12 @@ openerp.account = function (instance) {
|
||||
if (! line) return; // If no line found, we've got a syncing problem (let's turn a deaf ear)
|
||||
|
||||
// Warn the user if he's selecting lines from both a payable and a receivable account
|
||||
var last_selected_line = _.last(self.get("mv_lines_selected"));
|
||||
if (last_selected_line && last_selected_line.account_type != line.account_type) {
|
||||
new instance.web.Dialog(this, {
|
||||
title: _t("Warning"),
|
||||
size: 'medium',
|
||||
}, $("<div />").text(_.str.sprintf(_t("You are selecting transactions from both a payable and a receivable account.\n\nIn order to proceed, you first need to deselect the %s transactions."), last_selected_line.account_type))).open();
|
||||
selected_lines_account_types = _.collect(self.get("mv_lines_selected").concat(line), function(l) { return l.account_type });
|
||||
if (selected_lines_account_types.indexOf("payable") != -1 && selected_lines_account_types.indexOf("receivable") != -1) {
|
||||
new instance.web.CrashManager().show_warning({data: {
|
||||
exception_type: "Incorrect Operation",
|
||||
message: _t("You cannot mix items from receivable and payable accounts.")
|
||||
}});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1305,7 +1306,11 @@ openerp.account = function (instance) {
|
||||
|
||||
// Show or hide partial reconciliation
|
||||
if (self.get("mv_lines_selected").length > 0) {
|
||||
var propose_partial = self.getCreatedLines().length === 0 && self.get("mv_lines_selected").length === 1 && balance_type === "greater" && ! self.get("mv_lines_selected")[0].partial_reconcile;
|
||||
var propose_partial = self.getCreatedLines().length === 0
|
||||
&& self.get("mv_lines_selected").length === 1
|
||||
&& balance_type === "greater"
|
||||
&& ! self.get("mv_lines_selected")[0].partial_reconcile
|
||||
&& ! self.is_rapprochement;
|
||||
self.get("mv_lines_selected")[0].propose_partial_reconcile = propose_partial;
|
||||
self.updateAccountingViewMatchedLines();
|
||||
}
|
||||
@@ -1411,7 +1416,9 @@ openerp.account = function (instance) {
|
||||
|
||||
self.getParent().excludeMoveLines(self, self.partner_id, added_lines);
|
||||
self.getParent().unexcludeMoveLines(self, self.partner_id, removed_lines);
|
||||
|
||||
|
||||
self.is_rapprochement = added_lines.length > 0 && added_lines[0].already_paid;
|
||||
|
||||
$.when(self.updateMatches()).then(function(){
|
||||
self.updateAccountingViewMatchedLines();
|
||||
self.updateBalance();
|
||||
@@ -1575,6 +1582,7 @@ openerp.account = function (instance) {
|
||||
balance = Math.round(balance*1000)/1000;
|
||||
|
||||
self.set("balance", balance);
|
||||
|
||||
},
|
||||
|
||||
// Loads move lines according to the widget's state
|
||||
@@ -1636,6 +1644,7 @@ openerp.account = function (instance) {
|
||||
debit: line.debit,
|
||||
credit: line.credit,
|
||||
counterpart_move_line_id: line.id,
|
||||
already_paid: line.already_paid,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -1649,7 +1658,6 @@ openerp.account = function (instance) {
|
||||
if (amount > 0) dict['credit'] = amount;
|
||||
if (amount < 0) dict['debit'] = -1 * amount;
|
||||
if (line.tax_id) dict['account_tax_id'] = line.tax_id;
|
||||
if (line.is_tax_line) dict['is_tax_line'] = line.is_tax_line;
|
||||
if (line.analytic_account_id) dict['analytic_account_id'] = line.analytic_account_id;
|
||||
|
||||
return dict;
|
||||
@@ -1671,8 +1679,9 @@ openerp.account = function (instance) {
|
||||
makeMoveLineDicts: function() {
|
||||
var self = this;
|
||||
var mv_line_dicts = [];
|
||||
_.each(self.get("mv_lines_selected"), function(o) { mv_line_dicts.push(self.prepareSelectedMoveLineForPersisting(o)) });
|
||||
_.each(self.getCreatedLines(), function(o) { mv_line_dicts.push(self.prepareCreatedMoveLineForPersisting(o)) });
|
||||
_.each(self.get("mv_lines_selected"), function(l) { mv_line_dicts.push(self.prepareSelectedMoveLineForPersisting(l)) });
|
||||
created_lines = _.filter(self.getCreatedLines(), function(l) { return ! l.is_tax_line; }); // Tax lines are created via account_tax_id
|
||||
_.each(self.getCreatedLines(), function(l) { mv_line_dicts.push(self.prepareCreatedMoveLineForPersisting(l)) });
|
||||
if (Math.abs(self.get("balance")).toFixed(3) !== "0.000") mv_line_dicts.push(self.prepareOpenBalanceForPersisting());
|
||||
return mv_line_dicts;
|
||||
},
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
</t>
|
||||
|
||||
<t t-name="bank_statement_reconciliation_move_line">
|
||||
<tr class="mv_line" t-att-data-lineid="line.id" t-att-data-selected="selected">
|
||||
<tr t-att-class="'mv_line'+(line.already_paid ? ' already_reconciled' : '')" t-att-data-lineid="line.id" t-att-data-selected="selected">
|
||||
<td class="cell_action"><span class="glyphicon glyphicon-add-remove"></span></td>
|
||||
<td class="cell_account_code" t-if="line.account_code"><t t-esc="line.account_code"/></td>
|
||||
<td class="cell_due_date"><t t-esc="line.q_due_date"/></td>
|
||||
@@ -186,6 +186,9 @@
|
||||
<t t-if="line.debit !== 0" t-esc="line.debit_str"/><t t-if="line.credit !== 0" t-esc="line.credit_str"/>
|
||||
<t t-if="line.amount_currency_str"> (<t t-esc="line.amount_currency_str"/>)</t>
|
||||
</td></tr>
|
||||
<tr class="one_line_info" t-if='line.already_paid'>
|
||||
<td colspan="2">This payment is registered but not reconciled.</td>
|
||||
</tr>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
<field name="inherit_id" ref="account.view_bank_statement_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='bank_account_id']" position="after">
|
||||
<button name="cancel" attrs="{'invisible': [('journal_entry_id', '=', False)]}" string="Cancel" type="object" icon="gtk-undo"/>
|
||||
<button name="cancel" attrs="{'invisible': [('journal_entry_ids', '=', [])]}" string="Cancel" type="object" icon="gtk-undo"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -1062,10 +1062,7 @@ class account_voucher(osv.osv):
|
||||
else:
|
||||
raise osv.except_osv(_('Error!'),
|
||||
_('Please define a sequence on the journal.'))
|
||||
if not voucher.reference:
|
||||
ref = name.replace('/','')
|
||||
else:
|
||||
ref = voucher.reference
|
||||
ref = voucher.reference or name
|
||||
|
||||
move = {
|
||||
'name': name,
|
||||
|
||||
@@ -1066,15 +1066,15 @@ class expression(object):
|
||||
|
||||
subselect = """WITH temp_irt_current (id, name) as (
|
||||
SELECT ct.id, coalesce(it.value,ct.{quote_left})
|
||||
FROM {current_table} ct
|
||||
LEFT JOIN ir_translation it ON (it.name = %s and
|
||||
it.lang = %s and
|
||||
it.type = %s and
|
||||
it.res_id = ct.id and
|
||||
FROM {current_table} ct
|
||||
LEFT JOIN ir_translation it ON (it.name = %s and
|
||||
it.lang = %s and
|
||||
it.type = %s and
|
||||
it.res_id = ct.id and
|
||||
it.value != '')
|
||||
)
|
||||
)
|
||||
SELECT id FROM temp_irt_current WHERE {name} {operator} {right} order by name
|
||||
""".format(current_table=model._table, quote_left=_quote(left), name=unaccent('name'),
|
||||
""".format(current_table=model._table, quote_left=_quote(left), name=unaccent('name'),
|
||||
operator=sql_operator, right=instr)
|
||||
|
||||
params = (
|
||||
|
||||
Reference in New Issue
Block a user