~unifield-team/unifield-wm/us-826

« back to all changes in this revision

Viewing changes to msf_budget/msf_budget.py

  • Committer: matthieu.choplin at msf
  • Date: 2012-08-30 07:48:00 UTC
  • mto: This revision was merged to the branch mainline in revision 1118.
  • Revision ID: matthieu.choplin@geneva.msf.org-20120830074800-l442bu42mt0yzutn
[uf-1374]- change the write and create by an _sql_constraint on the financing contract check dates

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
    _name = "msf.budget"
29
29
    _description = 'MSF Budget'
30
30
    _trace = True
31
 
 
 
31
    
32
32
    def _get_total_budget_amounts(self, cr, uid, ids, field_names=None, arg=None, context=None):
33
33
        res = {}
34
 
        sql = """
35
 
        SELECT expense.budget_id, COALESCE(expense.total, 0.0) - COALESCE(income.total, 0.0) AS diff
36
 
        FROM (
37
 
            SELECT budget_id, SUM(COALESCE(month1 + month2 + month3 + month4 + month5 + month6 + month7 + month8 + month9 + month10 + month11 + month12, 0.0)) AS total
38
 
            FROM msf_budget_line AS l, account_account AS a, account_account_type AS t
39
 
            WHERE budget_id IN %s
40
 
            AND l.account_id = a.id
41
 
            AND a.user_type = t.id
42
 
            AND t.code = 'expense'
43
 
            AND a.type != 'view'
44
 
            AND l.line_type = 'destination'
45
 
            GROUP BY budget_id
46
 
        ) AS expense
47
 
        LEFT JOIN (
48
 
            SELECT budget_id, SUM(COALESCE(month1 + month2 + month3 + month4 + month5 + month6 + month7 + month8 + month9 + month10 + month11 + month12, 0.0)) AS total
49
 
            FROM msf_budget_line AS l, account_account AS a, account_account_type AS t
50
 
            WHERE budget_id IN %s
51
 
            AND l.account_id = a.id
52
 
            AND a.user_type = t.id
53
 
            AND t.code = 'income'
54
 
            AND a.type != 'view'
55
 
            AND l.line_type = 'destination'
56
 
            GROUP BY budget_id
57
 
        ) AS income ON expense.budget_id = income.budget_id"""
58
 
        cr.execute(sql, (tuple(ids),tuple(ids),))
59
 
        tmp_res = cr.fetchall()
60
 
        if not tmp_res:
61
 
            return res
62
 
        for b_id in ids:
63
 
            res.setdefault(b_id, 0.0)
64
 
        res.update(dict(tmp_res))
65
 
        return res
66
 
 
67
 
    def _get_instance_type(self, cr, uid, ids, field_names=None, arg=None, context=None):
68
 
        """
69
 
        Retrieve instance type regarding cost center id and check on instances which one have this cost center as "top cost center for budget"
70
 
        """
71
 
        if not context:
72
 
            context = {}
73
 
        res = {}
74
 
        for budget in self.browse(cr, uid, ids):
75
 
            res[budget.id] = 'project'
76
 
            if budget.cost_center_id:
77
 
                target_ids = self.pool.get('account.target.costcenter').search(cr, uid, [('cost_center_id', '=', budget.cost_center_id.id), ('is_top_cost_center', '=', True), ('instance_id.level', '=', 'coordo')])
78
 
                if target_ids:
79
 
                    res[budget.id] = 'coordo'
80
 
            if not budget.cost_center_id.parent_id:
81
 
                res[budget.id] = 'section'
82
 
        return res
83
 
 
84
 
    def _search_instance_type(self, cr, uid, obj, name, args, context=None):
85
 
        """
86
 
        Search all budget that have a cost coster used in a top_cost_center for an instance for the given type
87
 
        """
88
 
        res = []
89
 
        if not context:
90
 
            context = {}
91
 
        if not args:
92
 
            return res
93
 
        if args[0] and args[0][2]:
