1
# -*- coding: utf-8 -*-
2
##############################################################################
4
# OpenERP, Open Source Management Solution
5
# Copyright (C) 2011 MSF, TeMPO Consulting.
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 osv import fields, osv
23
from tools.translate import _
25
from dateutil.relativedelta import relativedelta
27
class wizard_accrual_validation(osv.osv_memory):
28
_name = 'wizard.accrual.validation'
30
def button_confirm(self, cr, uid, ids, context=None):
33
accrual_line_obj = self.pool.get('msf.accrual.line')
34
period_obj = self.pool.get('account.period')
35
move_obj = self.pool.get('account.move')
36
move_line_obj = self.pool.get('account.move.line')
37
if 'active_ids' in context:
38
for accrual_line in accrual_line_obj.browse(cr, uid, context['active_ids'], context=context):
39
# check for periods, distribution, etc.
40
if accrual_line.state == 'posted':
41
raise osv.except_osv(_('Warning !'), _("The line '%s' is already posted!" % accrual_line.description))
42
elif not accrual_line.period_id:
43
raise osv.except_osv(_('Warning !'), _("The line '%s' has no period set!" % accrual_line.description))
44
elif not accrual_line.analytic_distribution_id:
45
raise osv.except_osv(_('Warning !'), _("The line '%s' has no analytic distribution!" % accrual_line.description))
47
move_date = accrual_line.period_id.date_stop
48
reversal_move_date = (datetime.datetime.strptime(move_date, '%Y-%m-%d') + relativedelta(days=1)).strftime('%Y-%m-%d')
49
# check if periods are open
50
reversal_period_ids = period_obj.find(cr, uid, reversal_move_date, context=context)
51
if len(reversal_period_ids) == 0:
52
raise osv.except_osv(_('Warning !'), _("No period (M+1) was found in the system!"))
54
reversal_period_id = reversal_period_ids[0]
55
reversal_period = period_obj.browse(cr, uid, reversal_period_id, context=context)
56
if accrual_line.period_id.state != 'draft':
57
raise osv.except_osv(_('Warning !'), _("The period '%s' is not open!" % accrual_line.period_id.name))
58
elif reversal_period.state != 'draft':
59
raise osv.except_osv(_('Warning !'), _("The reversal period '%s' is not open!" % reversal_period.name))
63
'ref': accrual_line.reference,
64
'period_id': accrual_line.period_id.id,
65
'journal_id': accrual_line.journal_id.id,
68
reversal_move_vals = {
69
'ref': accrual_line.reference,
70
'period_id': reversal_period_id,
71
'journal_id': accrual_line.journal_id.id,
72
'date': reversal_move_date
74
move_id = move_obj.create(cr, uid, move_vals, context=context)
75
reversal_move_id = move_obj.create(cr, uid, reversal_move_vals, context=context)
78
accrual_move_line_vals = {
81
'journal_id': accrual_line.journal_id.id,
82
'period_id': accrual_line.period_id.id,
83
'reference': accrual_line.reference,
84
'name': accrual_line.description,
85
'account_id': accrual_line.accrual_account_id.id,
86
'partner_id': ((accrual_line.partner_id) and accrual_line.partner_id.id) or False,
87
'employee_id': ((accrual_line.employee_id) and accrual_line.employee_id.id) or False,
88
'credit': accrual_line.accrual_amount,
89
'currency_id': accrual_line.currency_id.id,
91
expense_move_line_vals = {
94
'journal_id': accrual_line.journal_id.id,
95
'period_id': accrual_line.period_id.id,
96
'reference': accrual_line.reference,
97
'name': accrual_line.description,
98
'account_id': accrual_line.expense_account_id.id,
99
'partner_id': ((accrual_line.partner_id) and accrual_line.partner_id.id) or False,
100
'employee_id': ((accrual_line.employee_id) and accrual_line.employee_id.id) or False,
101
'debit': accrual_line.accrual_amount,
102
'currency_id': accrual_line.currency_id.id,
103
'analytic_distribution_id': accrual_line.analytic_distribution_id.id,
107
reversal_accrual_move_line_vals = {
108
'move_id': reversal_move_id,
109
'date': reversal_move_date,
110
'journal_id': accrual_line.journal_id.id,
111
'period_id': reversal_period_id,
112
'reference': accrual_line.reference,
113
'name': accrual_line.description,
114
'account_id': accrual_line.accrual_account_id.id,
115
'partner_id': ((accrual_line.partner_id) and accrual_line.partner_id.id) or False,
116
'employee_id': ((accrual_line.employee_id) and accrual_line.employee_id.id) or False,
117
'debit': accrual_line.accrual_amount,
118
'currency_id': accrual_line.currency_id.id,
120
reversal_expense_move_line_vals = {
121
'move_id': reversal_move_id,
122
'date': reversal_move_date,
123
'journal_id': accrual_line.journal_id.id,
124
'period_id': reversal_period_id,
125
'reference': accrual_line.reference,
126
'name': accrual_line.description,
127
'account_id': accrual_line.expense_account_id.id,
128
'partner_id': ((accrual_line.partner_id) and accrual_line.partner_id.id) or False,
129
'employee_id': ((accrual_line.employee_id) and accrual_line.employee_id.id) or False,
130
'credit': accrual_line.accrual_amount,
131
'currency_id': accrual_line.currency_id.id,
132
'analytic_distribution_id': accrual_line.analytic_distribution_id.id,
135
accrual_move_line_id = move_line_obj.create(cr, uid, accrual_move_line_vals, context=context)
136
expense_move_line_id = move_line_obj.create(cr, uid, expense_move_line_vals, context=context)
137
reversal_accrual_move_line_id = move_line_obj.create(cr, uid, reversal_accrual_move_line_vals, context=context)
138
reversal_expense_move_line_id = move_line_obj.create(cr, uid, reversal_expense_move_line_vals, context=context)
141
move_obj.post(cr, uid, [move_id, reversal_move_id], context=context)
142
# Reconcile the accrual move line with its reversal
143
move_line_obj.reconcile_partial(cr, uid, [accrual_move_line_id, reversal_accrual_move_line_id], context=context)
144
# validate the accrual line
145
accrual_line_obj.write(cr, uid, [accrual_line.id], {'state': 'posted'}, context=context)
148
return {'type' : 'ir.actions.act_window_close'}
150
wizard_accrual_validation()
151
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: