mirror of
https://github.com/OCA/bank-payment.git
synced 2025-02-02 10:37:31 +02:00
[FIX] show linked invoice on draft statement lines
[FIX] invoice reconciliation shows both full and partial lines [FIX] exception not raised [RFR] write trigger on match wizard invoice selection [ADD] filter invoices for direct debit order by payment term
This commit is contained in:
@@ -542,10 +542,13 @@ class account_bank_statement_line(osv.osv):
|
||||
res = {}
|
||||
for st_line in self.browse(cr, uid, ids, context):
|
||||
res[st_line.id] = False
|
||||
for move_line in (st_line.reconcile_id and
|
||||
(st_line.reconcile_id.line_id or []) +
|
||||
(st_line.reconcile_id.line_partial_ids or []) or
|
||||
[]):
|
||||
for move_line in (
|
||||
st_line.reconcile_id and
|
||||
(st_line.reconcile_id.line_id or
|
||||
st_line.reconcile_id.line_partial_ids) or
|
||||
st_line.import_transaction_id and
|
||||
st_line.import_transaction_id.move_line_id and
|
||||
[st_line.import_transaction_id.move_line_id] or []):
|
||||
if move_line.invoice:
|
||||
res[st_line.id] = move_line.invoice.id
|
||||
continue
|
||||
|
||||
@@ -436,10 +436,16 @@ class banking_import_transaction(osv.osv):
|
||||
is_zero = lambda amount: self.pool.get('res.currency').is_zero(
|
||||
cr, uid, currency, amount)
|
||||
move_line = move_line_obj.browse(cr, uid, move_line_id, context=context)
|
||||
reconcile = move_line.reconcile_id or move_line.reconcile_partial_id
|
||||
if move_line.reconcile_id:
|
||||
raise osv.except_osv(
|
||||
_('Entry is already reconciled'),
|
||||
_("You cannot reconcile the bank transaction with this entry, " +
|
||||
"it is already reconciled")
|
||||
)
|
||||
reconcile = move_line.reconcile_partial_id
|
||||
line_ids = [move_line_id] + (
|
||||
[x.id for x in reconcile and (
|
||||
reconcile.line_id or reconcile.line_partial_ids) or []])
|
||||
[x.id for x in reconcile and ( # reconcile.line_id or
|
||||
reconcile.line_partial_ids) or []])
|
||||
if not reconcile:
|
||||
reconcile_id = reconcile_obj.create(
|
||||
cr, uid, {'type': 'auto' }, context=context)
|
||||
@@ -448,10 +454,15 @@ class banking_import_transaction(osv.osv):
|
||||
move_line_obj.get_balance(cr, uid, line_ids) - amount)
|
||||
# we should not have to check whether there is a surplus writeoff
|
||||
# as any surplus amount *should* have been split off in the matching routine
|
||||
if full:
|
||||
line_partial_ids = []
|
||||
else:
|
||||
line_partial_ids = line_ids[:]
|
||||
line_ids = []
|
||||
reconcile_obj.write(
|
||||
cr, uid, reconcile_id,
|
||||
{ 'line_id': [(6, 0, full and line_ids or [])],
|
||||
'line_partial_ids': [(6, 0, full and [] or line_ids)],
|
||||
{ 'line_id': [(6, 0, line_ids)],
|
||||
'line_partial_ids': [(6, 0, line_partial_ids)],
|
||||
}, context=context)
|
||||
return reconcile_id
|
||||
|
||||
@@ -466,10 +477,15 @@ class banking_import_transaction(osv.osv):
|
||||
line_ids.remove(move_line_id)
|
||||
if len(line_ids) > 1:
|
||||
full = is_zero(move_line_obj.get_balance(cr, uid, line_ids))
|
||||
if full:
|
||||
line_partial_ids = []
|
||||
else:
|
||||
line_partial_ids = line_ids.copy()
|
||||
line_ids = []
|
||||
reconcile_obj.write(
|
||||
cr, uid, reconcile.id,
|
||||
{ 'line_partial_ids': [(6, 0, full and [] or line_ids)],
|
||||
'line_id': [(6, 0, full and line_ids or [])],
|
||||
{ 'line_partial_ids': [(6, 0, line_ids)],
|
||||
'line_id': [(6, 0, line_partial_ids)],
|
||||
}, context=context)
|
||||
else:
|
||||
reconcile_obj.unlink(cr, uid, reconcile.id, context=context)
|
||||
@@ -483,24 +499,27 @@ class banking_import_transaction(osv.osv):
|
||||
self, cr, uid, transaction_id, context=None):
|
||||
statement_line_obj = self.pool.get('account.bank.statement.line')
|
||||
transaction = self.browse(cr, uid, transaction_id, context=context)
|
||||
move_line_id = transaction.move_line_id.id
|
||||
if not transaction.move_line_id:
|
||||
if transaction.match_type == 'invoice':
|
||||
osv.except_osv(
|
||||
raise osv.except_osv(
|
||||
_("Cannot link transaction %s with invoice") %
|
||||
transaction.statement_line_id.name,
|
||||
(transaction.invoice_ids and
|
||||
_("Please select one of the matches") or
|
||||
_("No match found"))
|
||||
)
|
||||
(_("Please select one of the matches in transaction %s.%s") or
|
||||
_("No match found for transaction %s.%s")) % (
|
||||
transaction.statement_line_id.statement_id.name,
|
||||
transaction.statement_line_id.name
|
||||
)))
|
||||
else:
|
||||
osv.except_osv(
|
||||
raise osv.except_osv(
|
||||
_("Cannot link transaction %s with accounting entry") %
|
||||
transaction.statement_line_id.name,
|
||||
(transaction.move_line_ids and
|
||||
_("Please select one of the matches") or
|
||||
_("No match found"))
|
||||
)
|
||||
(_("Please select one of the matches in transaction %s.%s") or
|
||||
_("No match found for transaction %s.%s")) % (
|
||||
transaction.statement_line_id.statement_id.name,
|
||||
transaction.statement_line_id.name
|
||||
)))
|
||||
currency = (transaction.statement_line_id.statement_id.journal_id.currency or
|
||||
transaction.statement_line_id.statement_id.company_id.currency_id)
|
||||
reconcile_id = self._do_move_reconcile(
|
||||
@@ -1121,17 +1140,15 @@ class banking_import_transaction(osv.osv):
|
||||
len(move_info['payment_order_ids']) == 1 and
|
||||
move_info['payment_order_ids'][0]
|
||||
)
|
||||
self_values['move_line_id'] = (move_info.get('move_line_ids', False) and
|
||||
len(move_info['move_line_ids']) == 1 and
|
||||
move_info['move_line_ids'][0]
|
||||
)
|
||||
if move_info['match_type'] == 'invoice':
|
||||
self_values['move_line_id'] = False
|
||||
self_values['invoice_id'] = (move_info.get('invoice_ids', False) and
|
||||
len(move_info['invoice_ids']) == 1 and
|
||||
move_info['invoice_ids'][0]
|
||||
)
|
||||
else:
|
||||
self_values['move_line_id'] = (move_info.get('move_line_ids', False) and
|
||||
len(move_info['move_line_ids']) == 1 and
|
||||
move_info['move_line_ids'][0]
|
||||
)
|
||||
values['partner_id'] = move_info['partner_id']
|
||||
values['partner_bank_id'] = move_info['partner_bank_id']
|
||||
values['type'] = move_info['type']
|
||||
@@ -1201,7 +1218,7 @@ class banking_import_transaction(osv.osv):
|
||||
|
||||
def _get_match_multi(self, cr, uid, ids, name, args, context=None):
|
||||
"""
|
||||
Indicate that multiple matches have been found
|
||||
Indicate in the wizard that multiple matches have been found
|
||||
and that the user has not yet made a choice between them.
|
||||
"""
|
||||
if not ids:
|
||||
@@ -1326,10 +1343,46 @@ class banking_transaction_wizard(osv.osv_memory):
|
||||
context=context)['import_transaction_id'][0] # many2one tuple
|
||||
|
||||
import_transaction_obj.match(cr, uid, [trans_id], context=context)
|
||||
return self.create_act_window(cr, uid, ids, context=context)
|
||||
return True
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
res = super(banking_transaction_wizard, self).write(
|
||||
cr, uid, ids, vals, context=context)
|
||||
if vals and 'invoice_id' in vals:
|
||||
statement_line_obj = self.pool.get('account.bank.statement.line')
|
||||
transaction_obj = self.pool.get('banking.import.transaction')
|
||||
for wiz in self.browse(cr, uid, ids, context=context):
|
||||
if (wiz.import_transaction_id.match_type == 'invoice' and
|
||||
wiz.import_transaction_id.invoice_id):
|
||||
if (wiz.move_line_id and wiz.move_line_id.invoice and
|
||||
wiz.move_line_id.invoice.id == wiz.invoice_id.id):
|
||||
found = True
|
||||
continue
|
||||
for move_line in wiz.import_transaction_id.move_line_ids:
|
||||
if (move_line.invoice.id ==
|
||||
wiz.import_transaction_id.invoice_id.id):
|
||||
transaction_obj.write(
|
||||
cr, uid, wiz.import_transaction_id.id,
|
||||
{ 'move_line_id': move_line.id, }, context=context)
|
||||
statement_line_obj.write(
|
||||
cr, uid, wiz.import_transaction_id.statement_line_id.id,
|
||||
{ 'partner_id': move_line.invoice.partner_id.id,
|
||||
'account_id': move_line.account_id.id,
|
||||
}, context=context)
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
transaction_obj.write(
|
||||
cr, uid, wiz.import_transaction_id.id,
|
||||
{ 'invoice_id': False, }, context=context)
|
||||
# osv.except_osv(
|
||||
# _("No entry found for the selected invoice"),
|
||||
# _("Please file a bug and resort to manual matching."))
|
||||
|
||||
def select_match(self, cr, uid, ids, context=None):
|
||||
return True
|
||||
# TODO: indicate residual
|
||||
# The procedure below has been moved to write()
|
||||
if isinstance(ids, (int, float)):
|
||||
ids = [ids]
|
||||
transaction_obj = self.pool.get('banking.import.transaction')
|
||||
|
||||
@@ -83,10 +83,42 @@ class account_move_line(osv.osv):
|
||||
return [('id', '=', '0')]
|
||||
return [('id', 'in', map(lambda x:x[0], res))]
|
||||
|
||||
def _dummy(self, cr, user, ids, name, arg, context=None):
|
||||
res = {}
|
||||
if ids:
|
||||
res = dict([(x.id, False) for x in ids])
|
||||
return res
|
||||
|
||||
def _invoice_payment_term_id_search(self, cr, uid, obj, name, args, context=None):
|
||||
if not args:
|
||||
return []
|
||||
invoice_obj = self.pool.get('account.invoice')
|
||||
invoice_ids = invoice_obj.search(
|
||||
cr, uid, [('payment_term', args[0][1], args[0][2])],
|
||||
context=context)
|
||||
operator = (args[0][1] not in ['in', '=', '==', 'like', 'ilike']
|
||||
and 'not in' or 'in')
|
||||
if not invoice_ids:
|
||||
return [('id', operator, [])]
|
||||
cr.execute('SELECT l.id ' \
|
||||
'FROM account_move_line l, account_invoice i ' \
|
||||
'WHERE l.move_id = i.move_id AND i.id in %s', (tuple(invoice_ids),))
|
||||
res = cr.fetchall()
|
||||
if not res:
|
||||
return [('id', '=', False)]
|
||||
return [('id', operator, [x[0] for x in res])]
|
||||
|
||||
_columns = {
|
||||
'amount_to_receive': fields.function(amount_to_receive, method=True,
|
||||
type='float', string='Amount to receive', fnct_search=_to_receive_search),
|
||||
}
|
||||
'amount_to_receive': fields.function(
|
||||
amount_to_receive, method=True,
|
||||
type='float', string='Amount to receive',
|
||||
fnct_search=_to_receive_search),
|
||||
'payment_term_id': fields.function(
|
||||
_dummy, method=True,
|
||||
string='Select by invoice payment term',
|
||||
type='many2one', relation='account.payment.term',
|
||||
fnct_search=_invoice_payment_term_id_search),
|
||||
}
|
||||
|
||||
account_move_line()
|
||||
|
||||
|
||||
@@ -19,21 +19,21 @@ class payment_mode(osv.osv):
|
||||
help=('Journal to write payment entries when confirming ' +
|
||||
'a debit order of this mode'),
|
||||
),
|
||||
'reference_filter': fields.char(
|
||||
'Reference filter', size=16,
|
||||
help=(
|
||||
'Optional substring filter on move line references. ' +
|
||||
'You can use this in combination with a specific journal ' +
|
||||
'for items that you want to handle with this mode. Use ' +
|
||||
'a separate sequence for the journal with a distinguished ' +
|
||||
'prefix or suffix and enter that character string here.'),
|
||||
),
|
||||
# 'payment_term_ids': fields.many2many(
|
||||
# 'account.payment.term', 'account_payment_order_terms_rel',
|
||||
# 'mode_id', 'term_id', 'Payment terms',
|
||||
# help=('Limit selected invoices to invoices with these payment ' +
|
||||
# 'terms')
|
||||
# 'reference_filter': fields.char(
|
||||
# 'Reference filter', size=16,
|
||||
# help=(
|
||||
# 'Optional substring filter on move line references. ' +
|
||||
# 'You can use this in combination with a specific journal ' +
|
||||
# 'for items that you want to handle with this mode. Use ' +
|
||||
# 'a separate sequence for the journal with a distinguished ' +
|
||||
# 'prefix or suffix and enter that character string here.'),
|
||||
# ),
|
||||
'payment_term_ids': fields.many2many(
|
||||
'account.payment.term', 'account_payment_order_terms_rel',
|
||||
'mode_id', 'term_id', 'Payment terms',
|
||||
help=('Limit selected invoices to invoices with these payment ' +
|
||||
'terms')
|
||||
),
|
||||
}
|
||||
payment_mode()
|
||||
|
||||
@@ -418,21 +418,19 @@ class payment_order_create(osv.osv_memory):
|
||||
# cannot filter on properties of (searchable)
|
||||
# function fields. Needs work in expression.expression.parse()
|
||||
# Currently gives an SQL error.
|
||||
# # apply payment term filter
|
||||
# if payment.mode.payment_term_ids:
|
||||
# term_ids = [term.id for term in payment.mode.payment_term_ids]
|
||||
# domain = domain + [
|
||||
# '|', ('invoice', '=', False),
|
||||
# ('invoice.payment_term', 'in', term_ids),
|
||||
# ]
|
||||
# apply payment term filter
|
||||
if payment.mode.payment_term_ids:
|
||||
term_ids = [term.id for term in payment.mode.payment_term_ids]
|
||||
domain = domain + [
|
||||
'|', ('invoice', '=', False),
|
||||
('payment_term_id', 'in', term_ids),
|
||||
]
|
||||
else:
|
||||
domain = [
|
||||
('reconcile_id', '=', False),
|
||||
('account_id.type', '=', 'payable'),
|
||||
('amount_to_pay', '>', 0)
|
||||
]
|
||||
if payment.mode.reference_filter:
|
||||
domain.append(('ref', 'ilike', payment.mode.reference_filter))
|
||||
# domain = [('reconcile_id', '=', False), ('account_id.type', '=', 'payable'), ('amount_to_pay', '>', 0)]
|
||||
### end account_direct_debit ###
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
<field name="type" position="after">
|
||||
<field name="transfer_account_id"/>
|
||||
<field name="transfer_journal_id"/>
|
||||
<field name="reference_filter"/>
|
||||
<field name="payment_term_ids"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
Reference in New Issue
Block a user