1
# -*- coding: utf-8 -*-
2
##############################################################################
4
# OpenERP, Open Source Management Solution
5
# Copyright (C) 2013 Savoir-faire Linux (<http://www.savoirfairelinux.com>).
7
# This program is free software: you can redistribute it and/or modify
8
# it under the terms of the GNU Affero General Public License as
9
# published by the Free Software Foundation, either version 3 of the
10
# License, or (at your option) any later version.
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU Affero General Public License for more details.
17
# You should have received a copy of the GNU Affero General Public License
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
20
##############################################################################
22
from openerp.osv import orm, fields
23
import openerp.addons.decimal_precision as dp
25
class account_voucher(orm.Model):
27
_inherit = "account.voucher"
29
def writeoff_move_line_get(self, cr, uid, voucher_id, line_total, move_id, name, company_currency, current_currency, context=None):
31
Set a dict to be use to create the writeoff move line.
33
:param voucher_id: Id of voucher what we are creating account_move.
34
:param line_total: Amount remaining to be allocated on lines.
35
:param move_id: Id of account move where this line will be added.
36
:param name: Description of account move line.
37
:param company_currency: id of currency of the company to which the voucher belong
38
:param current_currency: id of currency of the voucher
39
:return: mapping between fieldname and value of account move line to create
43
currency_obj = self.pool.get('res.currency')
46
voucher = self.pool.get('account.voucher').browse(cr,uid,voucher_id,context)
47
current_currency_obj = voucher.currency_id or voucher.journal_id.company_id.currency_id
49
if not currency_obj.is_zero(cr, uid, current_currency_obj, line_total):
53
if voucher.payment_option == 'with_writeoff':
54
account_id = voucher.writeoff_acc_id.id
55
write_off_name = voucher.comment
56
elif voucher.type in ('sale', 'receipt'):
57
account_id = voucher.partner_id.property_account_receivable.id
59
account_id = voucher.partner_id.property_account_payable.id
60
sign = voucher.type == 'payment' and -1 or 1
62
# Create multiple move lines, one for each analytic account
64
voucher_total = sum([l.amount for l in voucher.line_ids
67
invoice_obj = self.pool.get('account.invoice')
71
for voucher_line in voucher.line_ids:
73
if voucher_line.reconcile:
75
invoice_ids = invoice_obj.search(cr, uid, [('number', '=', voucher_line.name)])
76
invoices = invoice_obj.browse(cr, uid, invoice_ids)
78
invoice_ratio = voucher_line.amount / voucher_total
79
invoice_writeoff = diff * invoice_ratio
81
for invoice in invoices:
82
for invoice_line in invoice.invoice_line:
83
invoice_line_ratio = invoice_line.price_subtotal / invoice.amount_untaxed
84
invoice_line_writeoff = round(invoice_writeoff * invoice_line_ratio, 2)
87
'name': write_off_name or name,
88
'account_id': account_id,
90
'partner_id': voucher.partner_id.id,
92
'credit': invoice_line_writeoff > 0 and invoice_line_writeoff or 0.0,
93
'debit': invoice_line_writeoff < 0 and -invoice_line_writeoff or 0.0,
94
'amount_currency': company_currency <> current_currency and (sign * -1 * voucher.writeoff_amount) or 0.0,
95
'currency_id': company_currency <> current_currency and current_currency or False,
96
'analytic_account_id': invoice_line.account_analytic_id.id or False,
99
move_lines.append(move_line)
102
writeoff_debit = sum([l['debit'] for l in move_lines])
103
writeoff_credit = sum([l['credit'] for l in move_lines])
105
if writeoff_debit > 0 and writeoff_debit != -diff:
106
diff_writeoff = round(-diff - writeoff_debit, 2)
107
move_lines[0]['debit'] = move_lines[0]['debit'] + diff_writeoff
109
if writeoff_credit > 0 and writeoff_credit != diff:
120
def action_move_line_create(self, cr, uid, ids, context=None):
122
Confirm the vouchers given in ids and create the journal entries for each of them
127
move_pool = self.pool.get('account.move')
128
move_line_pool = self.pool.get('account.move.line')
129
for voucher in self.browse(cr, uid, ids, context=context):
132
company_currency = self._get_company_currency(cr, uid, voucher.id, context)
133
current_currency = self._get_current_currency(cr, uid, voucher.id, context)
134
# we select the context to use accordingly if it's a multicurrency case or not
135
context = self._sel_context(cr, uid, voucher.id, context)
136
# But for the operations made by _convert_amount, we always need to give the date in the context
138
ctx.update({'date': voucher.date})
139
# Create the account move record.
140
move_id = move_pool.create(cr, uid, self.account_move_get(cr, uid, voucher.id, context=context), context=context)
141
# Get the name of the account_move just created
142
name = move_pool.browse(cr, uid, move_id, context=context).name
143
# Create the first line of the voucher
144
move_line_id = move_line_pool.create(cr, uid, self.first_move_line_get(cr,uid,voucher.id, move_id, company_currency, current_currency, context), context)
145
move_line_brw = move_line_pool.browse(cr, uid, move_line_id, context=context)
146
line_total = move_line_brw.debit - move_line_brw.credit
148
if voucher.type == 'sale':
149
line_total = line_total - self._convert_amount(cr, uid, voucher.tax_amount, voucher.id, context=ctx)
150
elif voucher.type == 'purchase':
151
line_total = line_total + self._convert_amount(cr, uid, voucher.tax_amount, voucher.id, context=ctx)
152
# Create one move line per voucher line where amount is not 0.0
153
line_total, rec_list_ids = self.voucher_move_line_create(cr, uid, voucher.id, line_total, move_id, company_currency, current_currency, context)
155
# Create the writeoff line if needed
156
ml_writeoff = self.writeoff_move_line_get(cr, uid, voucher.id, line_total, move_id, name, company_currency, current_currency, context)
159
for move_line in ml_writeoff:
160
move_line_pool.create(cr, uid, move_line, context)
161
# We post the voucher.
162
self.write(cr, uid, [voucher.id], {
167
if voucher.journal_id.entry_posted:
168
move_pool.post(cr, uid, [move_id], context={})
169
# We automatically reconcile the account move lines.
171
for rec_ids in rec_list_ids:
172
if len(rec_ids) >= 2:
173
reconcile = move_line_pool.reconcile_partial(cr, uid, rec_ids, writeoff_acc_id=voucher.writeoff_acc_id.id, writeoff_period_id=voucher.period_id.id, writeoff_journal_id=voucher.journal_id.id)