94
 
            target_ids = self.pool.get('account.target.costcenter').search(cr, uid, [('is_top_cost_center', '=', True), ('instance_id.level', '=', 'coordo')])
95
 
            coordo_ids = [x and x.cost_center_id and x.cost_center_id.id for x in self.pool.get('account.target.costcenter').browse(cr, uid, target_ids)]
96
 
            hq_ids = self.pool.get('account.analytic.account').search(cr, uid, [('parent_id', '=', False)])
97
 
            if isinstance(hq_ids, (int, long)):
98
 
                hq_ids = [hq_ids]
99
 
            if args[0][2] == 'section':
100
 
                return [('cost_center_id', 'in', hq_ids)]
101
 
            elif args[0][2] == 'coordo':
102
 
                return [('cost_center_id', 'in', coordo_ids)]
103
 
            elif args[0][2] == 'project':
104
 
                return [('cost_center_id', 'not in', hq_ids), ('cost_center_id', 'not in', coordo_ids)]
105
 
        return res
106
 
 
 
34
        
 
35
        for budget in self.browse(cr, uid, ids, context=context):
 
36
            total_amounts = self.pool.get('msf.budget.line')._get_total_amounts(cr, uid, [x.id for x in budget.budget_line_ids], context=context)
 
37
            
 
38
            budget_amount = 0.0
 
39
            for budget_line in budget.budget_line_ids:
 
40
                if not budget_line.parent_id:
 
41
                    res[budget.id] = total_amounts[budget_line.id]['budget_amount']
 
42
                    break
 
43
        
 
44
        return res
 
45
    
107
46
    _columns = {
108
47
        'name': fields.char('Name', size=64, required=True),
109
48
        'code': fields.char('Code', size=64, required=True),
114
53
        'decision_moment_order': fields.related('decision_moment_id', 'order', string="Decision Moment Order", readonly=True, store=True, type="integer"),
115
54
        'version': fields.integer('Version'),
116
55
        'currency_id': fields.many2one('res.currency', 'Currency', required=True),
 
56
        'display_type': fields.selection([('all', 'Expenses and destinations'),
 
57
                                          ('expense', 'Expenses only'),
 
58
                                          ('view', 'Parent expenses only')], string="Display type"),
117
59
        'type': fields.selection([('normal', 'Normal'), ('view', 'View')], string="Budget type"),
118
 
        'total_budget_amount': fields.function(_get_total_budget_amounts, method=True, store=False, string="Total Budget Amount", type="float", readonly=True),
119
 
        'instance_type': fields.function(_get_instance_type, fnct_search=_search_instance_type, method=True, store=False, string='Instance type', type='selection', selection=[('section', 'HQ'), ('coordo', 'Coordo'), ('project', 'Project')], readonly=True),
 
60
        'total_budget_amount': fields.function(_get_total_budget_amounts, method=True, store=False, string="Total Budget Amount", type="float", readonly="True"),
120
61
    }
121
 
 
 
62
    
122
63
    _defaults = {
123
64
        'currency_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.currency_id.id,
124
65
        'state': 'draft',
 
66
        'display_type': 'all',
125
67
        'type': 'normal',
126
68
    }
127
69
 
128
70
    _order = 'decision_moment_order desc, version, code'
129
 
 
130
 
    def _check_parent(self, cr, uid, vals, context=None):
131
 
        """
132
 
        Check budget's parent to see if it exist.
133
 
        Create it if we're on another instance that top cost center one.
134
 
        Note: context can contains a list of budget lines. This permit to avoid problem of budget line template time consuming.
135
 
        We hope the copy() will take less time than the creation of an entire budget template.
136
 
        """
137
 
        # Some checks
138
 
        if context is None:
139
 
            context = {}
140
 
        # Prepare some values
141
 
        top_cost_center = self.pool.get('res.users').browse(cr, uid, uid).company_id.instance_id.top_cost_center_id
142
 
        ana_obj = self.pool.get('account.analytic.account')
143
 
        fy_obj = self.pool.get('account.fiscalyear')
