~banking-addons-team/banking-addons/github-7.0

« back to all changes in this revision

Viewing changes to account_banking_payment/model/account_payment.py

  • Committer: Stefan Rijnhart
  • Author(s): unknown
  • Date: 2014-06-25 09:19:35 UTC
  • mfrom: (225.1.23)
  • Revision ID: git-v1:7f93d703e87a5254b11a9900b0f0b35b49ec522c
1) Add 4 new modules to handle payment mode and bank accounts:
    - account_payment_partner
    - account_payment_sale
    - account_payment_sale_stock
    - account_payment_purchase

2) Filter the selection of invoices per payment mode.
    Add active field on payment.mode and payment.mode.type.
    Add menu entry for Payment Types.

3) Small code clean-up in the SEPA modules (views, 'state' field on SEPA file objects)

4) Code enhancement in the file account_banking_payment/model/account_payment.py (PEP-8, _prepare_* functions, support for payment lines with move_line_id = False)

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
#
4
4
#    Copyright (C) 2009 EduSense BV (<http://www.edusense.nl>).
5
5
#              (C) 2011 - 2013 Therp BV (<http://therp.nl>).
6
 
#            
 
6
#
7
7
#    All other contributions are (C) by their respective contributors
8
8
#
9
9
#    All Rights Reserved
63
63
        ),
64
64
        'state': fields.selection([
65
65
            ('draft', 'Draft'),
66
 
            ('open','Confirmed'),
67
 
            ('cancel','Cancelled'),
 
66
            ('open', 'Confirmed'),
 
67
            ('cancel', 'Cancelled'),
68
68
            ('sent', 'Sent'),
69
69
            ('rejected', 'Rejected'),
70
 
            ('done','Done'),
 
70
            ('done', 'Done'),
71
71
            ], 'State', select=True
72
72
        ),
73
73
        'line_ids': fields.one2many(
81
81
            },
82
82
        ),
83
83
        'user_id': fields.many2one(
84
 
            'res.users','User', required=True,
 
84
            'res.users', 'User', required=True,
85
85
            states={
86
86
                'sent': [('readonly', True)],
87
87
                'rejected': [('readonly', True)],
98
98
                'rejected': [('readonly', True)],
99
99
                'done': [('readonly', True)]
100
100
            },
101
 
            help=("Choose an option for the Payment Order:'Fixed' stands for a "
102
 
                  "date specified by you.'Directly' stands for the direct "
 
101
            help=("Choose an option for the Payment Order:'Fixed' stands for "
 
102
                  "a date specified by you.'Directly' stands for the direct "
103
103
                  "execution.'Due date' stands for the scheduled date of "
104
104
                  "execution."
105
 
                 )
 
105
                  )
106
106
            ),
107
107
        'date_sent': fields.date('Send date', readonly=True),
108
108
    }
109
109
 
110
110
    def _write_payment_lines(self, cr, uid, ids, **kwargs):
