1
1
from odoo import models , fields , api
2
+ from odoo .exceptions import ValidationError , UserError
3
+
2
4
3
5
class BudgetLine (models .Model ):
4
6
_name = "budget.management.budget.lines"
7
+ _description = "Budget Management Budget Lines"
5
8
6
- name = fields .Char ()
7
- budget_id = fields .Many2one (comodel_name = "budget.budget" , string = "Budget" )
8
- budget_amount = fields .Float (default = 0.0 )
9
- achieved_amount = fields .Float (default = 0.0 )
9
+ name = fields .Char (string = "Name" )
10
+ budget_id = fields .Many2one (
11
+ comodel_name = "budget.budget" , string = "Budget" , required = True
12
+ )
13
+ state = fields .Selection (related = "budget_id.state" )
14
+ budget_amount = fields .Monetary (
15
+ string = "Budget Amount" ,
16
+ default = 0.0 ,
17
+ currency_field = "currency_id" ,
18
+ help = "The total allocated budget for this budget line." ,
19
+ )
20
+ achieved_amount = fields .Monetary (
21
+ string = "Achieved Amount" ,
22
+ default = 0.0 ,
23
+ compute = "_compute_achieved_amount" ,
24
+ store = True ,
25
+ currency_field = "currency_id" ,
26
+ )
10
27
achieved_percentage = fields .Float (
11
- default = 0.0 ,
12
- compute = "_compute_achieved_percentage" ,
13
- store = True
14
- )
15
- analytic_account_id = fields .Many2one ('account.analytic.account' , string = 'Analytic Account' )
16
- # analytic_line_ids = fields.One2many('account.analytic.line', string='Analytic Account')
17
-
18
- @api .depends ("budget_amount" , "achieved_amount" )
19
- def _compute_achieved_percentage (self ):
28
+ string = "Achieved (%)" ,
29
+ compute = "_compute_achieved_amount" ,
30
+ store = True ,
31
+ readonly = True ,
32
+ help = "Percentage of the budget achieved based on analytic lines." ,
33
+ )
34
+ analytic_account_id = fields .Many2one (
35
+ "account.analytic.account" , string = "Analytic Account" , required = True
36
+ )
37
+ analytic_line_ids = fields .One2many (
38
+ comodel_name = "account.analytic.line" ,
39
+ inverse_name = "budget_line_id" ,
40
+ string = "Analytic Lines" ,
41
+ )
42
+ over_budget = fields .Monetary (
43
+ string = "Over Budget" ,
44
+ compute = "_compute_achieved_amount" ,
45
+ store = True ,
46
+ help = "The amount by which the budget line exceeds its allocated budget." ,
47
+ currency_field = "currency_id" ,
48
+ )
49
+ currency_id = fields .Many2one (
50
+ comodel_name = "res.currency" ,
51
+ related = "budget_id.currency_id" ,
52
+ string = "Currency" ,
53
+ readonly = True ,
54
+ )
55
+
56
+ @api .depends ("analytic_line_ids.amount" )
57
+ def _compute_achieved_amount (self ):
20
58
for record in self :
21
- if record .budget_amount :
22
- record .achieved_percentage = (record .achieved_amount / record .budget_amount ) * 100
59
+ record .achieved_amount = sum (record .analytic_line_ids .mapped ("amount" ))
60
+ record .achieved_percentage = (
61
+ (record .achieved_amount / record .budget_amount ) * 100
62
+ if record .budget_amount > 0
63
+ else 0.0
64
+ )
65
+ record .over_budget = max (0.0 , record .achieved_amount - record .budget_amount )
66
+
67
+ if (
68
+ record .budget_id .on_over_budget == "warning"
69
+ and record .achieved_amount > record .budget_amount
70
+ ):
71
+ record .budget_id .warnings = "Achived amount is more than your budget!"
23
72
else :
24
- record .achieved_percentage = 0.0
73
+ record .budget_id .warnings = False
74
+
75
+ @api .constrains ("budget_amount" )
76
+ def _check_budget_amount (self ):
77
+ for record in self :
78
+ if record .budget_amount < 0 :
79
+ raise ValidationError ("Budget amount cannot be negative." )
80
+
81
+
82
+ @api .model_create_multi
83
+ def create (self , vals_list ):
84
+ active_budget = None
85
+ if self .env .context .get ("active_id" ):
86
+ active_budget = self .env ["budget.budget" ].browse (self .env .context .get ("active_id" ))
87
+ if active_budget .state != "draft" :
88
+ raise UserError ("Budget lines can only be created when the state is 'draft'." )
89
+ else :
90
+ for vals in vals_list :
91
+ budget_id = vals .get ("budget_id" )
92
+ if budget_id :
93
+ active_budget = self .env ["budget.budget" ].browse (budget_id )
94
+ break
95
+
96
+ if not active_budget :
97
+ raise UserError ("No budget found in context or record." )
98
+
99
+ if active_budget .state != "draft" :
100
+ raise UserError ("Budget lines can only be created when the state is 'draft'." )
25
101
102
+ return super (BudgetLine , self ).create (vals_list )
0 commit comments