144
 
        tool_obj = self.pool.get('msf.budget.tools')
145
 
        # Fetch cost center info (id and parent)
146
 
        cc_id = vals.get('cost_center_id', False)
147
 
        cc = ana_obj.read(cr, uid, cc_id, ['parent_id'], context=context)
148
 
        parent_id = cc.get('parent_id', False) and cc.get('parent_id')[0] or False
149
 
        # Fetch fiscalyear info
150
 
        fy_id = vals.get('fiscalyear_id', False)
151
 
        fy = fy_obj.read(cr, uid, fy_id, ['code'])
152
 
        # Fetch decision moment id
153
 
        decision_moment_id = vals.get('decision_moment_id', False)
154
 
 
155
 
        # Check that no parent cost center exists for the given values
156
 
        if cc_id and cc_id != top_cost_center.id and parent_id:
157
 
            parent_cost_center = ana_obj.read(cr, uid, parent_id, ['code', 'name'], context=context)
158
 
            have_parent_budget = self.search(cr, uid, [('fiscalyear_id', '=', fy_id), ('cost_center_id', '=', parent_id), ('decision_moment_id', '=', decision_moment_id)], count=1, context=context)
159
 
            if have_parent_budget == 0:
160
 
                # Create budget's parent
161
 
                budget_vals = {
162
 
                    'name': "Budget " + fy.get('code', '')[4:6] + " - " + parent_cost_center.get('name', ''),
163
 
                    'code': "BU" + fy.get('code')[4:6] + " - " + parent_cost_center.get('code', ''),
164
 
                    'fiscalyear_id': fy_id,
165
 
                    'cost_center_id': parent_id,
166
 
                    'decision_moment_id': decision_moment_id,
167
 
                    'type': 'view'
168
 
                }
169
 
                parent_budget_id = self.create(cr, uid, budget_vals, context=context)
170
 
                # Create budget's line.
171
 
                tool_obj.create_budget_lines(cr, uid, parent_budget_id, context=context)
172
 
                # Validate this parent
173
 
                self.write(cr, uid, [parent_budget_id], {'state': 'valid'}, context=context)
174
 
        return True
175
 
 
 
71
    
176
72
    def create(self, cr, uid, vals, context=None):
177
 
        """
178
 
        Create a budget then check its parent.
179
 
        """
180
73
        res = super(msf_budget, self).create(cr, uid, vals, context=context)
181
 
        # Check parent budget
182
 
        self._check_parent(cr, uid, vals, context=context)
183
 
        return res
184
 
 
185
 
    def write(self, cr, uid, ids, vals, context=None):
186
 
        """
187
 
        Goal is to update parent budget regarding these criteria:
188
 
          - context is synchronization
189
 
          - state is in vals
190
 
          - state is different from draft (validated or done)
191
 
        """
192
 
 
193
 
        if not ids:
194
 
            return True
195
 
        if context is None:
196
 
            context = {}
197
 
        res = super(msf_budget, self).write(cr, uid, ids, vals, context=context)
198
 
        if context.get('sync_update_execution', False) and vals.get('state', False) and vals.get('state') != 'draft':
199
 
            # Update parent budget
200
 
            self.update_parent_budgets(cr, uid, ids, context=context)
201
 
 
202
 
        budget = self.browse(cr, uid, ids, context=context)[0]
203
 
        if budget.type == 'normal' and vals.get('state') == 'done':  # do not process for view accounts
204
 
            ala_obj = self.pool.get('account.analytic.account')
205
 
            # get parent cc
206
 
            cc_parent_ids = ala_obj._get_parent_of(cr, uid, budget.cost_center_id.id, context=context)
207
 
            # exclude the cc of the current budget line
208
 
            parent_cc_ids = [x for x in cc_parent_ids if x != budget.cost_center_id.id]
209
 
            # find all ccs which have the same parent
210
 
            all_cc_ids = ala_obj.search(cr, uid, [('parent_id','in',parent_cc_ids)], context=context)
211
 
            # remove parent ccs from the list