111
111
        '''
112
 
        ORM method for setting attributes of corresponding payment.line objects.
 
112
        ORM method for setting attributes of corresponding payment.line
 
113
        objects.
113
114
        Note that while this is ORM compliant, it is also very ineffecient due
114
115
        to the absence of filters on writes and hence the requirement to
115
116
        filter on the client(=OpenERP server) side.
143
144
            cr, uid, ids, *args
144
145
        )
145
146
 
146
 
    def debit_reconcile_transfer(self, cr, uid, payment_order_id, 
 
147
    def debit_reconcile_transfer(self, cr, uid, payment_order_id,
147
148
                                 amount, currency, context=None):
148
149
        """
149
150
        During import of bank statements, create the reconcile on the transfer
163
164
                if line.account_id.type == 'other' and not line.reconcile_id:
164
165
                    line_ids.append(line.id)
165
166
        if self.pool.get('res.currency').is_zero(
166
 
            cr, uid, currency,
167
 
            move_line_obj.get_balance(cr, uid, line_ids) - amount):
 
167
                cr, uid, currency,
 
168
                move_line_obj.get_balance(cr, uid, line_ids) - amount):
168
169
            reconcile_id = self.pool.get('account.move.reconcile').create(
169
 
                cr, uid, 
 
170
                cr, uid,
170
171
                {'type': 'auto', 'line_id': [(6, 0, line_ids)]},
171
172
                context)
172
173
            # set direct debit order to finished state
175
176
                uid, 'payment.order', payment_order_id, 'done', cr)
176
177
        return reconcile_id
177
178
 
178
 
    def debit_unreconcile_transfer(self, cr, uid, payment_order_id, reconcile_id,
179
 
                                 amount, currency, context=None):
 
179
    def debit_unreconcile_transfer(
 
180
            self, cr, uid, payment_order_id, reconcile_id, amount, currency,
 
181
            context=None):
180
182
        """
181
183
        Due to a cancelled bank statements import, unreconcile the move on
182
184
        the transfer account. Delegate the conditions to the workflow.
194
196
        if state != 'sent':
195
197
            raise orm.except_orm(
196
198
                _("Cannot unreconcile"),
197
 
                _("Cannot unreconcile payment order: "+
 
199
                _("Cannot unreconcile payment order: "
198
200
                  "Workflow will not allow it."))
199
201
        return True
200
202
 
201
203
    def test_undo_done(self, cr, uid, ids, context=None):
202
 
        """ 
 
204
        """
203
205
        Called from the workflow. Used to unset done state on
204
206
        payment orders that were reconciled with bank transfers
205
207
        which are being cancelled.
213
215
        for order in self.browse(cr, uid, ids, context=context):
214
216
            for order_line in order.line_ids:
215
217
                if order_line.transit_move_line_id.move_id:
216
 
                    for line in order_line.transit_move_line_id.move_id.line_id:
 
218
                    for line in \
 
219
                            order_line.transit_move_line_id.move_id.line_id:
217
220
                        if (line.account_id.type == 'other' and
218
221
                                line.reconcile_id):
219
222
                            return False
220
223
        return True
221
 
        
 
224
 
 
225
    def _prepare_transfer_move(
 
226
            self, cr, uid, order, line, labels, context=None):
 
227
        vals = {
 
228
            'journal_id': order.mode.transfer_journal_id.id,
 
229
            'name': '%s %s' % (labels[order.payment_order_type],
 
230
                               line.move_line_id
 
231
                               and line.move_line_id.move_id.name
 
232
                               or line.communication),
 
233
            'ref': '%s %s' % (order.payment_order_type[:3].upper(),
 
234
                              line.move_line_id
 
235
                              and line.move_line_id.move_id.name
 
236
                              or line.communication),
 
237
            }
 
238
        return vals
 
239
 
 
240
    def _prepare_move_line_transfer_account(
 
241
            self, cr, uid, order, line, move_id, labels, context=None):
 
242
        vals = {
 
243
            'name': _('%s for %s') % (
 
244
                labels[order.payment_order_type],
 
245
                line.move_line_id and (line.move_line_id.invoice
 
246
                                       and line.move_line_id.invoice.number
 
247
                                       or line.move_line_id.name)
 
248
                or line.communication),
 
249
            'move_id': move_id,
 
250
            'partner_id': False,
 
251
            'account_id': order.mode.transfer_account_id.id,
 
252
            'credit': (order.payment_order_type == 'payment'
 
253
                       and line.amount or 0.0),
 
254
            'debit': (order.payment_order_type == 'debit'
 
255
                      and line.amount or 0.0),
 
256
            'date': fields.date.context_today(
 
257
                self, cr, uid, context=context),
 
258
            }
 
259
        return vals
 
260
 
 
261
    def _update_move_line_partner_account(
 
262
            self, cr, uid, order, line, vals, context=None):
 
263
        vals.update({
 
264
            'partner_id': line.partner_id.id,
 
265
            'account_id': (line.move_line_id
 
266
                           and line.move_line_id.account_id.id
 
267
                           or False),
 
268
            # if not line.move_line_id, the field 'account_id' must be set by
 
269
            # another module that inherit this function, like for example in
 
270
            # the module purchase_payment_order
 
271
            'credit': (order.payment_order_type == 'debit'
 
272
                       and line.amount or 0.0),
 
273
            'debit': (order.payment_order_type == 'payment'
 
274
                      and line.amount or 0.0),
 
275
            })
 
276
        return vals
 
277
 
 
278
    def action_sent_no_move_line_hook(self, cr, uid, pay_line, context=None):
 
279
        """This function is designed to be inherited"""
 
280
        return
 
281
 
222
282
    def action_sent(self, cr, uid, ids, context=None):
223
 
        """ 
 
283
        """
224
284
        Create the moves that pay off the move lines from
225
285
        the debit order. This happens when the debit order file is
226
286
        generated.
233
293
            'debit': _('Direct debit order'),
234
294
            }
235
295
        for order in self.browse(cr, uid, ids, context=context):
236
 
            if not order.mode.transfer_journal_id or not order.mode.transfer_account_id:
 
296
            if not order.mode.transfer_journal_id \
 
297
                    or not order.mode.transfer_account_id:
237
298
                continue
238
299
            for line in order.line_ids:
239
300
                # basic checks
240
 
                if not line.move_line_id:
241
 
                    raise orm.except_orm(
242
 
                        _('Error'),
243
 
                        _('No move line provided for line %s') % line.name)
244
 
                if line.move_line_id.reconcile_id:
245
 
                    raise orm.except_orm(
246
 
                        _('Error'),
247
 
                        _('Move line %s has already been paid/reconciled') % 
248
 
                        line.move_line_id.name
249
 
                        )
 
301
                if line.move_line_id and line.move_line_id.reconcile_id:
 
302
                    raise orm.except_orm(
 
303
                        _('Error'),
 
304
                        _('Move line %s has already been paid/reconciled')
 
305
                        % line.move_line_id.name)
250
306
 
251
 
                move_id = account_move_obj.create(cr, uid, {
252
 
                        'journal_id': order.mode.transfer_journal_id.id,
253
 
                        'name': '%s %s' % (labels[order.payment_order_type], 
254
 
                                           line.move_line_id.move_id.name),
255
 
                        'ref': '%s%s' % (order.payment_order_type[:3].upper(),
256
 
                                               line.move_line_id.move_id.name),
257
 
                        }, context=context)
 
307
                move_id = account_move_obj.create(
 
308
                    cr, uid, self._prepare_transfer_move(
 
309
                        cr, uid, order, line, labels, context=context),
 
310
                    context=context)
258
311
 
259
312
                # TODO: take multicurrency into account
260
 
                
 
313
 
261
314
                # create the debit move line on the transfer account
262
 
                vals = {
263
 
                    'name': _('%s for %s') % (
264
 
                        labels[order.payment_order_type],
265
 
                        line.move_line_id.invoice and 
266
 
                        line.move_line_id.invoice.number or 
267
 
                        line.move_line_id.name),
268
 
                    'move_id': move_id,
269
 
                    'partner_id': False,
270
 
                    'account_id': order.mode.transfer_account_id.id,
271
 
                    'credit': (order.payment_order_type == 'payment'
272
 
                               and line.amount or 0.0),
273
 
                    'debit': (order.payment_order_type == 'debit'
274
 
                              and line.amount or 0.0),
275
 
                    'date': fields.date.context_today(
276
 
                        self, cr, uid, context=context),
277
 
                    }
278
 
                transfer_move_line_id = account_move_line_obj.create(
279
 
                    cr, uid, vals, context=context)
 
315
                ml_vals = self._prepare_move_line_transfer_account(
 
316
                    cr, uid, order, line, move_id, labels, context=context)
 
317
                account_move_line_obj.create(cr, uid, ml_vals, context=context)
280
318
 
281
 
                # create the debit move line on the receivable account
282
 
                vals.update({
283
 
                        'partner_id': line.partner_id.id,
284
 
                        'account_id': line.move_line_id.account_id.id,
285
 
                        'credit': (order.payment_order_type == 'debit'
286
 
                                   and line.amount or 0.0),
287
 
                        'debit': (order.payment_order_type == 'payment'
288
 
                                   and line.amount or 0.0),
289
 
                        })               
 
319
                # create the debit move line on the partner account
 
320
                self._update_move_line_partner_account(
 
321
                    cr, uid, order, line, ml_vals, context=context)
290
322
                reconcile_move_line_id = account_move_line_obj.create(
291
 
                    cr, uid, vals, context=context)
292
 
                
 
323
                    cr, uid, ml_vals, context=context)
 
324
 
293
325
                # register the debit move line on the payment line
294
326
                # and call reconciliation on it
295
327
                payment_line_obj.write(
297
329
                    {'transit_move_line_id': reconcile_move_line_id},
298
330
                    context=context)
299
331
 
300
 
                payment_line_obj.debit_reconcile(
301
 
                    cr, uid, line.id, context=context)
 
332
                if line.move_line_id:
 
333
                    payment_line_obj.debit_reconcile(
 
334
                        cr, uid, line.id, context=context)
 
335
                else:
 
336
                    self.action_sent_no_move_line_hook(
 
337
                        cr, uid, line, context=context)
302
338
                account_move_obj.post(cr, uid, [move_id], context=context)
303
339
 
304
340
        # State field is written by act_sent_wait
305
341
        self.write(cr, uid, ids, {
306
 
                'date_sent': fields.date.context_today(
307
 
                    self, cr, uid, context=context),
308
 
                }, context=context)
 
342
            'date_sent': fields.date.context_today(
 
343
                self, cr, uid, context=context),
 
344
            }, context=context)
309
345
 
310
346
        return True
311
 
 
312