1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# -*- coding: utf-8 -*-
# Copyright 2016 Eficent Business and IT Consulting Services S.L.
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0).
from openerp import api, fields, models
import openerp.addons.decimal_precision as dp
_STATES = [
('draft', 'Draft'),
('to_approve', 'To be approved'),
('approved', 'Approved'),
('rejected', 'Rejected')
]
class PurchaseRequest(models.Model):
_name = 'purchase.request'
_description = 'Purchase Request'
_inherit = ['mail.thread', 'ir.needaction_mixin']
@api.model
def _company_get(self):
company_id = self.env['res.company']._company_default_get(self._name)
return self.env['res.company'].browse(company_id.id)
@api.model
def _get_default_requested_by(self):
return self.env['res.users'].browse(self.env.uid)
@api.model
def _get_default_name(self):
return self.env['ir.sequence'].get('purchase.request')
@api.model
def _default_picking_type(self):
type_obj = self.env['stock.picking.type']
company_id = self.env.context.get('company_id') or \
self.env.user.company_id.id
types = type_obj.search([('code', '=', 'incoming'),
('warehouse_id.company_id', '=', company_id)])
if not types:
types = type_obj.search([('code', '=', 'incoming'),
('warehouse_id', '=', False)])
return types[:1]
@api.multi
@api.depends('state')
def _compute_is_editable(self):
for rec in self:
if rec.state in ('to_approve', 'approved', 'rejected'):
rec.is_editable = False
else:
rec.is_editable = True
@api.multi
def _track_subtype(self, init_values):
for rec in self:
if 'state' in init_values and rec.state == 'to_approve':
return 'purchase_request.mt_request_to_approve'
elif 'state' in init_values and rec.state == 'approved':
return 'purchase_request.mt_request_approved'
elif 'state' in init_values and rec.state == 'rejected':
return 'purchase_request.mt_request_rejected'
return super(PurchaseRequest, self)._track_subtype(init_values)
name = fields.Char('Request Reference', size=32, required=True,
default=_get_default_name,
track_visibility='onchange')
origin = fields.Char('Source Document', size=32)
date_start = fields.Date('Creation date',
help="Date when the user initiated the "
"request.",
default=fields.Date.context_today,
track_visibility='onchange')
requested_by = fields.Many2one('res.users',
'Requested by',
required=True,
track_visibility='onchange',
default=_get_default_requested_by)
assigned_to = fields.Many2one('res.users', 'Approver',
track_visibility='onchange')
description = fields.Text('Description')
company_id = fields.Many2one('res.company', 'Company',
required=True,
default=_company_get,
track_visibility='onchange')
line_ids = fields.One2many('purchase.request.line', 'request_id',
'Products to Purchase',
readonly=False,
copy=True,
track_visibility='onchange')
state = fields.Selection(selection=_STATES,
string='Status',
index=True,
track_visibility='onchange',
required=True,
copy=False,
default='draft')
is_editable = fields.Boolean(string="Is editable",
compute="_compute_is_editable",
readonly=True)
picking_type_id = fields.Many2one('stock.picking.type',
'Picking Type', required=True,
default=_default_picking_type)
@api.multi
def copy(self, default=None):
default = dict(default or {})
self.ensure_one()
default.update({
'state': 'draft',
'name': self.env['ir.sequence'].get('purchase.request'),
})
return super(PurchaseRequest, self).copy(default)
@api.model
def create(self, vals):
request = super(PurchaseRequest, self).create(vals)
if vals.get('assigned_to'):
request.message_subscribe_users(user_ids=[request.assigned_to.id])
return request
@api.multi
def write(self, vals):
res = super(PurchaseRequest, self).write(vals)
for request in self:
if vals.get('assigned_to'):
self.message_subscribe_users(user_ids=[request.assigned_to.id])
return res
@api.multi
def button_draft(self):
for rec in self:
rec.state = 'draft'
return True
@api.multi
def button_to_approve(self):
for rec in self:
rec.state = 'to_approve'
return True
@api.multi
def button_approved(self):
for rec in self:
rec.state = 'approved'
return True
@api.multi
def button_rejected(self):
for rec in self:
rec.state = 'rejected'
return True
class PurchaseRequestLine(models.Model):
_name = "purchase.request.line"
_description = "Purchase Request Line"
_inherit = ['mail.thread', 'ir.needaction_mixin']
@api.multi
@api.depends('product_id', 'name', 'product_uom_id', 'product_qty',
'analytic_account_id', 'date_required', 'specifications')
def _compute_is_editable(self):
for rec in self:
if rec.request_id.state in ('to_approve', 'approved', 'rejected'):
rec.is_editable = False
else:
rec.is_editable = True
@api.multi
def _compute_supplier_id(self):
for rec in self:
if rec.product_id:
if rec.product_id.seller_ids:
rec.supplier_id = rec.product_id.seller_ids[0].name
product_id = fields.Many2one(
'product.product', 'Product',
domain=[('purchase_ok', '=', True)],
track_visibility='onchange')
name = fields.Char('Description', size=256,
track_visibility='onchange')
product_uom_id = fields.Many2one('product.uom', 'Product Unit of Measure',
track_visibility='onchange')
product_qty = fields.Float('Quantity', track_visibility='onchange',
digits_compute=dp.get_precision(
'Product Unit of Measure'))
request_id = fields.Many2one('purchase.request',
'Purchase Request',
ondelete='cascade', readonly=True)
company_id = fields.Many2one('res.company',
related='request_id.company_id',
string='Company',
store=True, readonly=True)
analytic_account_id = fields.Many2one('account.analytic.account',
'Analytic Account',
track_visibility='onchange')
requested_by = fields.Many2one('res.users',
related='request_id.requested_by',
string='Requested by',
store=True, readonly=True)
assigned_to = fields.Many2one('res.users',
related='request_id.assigned_to',
string='Assigned to',
store=True, readonly=True)
date_start = fields.Date(related='request_id.date_start',
string='Request Date', readonly=True,
store=True)
description = fields.Text(related='request_id.description',
string='Description', readonly=True,
store=True)
origin = fields.Char(related='request_id.origin',
size=32, string='Source Document', readonly=True,
store=True)
date_required = fields.Date(string='Request Date', required=True,
track_visibility='onchange',
default=fields.Date.context_today)
is_editable = fields.Boolean(string='Is editable',
compute="_compute_is_editable",
readonly=True)
specifications = fields.Text(string='Specifications')
request_state = fields.Selection(string='Request state',
readonly=True,
related='request_id.state',
selection=_STATES,
store=True)
supplier_id = fields.Many2one('res.partner',
string='Preferred supplier',
compute="_compute_supplier_id")
procurement_id = fields.Many2one('procurement.order',
'Procurement Order',
readonly=True)
@api.onchange('product_id', 'product_uom_id')
def onchange_product_id(self):
if self.product_id:
name = self.product_id.name
if self.product_id.code:
name = '[%s] %s' % (name, self.product_id.code)
if self.product_id.description_purchase:
name += '\n' + self.product_id.description_purchase
self.product_uom_id = self.product_id.uom_id.id
self.product_qty = 1
self.name = name