212
 
            peer_cc_ids = [x for x in all_cc_ids if x not in parent_cc_ids]
213
 
            # find peer budget lines based on cc
214
 
            peer_budget_ids = self.search(cr, uid, [('cost_center_id','in',peer_cc_ids),('decision_moment_id','=',budget.decision_moment_id.id),('fiscalyear_id','=',budget.fiscalyear_id.id),'!',('id','=',budget.id)],context=context)
215
 
            peer_budgets = self.browse(cr, uid, peer_budget_ids, context=context)
216
 
 
217
 
            all_done = True
218
 
            for peer in peer_budgets:
219
 
                if peer.state != 'done':
220
 
                    all_done = False
221
 
            if all_done == True:
222
 
                parent_ids = self.search(cr, uid, [('cost_center_id', 'in', parent_cc_ids),('decision_moment_id','=',budget.decision_moment_id.id),('fiscalyear_id','=',budget.fiscalyear_id.id),'!',('state','=','done')],context=context)
223
 
                self.write(cr, uid, parent_ids, {'state': 'done'},context=context)
224
 
        return res
225
 
 
226
 
    def update(self, cr, uid, ids, context=None):
227
 
        """
228
 
        Update given budget. But only update view one.
229
 
        """
230
 
        # Some checks
231
 
        if context is None:
232
 
            context = {}
233
 
        if isinstance(ids, (int, long)):
234
 
            ids = [ids]
235
 
        # Prepare some values
236
 
        ana_obj = self.pool.get('account.analytic.account')
237
 
        line_obj = self.pool.get('msf.budget.line')
238
 
        sql = """
239
 
            SELECT
240
 
                SUM(COALESCE(month1, 0)),
241
 
                SUM(COALESCE(month2, 0)),
242
 
                SUM(COALESCE(month3, 0)),
243
 
                SUM(COALESCE(month4, 0)),
244
 
                SUM(COALESCE(month5, 0)),
245
 
                SUM(COALESCE(month6, 0)),
246
 
                SUM(COALESCE(month7, 0)),
247
 
                SUM(COALESCE(month8, 0)),
248
 
                SUM(COALESCE(month9, 0)),
249
 
                SUM(COALESCE(month10, 0)),
250
 
                SUM(COALESCE(month11, 0)),
251
 
                SUM(COALESCE(month12, 0))
252
 
            FROM msf_budget_line
253
 
            WHERE id IN %s"""
254
 
        # Filter budget to only update those that are view one
255
 
        to_update = self.search(cr, uid, [('id', 'in', ids), ('type', '=', 'view')])
256
 
        # Then update budget, one by one, line by line...
257
 
        for budget in self.browse(cr, uid, to_update, context=context):
258
 
            cost_center_id = budget.cost_center_id and budget.cost_center_id.id or False
259
 
            if not cost_center_id:
260
 
                raise osv.except_osv(_('Error'), _('Problem while reading Cost Center for the given budget: %s') % (budget.get('name', ''),))
261
 
            child_cc_ids = ana_obj.search(cr, uid, [('parent_id', 'child_of', cost_center_id)])
262
 
            budget_ids = []
263
 
            # For each CC, search the last budget
264
 
            for cc_id in child_cc_ids:
265
 
                cc_args = [
266
 
                    ('cost_center_id', '=', cc_id),
267
 
                    ('type', '!=', 'view'),
268
 
                    ('state', '!=', 'draft'),
269
 
                    ('decision_moment_id', '=', budget.decision_moment_id.id)
270
 
                ]
271
 
                corresponding_budget_ids = self.search(cr, uid, cc_args, limit=1, order='version DESC')
272
 
                if corresponding_budget_ids:
273
 
                    budget_ids.append(corresponding_budget_ids)
274
 
            # Browse each budget line to update it
275
 
            for budget_line in budget.budget_line_ids:
