1
# -*- coding: utf-8 -*-
2
from osv import fields, osv
4
from tools.translate import _
6
class payment_line(osv.osv):
7
_inherit = 'payment.line'
9
def debit_storno(self, cr, uid, payment_line_id, amount,
10
currency, storno_retry=True, context=None):
12
The processing of a storno is triggered by a debit
13
transfer on one of the company's bank accounts.
14
This method offers to re-reconcile the original debit
15
payment. For this purpose, we have registered that
16
payment move on the payment line.
18
Return the (now incomplete) reconcile id. The caller MUST
19
re-reconcile this reconcile with the bank transfer and
20
re-open the associated invoice.
22
:param payment_line_id: the single payment line id
23
:param amount: the (signed) amount debited from the bank account
24
:param currency: the bank account's currency *browse object*
25
:param boolean storno_retry: when True, attempt to reopen the invoice, \
26
set the invoice to 'Debit denied' otherwise.
27
:return: an incomplete reconcile for the caller to fill
28
:rtype: database id of an account.move.reconcile resource.
31
move_line_obj = self.pool.get('account.move.line')
32
reconcile_obj = self.pool.get('account.move.reconcile')
33
line = self.browse(cr, uid, payment_line_id)
35
if (line.transit_move_line_id and not line.storno and
36
self.pool.get('res.currency').is_zero(
38
(line.transit_move_line_id.credit or 0.0) -
39
(line.transit_move_line_id.debit or 0.0) + amount))):
40
# Two different cases, full and partial
41
# Both cases differ subtly in the procedure to follow
42
# Needs refractoring, but why is this not in the OpenERP API?
43
# Actually, given the nature of a direct debit order and storno,
44
# we should not need to take partial into account on the side of
45
# the transit_move_line.
46
if line.transit_move_line_id.reconcile_partial_id:
47
reconcile_id = line.transit_move_line_id.reconcile_partial_id.id
48
attribute = 'reconcile_partial_id'
49
if len(line.transit_move_line_id.reconcile_id.line_partial_ids) == 2:
50
# reuse the simple reconcile for the storno transfer
52
cr, uid, reconcile_id, {
53
'line_id': [(6, 0, line.transit_move_line_id.id)],
54
'line_partial_ids': [(6, 0, [])],
57
# split up the original reconcile in a partial one
58
# and a new one for reconciling the storno transfer
60
cr, uid, reconcile_id, {
61
'line_partial_ids': [(3, line.transit_move_line_id.id)],
63
reconcile_id = reconcile_obj.create(
66
'line_id': [(6, 0, line.transit_move_line_id.id)],
68
elif line.transit_move_line_id.reconcile_id:
69
reconcile_id = line.transit_move_line_id.reconcile_id.id
70
if len(line.transit_move_line_id.reconcile_id.line_id) == 2:
71
# reuse the simple reconcile for the storno transfer
73
cr, uid, reconcile_id, {
74
'line_id': [(6, 0, [line.transit_move_line_id.id])]
77
# split up the original reconcile in a partial one
78
# and a new one for reconciling the storno transfer
80
x.id for x in line.transit_move_line_id.reconcile_id.line_id
81
if x.id != line.transit_move_line_id.id
84
cr, uid, reconcile_id, {
85
'line_partial_ids': [(6, 0, partial_ids)],
86
'line_id': [(6, 0, [])],
88
reconcile_id = reconcile_obj.create(
91
'line_id': [(6, 0, line.transit_move_line_id.id)],
93
# mark the payment line for storno processed
95
self.write(cr, uid, [payment_line_id],
96
{'storno': True}, context=context)
97
# put forth the invoice workflow
98
if line.move_line_id.invoice:
99
activity = (storno_retry and 'open_test'
100
or 'invoice_debit_denied')
101
netsvc.LocalService("workflow").trg_validate(
102
uid, 'account.invoice', line.move_line_id.invoice.id,
106
def get_storno_account_id(self, cr, uid, payment_line_id, amount,
107
currency, context=None):
109
Check the match of the arguments, and return the account associated
111
Used in account_banking interactive mode
113
:param payment_line_id: the single payment line id
114
:param amount: the (signed) amount debited from the bank account
115
:param currency: the bank account's currency *browse object*
116
:return: an account if there is a full match, False otherwise
117
:rtype: database id of an account.account resource.
120
line = self.browse(cr, uid, payment_line_id)
122
if (line.transit_move_line_id and not line.storno and
123
self.pool.get('res.currency').is_zero(
125
(line.transit_move_line_id.credit or 0.0) -
126
(line.transit_move_line_id.debit or 0.0) + amount))):
127
account_id = line.transit_move_line_id.account_id.id
130
def debit_reconcile(self, cr, uid, payment_line_id, context=None):
132
Raise if a payment line is passed for which storno is True
134
if isinstance(payment_line_id, (list, tuple)):
135
payment_line_id = payment_line_id[0]
136
payment_line_vals = self.read(
137
cr, uid, payment_line_id, ['storno', 'name'], context=context)
138
if payment_line_vals['storno']:
139
raise osv.except_osv(
140
_('Can not reconcile'),
141
_('Cancelation of payment line \'%s\' has already been '
142
'processed') % payment_line_vals['name'])
143
return super(payment_line, self).debit_reconcile(
144
cr, uid, payment_line_id, context=context)
147
'storno': fields.boolean(
150
help=("If this is true, the debit order has been canceled "
151
"by the bank or by the customer")),