1
# -*- coding: utf-8 -*-
2
###############################################################################
4
# sale_automatic_workflow for OpenERP
5
# Copyright (C) 2011-TODAY Akretion <http://www.akretion.com>.
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.
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.
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/>.
21
###############################################################################
22
from openerp.osv.orm import Model
23
from openerp.osv import fields
25
class account_invoice(Model):
26
_inherit = "account.invoice"
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')
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):
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:
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)
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)
49
def _get_sum_move_line(self, cr, uid, move_lines, line_type, context=None):
54
'total_amount_currency': 0,
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
65
def _prepare_write_off(self, cr, uid, invoice, res_invoice, res_payment, context=None):
69
if res_invoice['total_amount'] - res_payment['total_amount'] > 0:
70
writeoff_type = 'expense'
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]
80
'writeoff_acc_id': account_id,
81
'writeoff_period_id': period_id,
82
'writeoff_journal_id': journal_id,
86
def reconcile_invoice(self, cr, uid, ids, context=None):
88
Simple method to reconcile the invoice with the payment generated on the sale order
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']
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)
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)