276
 
                line_vals = {
277
 
                    'month1': 0.0,
278
 
                    'month2': 0.0,
279
 
                    'month3': 0.0,
280
 
                    'month4': 0.0,
281
 
                    'month5': 0.0,
282
 
                    'month6': 0.0,
283
 
                    'month7': 0.0,
284
 
                    'month8': 0.0,
285
 
                    'month9': 0.0,
286
 
                    'month10': 0.0,
287
 
                    'month11': 0.0,
288
 
                    'month12': 0.0
289
 
                }
290
 
                # search all linked budget lines
291
 
                args = [('budget_id', 'in', budget_ids), ('account_id', '=', budget_line.account_id.id), ('line_type', '=', budget_line.line_type)]
292
 
                if budget_line.destination_id:
293
 
                    args.append(('destination_id', '=', budget_line.destination_id.id))
294
 
                child_line_ids = line_obj.search(cr, uid, args, context=context)
295
 
                if child_line_ids:
296
 
                    cr.execute(sql, (tuple(child_line_ids),))
297
 
                    if cr.rowcount:
298
 
                        tmp_res = cr.fetchall()
299
 
                        res = tmp_res and tmp_res[0]
300
 
                        if res:
301
 
                            for x in xrange(1, 13, 1):
302
 
                                try:
303
 
                                    line_vals.update({'month'+str(x): res[x - 1]})
304
 
                                except IndexError:
305
 
                                    continue
306
 
                line_obj.write(cr, uid, [budget_line.id], line_vals)
307
 
        return True
308
 
 
309
 
    def update_parent_budgets(self, cr, uid, ids, context=None):
310
 
        """
311
 
        Search all parent budget and update them.
312
 
        """
313
 
        # Some checks
314
 
        if context is None:
315
 
            context = {}
316
 
        if isinstance(ids, (int, long)):
317
 
            ids = [ids]
318
 
        # We only need to update parent budgets.
319
 
        # So we search all parent cost center (but only them, so we don't care about cost center that are linked to given budgets)
320
 
        # Then we use these parent cost center to find budget to update (only budget lines)
321
 
        budgets = self.read(cr, uid, ids, ['cost_center_id'])
322
 
        cost_center_ids = [x.get('cost_center_id', False) and x.get('cost_center_id')[0] or 0 for x in budgets]
323
 
        cc_parent_ids = self.pool.get('account.analytic.account')._get_parent_of(cr, uid, cost_center_ids, context=context)
324
 
        parent_ids = [x for x in cc_parent_ids if x not in cost_center_ids]
325
 
        to_update = self.search(cr, uid, [('cost_center_id', 'in', parent_ids)])
326
 
        # Update budgets
327
 
        self.update(cr, uid, to_update, context=context)
328
 
        return True
329
 
 
 
74
        # If the "parent" budget does not exist and we're not on the proprietary instance level already, create it.
 
75
        budget = self.browse(cr, uid, res, context=context)
 
76
        prop_instance_cost_center = self.pool.get('res.users').browse(cr, uid, uid).company_id.instance_id.cost_center_id.id
 
77
        if budget.cost_center_id and budget.cost_center_id.id != prop_instance_cost_center and budget.cost_center_id.parent_id:
 
78
            parent_cost_center = budget.cost_center_id.parent_id
 
79
            parent_budget_ids = self.search(cr,
 
80
                                            uid,
 
81
                                            [('fiscalyear_id','=',budget.fiscalyear_id.id),
 
82
                                             ('cost_center_id','=',parent_cost_center.id),
 
83
                                             ('decision_moment_id','=',budget.decision_moment_id.id)])
 
84
            if len(parent_budget_ids) == 0:
 
85
                parent_budget_id = self.create(cr,
 
86
                                               uid,
 
87
                                               {'name': "Budget " + budget.fiscalyear_id.code[4:6] + " - " + parent_cost_center.name,
 
88
                                                'code': "BU" + budget.fiscalyear_id.code[4:6] + " - " + parent_cost_center.code,
 
89
                                                'fiscalyear_id': budget.fiscalyear_id.id,
 
90
                                                'cost_center_id': budget.cost_center_id.parent_id.id,
 
91
                                                'decision_moment_id': budget.decision_moment_id.id,
 
92
                                                'type': 'view'}, context=context)
 
