1
1
# Copyright (C) 2018 - TODAY, Open Source Integrators
2
2
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
3
3
4
- from odoo import _ , api , fields , models
5
- from odoo .exceptions import ValidationError
6
-
7
-
8
- ACCOUNT_STAGES = [('draft' , 'Draft' ),
9
- ('review' , 'Needs Review' ),
10
- ('confirmed' , 'Confirmed' ),
11
- ('invoiced' , 'Fully Invoiced' ),
12
- ('no' , 'Nothing Invoiced' )]
4
+ from odoo import api , fields , models
13
5
14
6
15
7
class FSMOrder (models .Model ):
16
8
_inherit = 'fsm.order'
17
9
18
- contractor_cost_ids = fields .One2many ('account.invoice.line' ,
19
- 'fsm_order_id' ,
20
- string = 'Contractor Costs' )
21
- employee_timesheet_ids = fields .One2many ('account.analytic.line' ,
22
- "fsm_order_id" ,
23
- string = 'Employee Timesheets' )
24
10
total_cost = fields .Float (compute = '_compute_total_cost' ,
25
11
string = 'Total Cost' )
26
- employee = fields .Boolean (compute = '_compute_employee' )
27
- contractor_total = fields .Float (compute = '_compute_contractor_cost' ,
28
- string = 'Contractor Cost Estimate' )
29
- employee_time_total = fields .Float (compute = '_compute_employee_hours' ,
30
- string = 'Total Employee Hours' )
31
- account_stage = fields .Selection (ACCOUNT_STAGES , string = 'Accounting Stage' ,
32
- default = 'draft' )
33
12
bill_to = fields .Selection ([('location' , 'Bill Location' ),
34
13
('contact' , 'Bill Contact' )],
35
14
string = "Bill to" ,
@@ -41,158 +20,10 @@ class FSMOrder(models.Model):
41
20
index = True ,
42
21
track_visibility = 'always' )
43
22
44
- def _compute_employee (self ):
45
- user = self .env ['res.users' ].browse (self .env .uid )
46
- for order in self :
47
- if user .employee_ids :
48
- order .employee = True
49
-
50
- @api .depends ('employee_timesheet_ids' , 'contractor_cost_ids' )
51
23
def _compute_total_cost (self ):
24
+ """ To be overridden as needed from other modules """
52
25
for order in self :
53
26
order .total_cost = 0.0
54
- rate = 0
55
- for line in order .employee_timesheet_ids :
56
- rate = line .employee_id .timesheet_cost
57
- order .total_cost += line .unit_amount * rate
58
- for cost in order .contractor_cost_ids :
59
- order .total_cost += cost .price_unit * cost .quantity
60
-
61
- @api .depends ('employee_timesheet_ids' )
62
- def _compute_employee_hours (self ):
63
- for order in self :
64
- order .employee_time_total = 0.0
65
- for line in order .employee_timesheet_ids :
66
- order .employee_time_total += line .unit_amount
67
-
68
- @api .depends ('contractor_cost_ids' )
69
- def _compute_contractor_cost (self ):
70
- for order in self :
71
- order .contractor_total = 0.0
72
- for cost in order .contractor_cost_ids :
73
- order .contractor_total += cost .price_unit * cost .quantity
74
-
75
- def action_complete (self ):
76
- for order in self :
77
- order .account_stage = 'review'
78
- if self .person_id .supplier and not self .contractor_cost_ids :
79
- raise ValidationError (_ ("Cannot move to Complete " +
80
- "until 'Contractor Costs' is filled in" ))
81
- if not self .person_id .supplier and not self .employee_timesheet_ids :
82
- raise ValidationError (_ ("Cannot move to Complete until " +
83
- "'Employee Timesheets' is filled in" ))
84
- return super (FSMOrder , self ).action_complete ()
85
-
86
- def create_bills (self ):
87
- jrnl = self .env ['account.journal' ].search ([
88
- ('company_id' , '=' , self .env .user .company_id .id ),
89
- ('type' , '=' , 'purchase' ),
90
- ('active' , '=' , True )],
91
- limit = 1 )
92
- fpos = self .customer_id .property_account_position_id
93
- vals = {
94
- 'partner_id' : self .person_id .partner_id .id ,
95
- 'type' : 'in_invoice' ,
96
- 'journal_id' : jrnl .id or False ,
97
- 'fiscal_position_id' : fpos .id or False ,
98
- 'fsm_order_id' : self .id
99
- }
100
- bill = self .env ['account.invoice' ].sudo ().create (vals )
101
- for line in self .contractor_cost_ids :
102
- line .invoice_id = bill
103
- bill .compute_taxes ()
104
-
105
- def account_confirm (self ):
106
- for order in self :
107
- contractor = order .person_id .partner_id .supplier
108
- if order .contractor_cost_ids :
109
- if contractor :
110
- order .create_bills ()
111
- order .account_stage = 'confirmed'
112
- else :
113
- raise ValidationError (_ ("The worker assigned to this order"
114
- " is not a supplier" ))
115
- if order .employee_timesheet_ids :
116
- order .account_stage = 'confirmed'
117
-
118
- def account_create_invoice (self ):
119
- jrnl = self .env ['account.journal' ].search ([
120
- ('company_id' , '=' , self .env .user .company_id .id ),
121
- ('type' , '=' , 'sale' ),
122
- ('active' , '=' , True )],
123
- limit = 1 )
124
- if self .bill_to == 'contact' :
125
- if not self .customer_id :
126
- raise ValidationError (_ ("Contact empty" ))
127
- fpos = self .customer_id .property_account_position_id
128
- vals = {
129
- 'partner_id' : self .customer_id .id ,
130
- 'type' : 'out_invoice' ,
131
- 'journal_id' : jrnl .id or False ,
132
- 'fiscal_position_id' : fpos .id or False ,
133
- 'fsm_order_id' : self .id
134
- }
135
- invoice = self .env ['account.invoice' ].sudo ().create (vals )
136
- price_list = invoice .partner_id .property_product_pricelist
137
- else :
138
- fpos = self .location_id .customer_id .property_account_position_id
139
- vals = {
140
- 'partner_id' : self .location_id .customer_id .id ,
141
- 'type' : 'out_invoice' ,
142
- 'journal_id' : jrnl .id or False ,
143
- 'fiscal_position_id' : fpos .id or False ,
144
- 'fsm_order_id' : self .id
145
- }
146
- invoice = self .env ['account.invoice' ].sudo ().create (vals )
147
- price_list = invoice .partner_id .property_product_pricelist
148
- for line in self .employee_timesheet_ids :
149
- price = price_list .get_product_price (product = line .product_id ,
150
- quantity = line .unit_amount ,
151
- partner = invoice .partner_id ,
152
- date = False ,
153
- uom_id = False )
154
- template = line .product_id .product_tmpl_id
155
- accounts = template .get_product_accounts ()
156
- account = accounts ['income' ]
157
- vals = {
158
- 'product_id' : line .product_id .id ,
159
- 'account_analytic_id' : line .account_id .id ,
160
- 'quantity' : line .unit_amount ,
161
- 'name' : line .name ,
162
- 'price_unit' : price ,
163
- 'account_id' : account .id ,
164
- 'invoice_id' : invoice .id
165
- }
166
- time_cost = self .env ['account.invoice.line' ].create (vals )
167
- taxes = template .taxes_id
168
- time_cost .invoice_line_tax_ids = fpos .map_tax (taxes )
169
- for cost in self .contractor_cost_ids :
170
- price = price_list .get_product_price (product = cost .product_id ,
171
- quantity = cost .quantity ,
172
- partner = invoice .partner_id ,
173
- date = False ,
174
- uom_id = False )
175
- template = cost .product_id .product_tmpl_id
176
- accounts = template .get_product_accounts ()
177
- account = accounts ['income' ]
178
- vals = {
179
- 'product_id' : cost .product_id .id ,
180
- 'account_analytic_id' : cost .account_analytic_id .id ,
181
- 'quantity' : cost .quantity ,
182
- 'name' : cost .name ,
183
- 'price_unit' : price ,
184
- 'account_id' : account .id ,
185
- 'invoice_id' : invoice .id
186
- }
187
- con_cost = self .env ['account.invoice.line' ].create (vals )
188
- taxes = template .taxes_id
189
- con_cost .invoice_line_tax_ids = fpos .map_tax (taxes )
190
- invoice .compute_taxes ()
191
- self .account_stage = 'invoiced'
192
- return invoice
193
-
194
- def account_no_invoice (self ):
195
- self .account_stage = 'no'
196
27
197
28
@api .onchange ('location_id' )
198
29
def _onchange_location_id_customer_account (self ):
0 commit comments