~extra-addons-commiter/e-commerce-addons/7.0

« back to all changes in this revision

Viewing changes to sale_automatic_workflow/invoice.py

  • Committer: Guewen Baconnier
  • Date: 2013-01-14 07:40:50 UTC
  • mfrom: (231.1.12 e-commerce-addons)
  • Revision ID: guewen.baconnier@camptocamp.com-20130114074050-kitvv6l8hiojxo6f
[MRG] from lp:~extra-addons-commiter/e-commerce-addons/trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
###############################################################################
 
3
#
 
4
#   sale_automatic_workflow for OpenERP
 
5
#   Copyright (C) 2011-TODAY Akretion <http://www.akretion.com>.
 
6
#     All Rights Reserved
 
7
#     @author Sébastien BEAU <sebastien.beau@akretion.com>
 
8
#   This program is free software: you can redistribute it and/or modify
 
9
#   it under the terms of the GNU Affero General Public License as
 
10
#   published by the Free Software Foundation, either version 3 of the
 
11
#   License, or (at your option) any later version.
 
12
#
 
13
#   This program is distributed in the hope that it will be useful,
 
14
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
#   GNU Affero General Public License for more details.
 
17
#
 
18
#   You should have received a copy of the GNU Affero General Public License
 
19
#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
20
#
 
21
###############################################################################
 
22
from openerp.osv.orm import Model
 
23
from openerp.osv import fields
 
24
 
 
25
class account_invoice(Model):
 
26
    _inherit = "account.invoice"
 
27
    _columns = {
 
28
        'workflow_process_id':fields.many2one('sale.workflow.process', 'Sale Workflow Process'),
 
29
        #TODO propose a merge to add this field by default in acount module
 
30
        'sale_ids': fields.many2many('sale.order', 'sale_order_invoice_rel', 'invoice_id', 'order_id', 'Sale Orders')
 
31
    }
 
32
 
 
33
    def _can_be_reconciled(self, cr, uid, invoice, context=None):
 
34
        if not (invoice.sale_ids and invoice.sale_ids[0].payment_ids and invoice.move_id):
 
35
            return False
 
36
        #Check currency
 
37
        for payment in invoice.sale_ids[0].payment_ids:
 
38
            for move in payment.move_ids:
 
39
                if (move.currency_id.id or invoice.company_id.currency_id.id) != invoice.currency_id.id:
 
40
                    return False
 
41
        return True
 
42
 
 
43
    def _get_sum_invoice_move_line(self, cr, uid, move_lines, context=None):
 
44
        return self._get_sum_move_line(cr, uid, move_lines, 'debit', context=None)
 
45
 
 
46
    def _get_sum_payment_move_line(self, cr, uid, move_lines, context=None):
 
47
        return self._get_sum_move_line(cr, uid, move_lines, 'credit', context=None)
 
48
 
 
49
    def _get_sum_move_line(self, cr, uid, move_lines, line_type, context=None):
 
50
        res = {
 
51
            'max_date': False,
 
52
            'line_ids': [],
 
53
            'total_amount': 0,
 
54
            'total_amount_currency': 0,
 
55
        }
 
56
        for move_line in move_lines:
 
57
            if move_line[line_type] > 0:
 
58
                if move_line.date > res['max_date']:
 
59
                    res['max_date'] = move_line.date
 
60
                res['line_ids'].append(move_line.id)
 
61
                res['total_amount'] += move_line[line_type]
 
62
                res['total_amount_currency'] += move_line.amount_currency
 
63
        return res
 
64
 
 
65
    def _prepare_write_off(self, cr, uid, invoice, res_invoice, res_payment, context=None):
 
66
        if not context:
 
67
            context = {}
 
68
        ctx = context.copy()
 
69
        if res_invoice['total_amount'] - res_payment['total_amount'] > 0:
 
70
            writeoff_type = 'expense'
 
71
        else:
 
72
            writeoff_type = 'income'
 
73
        account_id, journal_id = invoice.company_id.\
 
74
            get_write_off_information('exchange', writeoff_type, context=context)
 
75
        max_date = max(res_invoice['max_date'], res_payment['max_date'])
 
76
        ctx['p_date'] = max_date
 
77
        period_id = self.pool.get('account.period').find(cr, uid, max_date, context=context)[0]
 
78
        return {
 
79
            'type': 'auto',
 
80
            'writeoff_acc_id': account_id,
 
81
            'writeoff_period_id': period_id,
 
82
            'writeoff_journal_id': journal_id,
 
83
            'context': ctx,
 
84
        }
 
85
 
 
86
    def reconcile_invoice(self, cr, uid, ids, context=None):
 
87
        """
 
88
        Simple method to reconcile the invoice with the payment generated on the sale order
 
89
        """
 
90
        if not context:
 
91
            context={}
 
92
        precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account')
 
93
        obj_move_line = self.pool.get('account.move.line')
 
94
        for invoice in self.browse(cr, uid, ids, context=context):
 
95
            use_currency = invoice.currency_id.id != invoice.company_id.currency_id.id
 
96
            if self._can_be_reconciled(cr, uid, invoice, context=context):
 
97
                payment_move_line = []
 
98
                for payment in invoice.sale_ids[0].payment_ids:
 
99
                    payment_move_line += payment.move_ids
 
100
                res_payment = self._get_sum_payment_move_line(cr, uid, payment_move_line, context=context)
 
101
                res_invoice = self._get_sum_invoice_move_line(cr, uid, invoice.move_id.line_id, context=context)
 
102
                line_ids = res_invoice['line_ids'] + res_payment['line_ids']
 
103
                if not use_currency:
 
104
                    balance = abs(res_invoice['total_amount']-res_payment['total_amount'])
 
105
                    if line_ids and not round(balance, precision):
 
106
                        obj_move_line.reconcile(cr, uid, line_ids, context=context)
 
107
                else:
 
108
                    balance = abs(res_invoice['total_amount_currency']-res_payment['total_amount_currency'])
 
109
                    if line_ids and not round(balance, precision):
 
110
                        kwargs = self._prepare_write_off(cr, uid, invoice, res_invoice, res_payment, context=context)
 
111
                        obj_move_line.reconcile(cr, uid, line_ids, **kwargs)
 
112
        return True