93
                # Create all lines for all accounts/destinations (no budget values, those are retrieved)
 
94
                expense_account_ids = self.pool.get('account.account').search(cr, uid, [('user_type_code', '=', 'expense'),
 
95
                                                                                        ('user_type_report_type', '=', 'expense'),
 
96
                                                                                        ('type', '!=', 'view')], context=context)
 
97
                destination_obj = self.pool.get('account.destination.link')
 
98
                destination_link_ids = destination_obj.search(cr, uid, [('account_id', 'in',  expense_account_ids)], context=context)
 
99
                account_destination_ids = [(dest.account_id.id, dest.destination_id.id)
 
100
                                           for dest
 
101
                                           in destination_obj.browse(cr, uid, destination_link_ids, context=context)]
 
102
                for account_id, destination_id in account_destination_ids:
 
103
                    budget_line_vals = {'budget_id': parent_budget_id,
 
104
                                        'account_id': account_id,
 
105
                                        'destination_id': destination_id,
 
106
                                        'line_type': 'destination'}
 
107
                    self.pool.get('msf.budget.line').create(cr, uid, budget_line_vals, context=context)
 
108
                # validate this parent
 
109
                self.write(cr, uid, [parent_budget_id], {'state': 'valid'}, context=context)
 
110
        return res
 
111
    
 
112
    # Methods for display view lines (warning, dirty, but it works)
330
113
    def button_display_type(self, cr, uid, ids, context=None, *args, **kwargs):
331
114
        """
332
 
        Just reset the budget view to give the context to the one2many_budget_lines object
 
115
        Change display type
333
116
        """
334
 
        if context is None:
335
 
            context = {}
336
 
        if isinstance(ids, (int, long)):
337
 
            ids = [ids]
338
 
        # do not erase the previous context!
339
 
        context.update({
340
 
            'active_id': ids[0],
341
 
            'active_ids': ids,
342
 
        })
 
117
        display_types = {}
 
118
        for budget in self.read(cr, uid, ids, ['display_type']):
 
119
            display_types[budget['id']] = budget['display_type']
 
120
            
 
121
        for budget_id in ids:
 
122
            result = 'all'
 
123
            if display_types[budget_id] == 'all':
 
124
                result = 'expense'
 
125
            elif display_types[budget_id] == 'expense':
 
126
                result = 'view'
 
127
            elif display_types[budget_id] == 'view':
 
128
                result = 'all'
 
129
            self.write(cr, uid, [budget_id], {'display_type': result}, context=context)
 
130
        return True
 
131
    
 
132
    
 
133
    def budget_summary_open_window(self, cr, uid, ids, context=None):
 
134
        parent_line_id = False
 
135
        fiscalyear_id = self.pool.get('account.fiscalyear').find(cr, uid, datetime.date.today(), True, context=context)
 
136
        cost_center_ids = self.pool.get('account.analytic.account').search(cr, uid, [('category', '=', 'OC'), ('parent_id', '=', False)], context=context)                       
 
137
        if len(cost_center_ids) != 0:
 
138
            cr.execute("SELECT id FROM msf_budget WHERE fiscalyear_id = %s \
 
139
                                                    AND cost_center_id = %s \
 
140
                                                    AND state != 'draft' \
 
141
                                                    ORDER BY decision_moment_order DESC, version DESC LIMIT 1",
 
142
                                                    (fiscalyear_id,
 
143
                                                     cost_center_ids[0]))
 
144
            if cr.rowcount:
 
145
                # A budget was found
 
146
                budget_id = cr.fetchall()[0][0]
 
147
                parent_line_id = self.pool.get('msf.budget.summary').create(cr,
 
148
                                                                            uid,
 
149
                                                                            {'budget_id': budget_id},
 
150
                                                                            context=context)
 
151
        
343
152
        return {
344
 
            'name': _('Budgets'),
345
 
            'type': 'ir.actions.act_window',
346
 
            'res_model': 'msf.budget',
347
 
            'target': 'crush',
348
 
            'view_mode': 'form,tree',
349
 
            'view_type': 'form',
350
 
            'res_id': ids[0],
351
 
            'context': context,
 
153
               'type': 'ir.actions.act_window',
 
154
               'res_model': 'msf.budget.summary',
 
155
               'view_type': 'tree',
 
156
               'view_mode': 'tree',
 
157
               'target': 'current',
 
158
               'domain': [('id', '=', parent_line_id)],
 
159
               'context': context
352
160
        }
353
 
 
354
 
    def budget_summary_open_window(self, cr, uid, ids, context=None):
355
 
        budget_id = False
356
 
        if not ids:
357
 
            fiscalyear_id = self.pool.get('account.fiscalyear').find(cr, uid, datetime.date.today(), True, context=context)
358
 
            prop_instance = self.pool.get('res.users').browse(cr, uid, uid).company_id.instance_id
359
 
            if prop_instance.top_cost_center_id:
360
 
                cr.execute("SELECT id FROM msf_budget WHERE fiscalyear_id = %s \
361
 
                            AND cost_center_id = %s \
362
 
                            AND state != 'draft' \
363
 
                            ORDER BY decision_moment_order DESC, version DESC LIMIT 1",
364
 
                            (fiscalyear_id,
365
 
                             prop_instance.top_cost_center_id.id))
366
 
                if cr.rowcount:
367
 
                    # A budget was found
368
 
                    budget_id = cr.fetchall()[0][0]
369
 
        else:
370
 
            if isinstance(ids, (int, long)):
371
 
                ids = [ids]
372
 
            budget_id = ids[0]
373
 
 
374
 
        if budget_id:
375
 
            parent_line_id = self.pool.get('msf.budget.summary').create(cr,
376
 
                uid, {'budget_id': budget_id}, context=context)
377
 
            if parent_line_id:
378
 
                context.update({'display_fp': True})
379
 
                return {
380
 
                       'type': 'ir.actions.act_window',
381
 
                       'res_model': 'msf.budget.summary',
382
 
                       'view_type': 'tree',
383
 
                       'view_mode': 'tree',
384
 
                       'target': 'current',
385
 
                       'domain': [('id', '=', parent_line_id)],
386
 
                       'context': context
387
 
                }
388
 
        return {}
389
 
 
390
 
    def action_confirmed(self, cr, uid, ids, context=None):
391
 
        """
392
 
        At budget validation we should update all parent budgets.
393
 
        To do this, each parent need to take all its validated children budget at the last version.
394
 
        """
395
 
        # Some checks
396
 
        if context is None:
397
 
            context = {}
398
 
        if isinstance(ids, (int, long)):
399
 
            ids = [ids]
400
 
        # Only validate budget that are draft!
401
 
        to_validate = []
402
 
        for budget in self.read(cr, uid, ids, ['state']):
403
 
            if budget.get('state', '') and budget.get('state') == 'draft':
404
 
                to_validate.append(budget.get('id', 0))
405
 
        # Change budget statuses. Important in order to include given budgets in their parents!
406
 
        self.write(cr, uid, to_validate, {'state': 'valid'}, context=context)
407
 
        # Update parent budget
408
 
        self.update_parent_budgets(cr, uid, to_validate, context=context)
409
 
        return True
410
 
 
411
 
    def unlink(self, cr, uid, ids, context=None):
412
 
        '''
413
 
        UFTP-156: Make sure that the validated budget cannot be deleted
414
 
        '''
415
 
        for budget in self.browse(cr, uid, ids, context=context):
416
 
            if budget.state == 'valid':
417
 
                raise osv.except_osv(_('Error'), _('You cannot delete the validated budget!'))
418
 
 
419
 
        return super(msf_budget, self).unlink(cr, uid, budget.id, context=context)
420
 
 
 
161
        
421
162
msf_budget()
422
163
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: