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
24
class msf_instance(osv.osv):
25
_name = 'msf.instance'
27
def _get_current_instance_level(self, cr, uid, ids, fields, arg, context=None):
30
res = dict.fromkeys(ids, False)
31
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
32
if user.company_id and user.company_id.instance_id:
34
res[id] = user.company_id.instance_id.level
37
def _get_top_cost_center(self, cr, uid, ids, fields, arg, context=None):
40
if isinstance(ids, (int, long)):
43
res = dict.fromkeys(ids, False)
44
for instance in self.browse(cr, uid, ids, context=context):
45
if instance.target_cost_center_ids:
46
for target in instance.target_cost_center_ids:
47
if target.is_top_cost_center:
48
res[instance.id] = target.cost_center_id.id
50
elif instance.level == 'section':
51
parent_cost_centers = self.pool.get('account.analytic.account').search(cr, uid, [('category', '=', 'OC'), ('parent_id', '=', '')], context=context)
52
if len(parent_cost_centers) > 0:
53
res[instance.id] = parent_cost_centers[0]
56
def _get_po_fo_cost_center(self, cr, uid, ids, fields, arg, context=None):
59
if isinstance(ids, (int, long)):
62
res = dict.fromkeys(ids, False)
63
for instance in self.browse(cr, uid, ids, context=context):
64
if instance.target_cost_center_ids:
65
for target in instance.target_cost_center_ids:
66
if target.is_po_fo_cost_center:
67
res[instance.id] = target.cost_center_id.id
69
elif instance.level == 'section':
70
parent_cost_centers = self.pool.get('account.analytic.account').search(cr, uid, [('category', '=', 'OC'), ('parent_id', '=', '')], context=context)
71
if len(parent_cost_centers) > 0:
72
res[instance.id] = parent_cost_centers[0]
76
'level': fields.selection([('section', 'Section'),
78
('project', 'Project')], 'Level', required=True),
79
'code': fields.char('Code', size=64, required=True),
80
'mission': fields.char('Mission', size=64),
81
'instance': fields.char('Instance', size=64),
82
#'parent_id': fields.many2one('msf.instance', 'Parent', domain=[('level', '!=', 'project'), ('state', '=', 'active')]),
83
'parent_id': fields.many2one('msf.instance', 'Parent', domain=[('level', '!=', 'project') ]),
84
'child_ids': fields.one2many('msf.instance', 'parent_id', 'Children'),
85
'name': fields.char('Name', size=64, required=True),
86
'note': fields.char('Note', size=256),
87
'target_cost_center_ids': fields.one2many('account.target.costcenter', 'instance_id', 'Target Cost Centers'),
88
'state': fields.selection([('draft', 'Draft'),
90
('inactive', 'Inactive')], 'State', required=True),
91
'move_prefix': fields.char('Account move prefix', size=5, required=True),
92
'reconcile_prefix': fields.char('Reconcilation prefix', size=5, required=True),
93
'current_instance_level': fields.function(_get_current_instance_level, method=True, store=False, string="Current Instance Level", type="char", readonly="True"),
94
'top_cost_center_id': fields.function(_get_top_cost_center, method=True, store=False, string="Top cost centre for budget consolidation", type="many2one", relation="account.analytic.account", readonly="True"),
95
'po_fo_cost_center_id': fields.function(_get_po_fo_cost_center, method=True, store=False, string="Cost centre picked for PO/FO reference", type="many2one", relation="account.analytic.account", readonly="True"),
100
'current_instance_level': 'section', # UTP-941 set the default value to section, otherwise all fields in the new form are readonly
103
def button_cost_center_wizard(self, cr, uid, ids, context=None):
106
if isinstance(ids, (int, long)):
114
'name': "Add Cost Centers",
115
'type': 'ir.actions.act_window',
116
'res_model': 'wizard.add.cost.centers',
118
'view_mode': 'form,tree',
123
def create(self, cr, uid, vals, context=None):
124
# Check if lines are imported from coordo; if now, create those
125
res_id = osv.osv.create(self, cr, uid, vals, context=context)
126
if 'parent_id' in vals and 'level' in vals and vals['level'] == 'project':
127
parent_instance = self.browse(cr, uid, vals['parent_id'], context=context)
128
instance = self.browse(cr, uid, res_id, context=context)
129
if len(parent_instance.target_cost_center_ids) != len(instance.target_cost_center_ids):
130
# delete existing cost center lines
131
old_target_line_ids = [x.id for x in instance.target_cost_center_ids]
132
self.unlink(cr, uid, old_target_line_ids, context=context)
133
# copy existing lines for project
134
for line_to_copy in parent_instance.target_cost_center_ids:
135
self.pool.get('account.target.costcenter').create(cr, uid, {'instance_id': instance.id,
136
'cost_center_id': line_to_copy.cost_center_id.id,
138
'parent_id': line_to_copy.id}, context=context)
142
def _check_name_code_unicity(self, cr, uid, ids, context=None):
145
for instance in self.browse(cr, uid, ids, context=context):
146
bad_ids = self.search(cr, uid, [('&'),
147
('state', '!=', 'inactive'),
149
('name', '=ilike', instance.name),
150
('code', '=ilike', instance.code)])
151
if len(bad_ids) and len(bad_ids) > 1:
155
def onchange_parent_id(self, cr, uid, ids, parent_id, level, context=None):
159
if isinstance(ids, (int, long)):
161
if parent_id and level == 'project':
162
parent_instance = self.browse(cr, uid, parent_id, context=context)
163
for instance in self.browse(cr, uid, ids, context=context):
164
# delete existing cost center lines
165
old_target_line_ids = [x.id for x in instance.target_cost_center_ids]
166
self.unlink(cr, uid, old_target_line_ids, context=context)
167
# copy existing lines for project
168
for line_to_copy in parent_instance.target_cost_center_ids:
169
self.pool.get('account.target.costcenter').create(cr, uid, {'instance_id': instance.id,
170
'cost_center_id': line_to_copy.cost_center_id.id,
172
'parent_id': line_to_copy.id}, context=context)
175
def _check_database_unicity(self, cr, uid, ids, context=None):
178
for instance in self.browse(cr, uid, ids, context=context):
179
bad_ids = self.search(cr, uid, [('&'),
180
('state', '!=', 'inactive'),
182
('instance', '!=', False),
183
('instance', '=', instance.instance)])
184
if len(bad_ids) and len(bad_ids) > 1:
188
def _check_move_prefix_unicity(self, cr, uid, ids, context=None):
191
for instance in self.browse(cr, uid, ids, context=context):
192
bad_ids = self.search(cr, uid, [('&'),
193
('state', '!=', 'inactive'),
194
('move_prefix', '=ilike', instance.move_prefix)])
195
if len(bad_ids) and len(bad_ids) > 1:
199
def _check_reconcile_prefix_unicity(self, cr, uid, ids, context=None):
202
for instance in self.browse(cr, uid, ids, context=context):
203
bad_ids = self.search(cr, uid, [('&'),
204
('state', '!=', 'inactive'),
205
('reconcile_prefix', '=ilike', instance.reconcile_prefix)])
206
if len(bad_ids) and len(bad_ids) > 1:
211
(_check_name_code_unicity, 'You cannot have the same code or name than an active instance!', ['code', 'name']),
212
(_check_database_unicity, 'You cannot have the same database than an active instance!', ['instance']),
213
(_check_move_prefix_unicity, 'You cannot have the same move prefix than an active instance!', ['move_prefix']),
214
(_check_reconcile_prefix_unicity, 'You cannot have the same reconciliation prefix than an active instance!', ['reconcile_prefix']),
217
def name_get(self, cr, user, ids, context=None):
220
result = self.browse(cr, user, ids, context=context)
224
res += [(rs.id, txt)]
225
context['level'] = rs.level
229
def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100):
231
Search Instance regarding their code and their name
239
ids = self.search(cr, uid, [('code', 'ilike', name)]+ args, limit=limit, context=context)
241
ids = self.search(cr, uid, [('name', 'ilike', name)]+ args, limit=limit, context=context)
242
return self.name_get(cr, uid, ids, context=context)
244
def button_deactivate(self, cr, uid, ids, context=None):
248
self.write(cr, uid, ids, {'state': 'inactive'}, context=context)
251
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
253
Override the tree view to display historical prices according to context
257
res = super(msf_instance, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu)
258
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
260
if user.company_id and user.company_id.instance_id:
261
current_instance_level = user.company_id.instance_id.current_instance_level
263
if current_instance_level != 'section':
264
if 'hide_new_button="PROP_INSTANCE_HIDE_BUTTON"' in res['arch']:
265
res['arch'] = res['arch'].replace('hide_duplicate_button="PROP_INSTANCE_HIDE_BUTTON"', 'hide_duplicate_button="1"')
266
res['arch'] = res['arch'].replace('hide_delete_button="PROP_INSTANCE_HIDE_BUTTON"', 'hide_delete_button="1"')
267
res['arch'] = res['arch'].replace('hide_new_button="PROP_INSTANCE_HIDE_BUTTON"', 'hide_new_button="1" noteditable="1" notselectable="0"')
269
if 'target_cost_center_ids' in res['fields']:
270
arch = res['fields']['target_cost_center_ids']['views']['tree']['arch']
271
if 'hide_delete_button="PROP_INSTANCE_HIDE_BUTTON' in arch:
272
res['fields']['target_cost_center_ids']['views']['tree']['arch'] = arch.replace('hide_delete_button="PROP_INSTANCE_HIDE_BUTTON', 'noteditable="1" hide_delete_button="1')
274
if res['type'] == 'form' and 'hide_new_button="PROP_INSTANCE_HIDE_BUTTON"' in res['arch']:
275
res['arch'] = res['arch'].replace('hide_duplicate_button="PROP_INSTANCE_HIDE_BUTTON"', '')
276
res['arch'] = res['arch'].replace('hide_delete_button="PROP_INSTANCE_HIDE_BUTTON"', '')
277
res['arch'] = res['arch'].replace('hide_new_button="PROP_INSTANCE_HIDE_BUTTON"', '')
278
if 'target_cost_center_ids' in res['fields']:
279
arch = res['fields']['target_cost_center_ids']['views']['tree']['arch']
280
if 'hide_delete_button="PROP_INSTANCE_HIDE_BUTTON' in arch:
281
res['fields']['target_cost_center_ids']['views']['tree']['arch'] = arch.replace('PROP_INSTANCE_HIDE_BUTTON', '0')
288
class res_users(osv.osv):
289
_inherit = 'res.users'
292
def get_browse_user_instance(self, cr, uid, context=None):
293
current_user = self.browse(cr, uid, uid, context=context)
294
return current_user and current_user.company_id and current_user.company_id.instance_id or False
296
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: