[FIX] Bank import writes to browse object

[ADD] direct debit order: process storno during bank import
[ADD] bank import: add hooks for processing debit orders and stornos
[ADD] direct debit order: pre-select move lines on reference substring
	configured in payment mode
[ADD] payment term for direct debit invoices
[ADD] payment line views: add storno field
[RFR] standardize storno and debit order processing during bank import
This commit is contained in:
OpenERP instance user
2011-12-14 15:35:02 +01:00
parent 4af0d711f1
commit cab64a4ebb
9 changed files with 268 additions and 98 deletions

View File

@@ -751,6 +751,26 @@ class payment_line(osv.osv):
return res
def debit_storno(self, cr, uid, payment_line_id, amount,
currency_id, storno_retry=True, context=None):
"""
Hook for handling a canceled item of a direct debit order.
Presumably called from a bank statement import routine.
Decide on the direction that the invoice's workflow needs to take.
You may optionally return an incomplete reconcile for the caller
to reconcile the now void payment.
:param payment_line_id: the single payment line id
:param amount: the (negative) amount debited from the bank account
:param currency_id: the bank account's currency id
:param boolean storno_retry: whether the storno is considered fatal \
or not.
:return: an incomplete reconcile for the caller to fill
:rtype: database id of an account.move.reconcile resource.
"""
return False
payment_line()

View File

@@ -174,6 +174,10 @@ class mem_bank_transaction(object):
# An error message for interaction with the user
# Only used when mem_transaction.valid returns False.
'error_message',
# Storno attribute. When True, make the cancelled debit eligible for
# a next direct debit run
'storno_retry',
]
@@ -206,6 +210,10 @@ class mem_bank_transaction(object):
# PERIODIC_ORDER An automated payment by the bank on your behalf.
# Always outgoing.
# Will be selected for matching.
# STORNO A failed or reversed attempt at direct debit.
# Either due to an action on the payer's side
# or a failure observed by the bank (lack of
# credit for instance)
#
# Perhaps more will follow.
#

View File

@@ -77,10 +77,10 @@ class banking_import(osv.osv_memory):
retval.type = 'general'
if partial:
move_line.reconcile_partial_id = reconcile_obj.create(
reconcile_obj.create(
cursor, uid, {
'type': 'auto',
'line_partial_ids': [(4, 0, [move_line.id])]
'line_partial_ids': [(4, 0, [move_line.id])],
}
)
else:
@@ -90,19 +90,56 @@ class banking_import(osv.osv_memory):
]
else:
partial_ids = []
move_line.reconcile_id = reconcile_obj.create(
reconcile_obj.create(
cursor, uid, {
'type': 'auto',
'line_id': [
(4, x, False) for x in [move_line.id] + partial_ids
],
'line_partial_ids': [
(3, x, False) for x in partial_ids
]
'line_id': [(6, 0, [move_line.id] + partial_ids)],
'line_partial_ids': [(6, 0, [])],
}
)
return retval
def _link_storno(
self, cr, uid, trans, account_info, log, context=None):
payment_line_obj = self.pool.get('payment.line')
move_line_obj = self.pool.get('account.move.line')
line_ids = payment_line_obj.search(
cr, uid, [
('order_id.payment_order_type', '=', 'debit'),
('order_id.state', 'in', ['sent', 'done']),
('communication', '=', trans.reference)
], context=context)
if len(line_ids) == 1:
reconcile_id = payment_line_obj.debit_storno(
cr, uid, line_ids[0], trans.transferred_amount,
account_info.currency_id, trans.storno_retry, context=None)
if reconcile_id:
# we need to retrieve the move line as per consistency
# but it is only used to retrieve the account_id to book
# the transfer to. By necessity, we can use any of the
# move lines from the reconcile as all of them should have
# the same account.
move_line_ids = move_line_obj.search(
cr, uid,
[
'|', ('reconcile_id', '=', reconcile_id),
('reconcile_partial_id', '=', reconcile_id),
]
, context=context)
if move_line_ids:
move_line=move_line_obj.browse(
cr, uid, move_line_ids[0], context=context)
return struct(
move_line=move_line,
partner_id=False,
partner_bank_id=False,
reference=False,
type='general',
)
# TODO log the reason why there is no result for transfers marked
# as storno
return False
def _link_debit_order(
self, cr, uid, trans, account_info, log, context=None):
@@ -309,6 +346,7 @@ class banking_import(osv.osv_memory):
]
move_line = False
if candidates and len(candidates) > 0:
# Now a possible selection of invoices has been found, check the
# amounts expected and received.
@@ -753,6 +791,9 @@ class banking_import(osv.osv_memory):
if transaction.type == bt.DIRECT_DEBIT:
move_info = self._link_debit_order(
cursor, uid, transaction, account_info, results.log, context)
if transaction.type == bt.STORNO:
move_info = self._link_storno(
cursor, uid, transaction, account_info, results.log, context)
# Allow inclusion of generated bank invoices
if transaction.type == bt.BANK_COSTS:
lines = self._link_costs(
@@ -864,7 +905,12 @@ class banking_import(osv.osv_memory):
)
if move_info:
values.type = move_info.type
values.reconcile_id = move_info.move_line.reconcile_id.id
values.reconcile_id = (
move_info.move_line.reconcile_id and
move_info.move_line.reconcile_id.id or
move_info.move_line.reconcile_partial_id and
move_info.move_line.reconcile_partial_id.id
)
values.partner_id = move_info.partner_id
values.partner_bank_id = move_info.partner_bank_id
else: