~jsancho/sepa-tools/make-payments-6.0

« back to all changes in this revision

Viewing changes to account_payment_direct_debit/model/payment_line.py

  • Committer: Ignacio Ibeas - Acysos S.L.
  • Date: 2014-02-11 18:29:05 UTC
  • Revision ID: ignacio@acysos.com-20140211182905-bzlhkh052cnc0qfw
[ADD] Account Payment SEPA: modules SEPA for account_paymnt_extension adapted from banking addons

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
from osv import fields, osv
 
3
import netsvc
 
4
from tools.translate import _
 
5
 
 
6
class payment_line(osv.osv):
 
7
    _inherit = 'payment.line'
 
8
 
 
9
    def debit_storno(self, cr, uid, payment_line_id, amount,
 
10
                     currency, storno_retry=True, context=None):
 
11
        """
 
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.
 
17
 
 
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.
 
21
 
 
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.
 
29
        """
 
30
 
 
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)
 
34
        reconcile_id = False
 
35
        if (line.transit_move_line_id and not line.storno and
 
36
            self.pool.get('res.currency').is_zero(
 
37
                cr, uid, currency, (
 
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
 
51
                    reconcile_obj.write(
 
52
                        cr, uid, reconcile_id, {
 
53
                            'line_id': [(6, 0, line.transit_move_line_id.id)],
 
54
                            'line_partial_ids': [(6, 0, [])],
 
55
                            }, context=context)
 
56
                else:
 
57
                    # split up the original reconcile in a partial one
 
58
                    # and a new one for reconciling the storno transfer
 
59
                    reconcile_obj.write(
 
60
                        cr, uid, reconcile_id, {
 
61
                            'line_partial_ids': [(3, line.transit_move_line_id.id)],
 
62
                            }, context=context)
 
63
                    reconcile_id = reconcile_obj.create(
 
64
                        cr, uid, {
 
65
                            'type': 'auto',
 
66
                            'line_id': [(6, 0, line.transit_move_line_id.id)],
 
67
                            }, context=context)
 
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
 
72
                    reconcile_obj.write(
 
73
                        cr, uid, reconcile_id, {
 
74
                            'line_id': [(6, 0, [line.transit_move_line_id.id])]
 
75
                            }, context=context)
 
76
                else:
 
77
                    # split up the original reconcile in a partial one
 
78
                    # and a new one for reconciling the storno transfer
 
79
                    partial_ids = [ 
 
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
 
82
                        ]
 
83
                    reconcile_obj.write(
 
84
                        cr, uid, reconcile_id, {
 
85
                            'line_partial_ids': [(6, 0, partial_ids)],
 
86
                            'line_id': [(6, 0, [])],
 
87
                            }, context=context)
 
88
                    reconcile_id = reconcile_obj.create(
 
89
                        cr, uid, {
 
90
                            'type': 'auto',
 
91
                            'line_id': [(6, 0, line.transit_move_line_id.id)],
 
92
                            }, context=context)
 
93
            # mark the payment line for storno processed
 
94
            if reconcile_id:
 
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,
 
103
                        activity, cr)
 
104
        return reconcile_id
 
105
 
 
106
    def get_storno_account_id(self, cr, uid, payment_line_id, amount,
 
107
                     currency, context=None):
 
108
        """
 
109
        Check the match of the arguments, and return the account associated
 
110
        with the storno.
 
111
        Used in account_banking interactive mode
 
112
 
 
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.
 
118
        """
 
119
 
 
120
        line = self.browse(cr, uid, payment_line_id)
 
121
        account_id = False
 
122
        if (line.transit_move_line_id and not line.storno and
 
123
            self.pool.get('res.currency').is_zero(
 
124
                cr, uid, currency, (
 
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
 
128
        return account_id
 
129
 
 
130
    def debit_reconcile(self, cr, uid, payment_line_id, context=None):
 
131
        """
 
132
        Raise if a payment line is passed for which storno is True
 
133
        """
 
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)
 
145
 
 
146
    _columns = {
 
147
        'storno': fields.boolean(
 
148
            'Storno',
 
149
            readonly=True,
 
150
            help=("If this is true, the debit order has been canceled "
 
151
                  "by the bank or by the customer")),
 
152
        }
 
153
payment_line()