73
'requestor': fields.char(size=128, string='Requestor', states={'draft': [('readonly', False)]}, readonly=True),
74
'procurement_request': fields.boolean(string='Internal Request', readonly=True),
75
'requested_date': fields.date(string='Requested date', states={'draft': [('readonly', False)]}, readonly=True),
76
'warehouse_id': fields.many2one('stock.warehouse', string='Warehouse', states={'draft': [('readonly', False)]}, readonly=True),
77
'origin': fields.char(size=64, string='Origin', states={'draft': [('readonly', False)]}, readonly=True),
71
'requestor': fields.char(size=128, string='Requestor'),
72
'procurement_request': fields.boolean(string='Procurement Request', readonly=True),
73
'requested_date': fields.date(string='Requested date'),
74
'warehouse_id': fields.many2one('stock.warehouse', string='Warehouse'),
75
'origin': fields.char(size=64, string='Origin'),
78
76
'notes': fields.text(string='Notes'),
79
77
'order_ids': fields.many2many('purchase.order', 'procurement_request_order_rel',
80
78
'request_id', 'order_id', string='Orders', readonly=True),
82
80
# Remove readonly parameter from sale.order class
83
'order_line': fields.one2many('sale.order.line', 'order_id', 'Order Lines', readonly=True, states={'draft': [('readonly', False)]}),
81
'order_line': fields.one2many('sale.order.line', 'order_id', 'Order Lines', readonly=True, states={'procurement': [('readonly', False)], 'draft': [('readonly', False)]}),
84
82
'amount_untaxed': fields.function(_amount_all, method=True, digits_compute= dp.get_precision('Sale Price'), string='Untaxed Amount',
86
'sale.order': (lambda self, cr, uid, ids, c=None: ids, ['order_line'], 10),
84
'sale.order': (lambda self, cr, uid, ids, c={}: ids, ['order_line'], 10),
87
85
'sale.order.line': (_get_order, ['price_unit', 'tax_id', 'discount', 'product_uom_qty'], 10),
89
87
multi='sums', help="The amount without tax."),
90
88
'amount_tax': fields.function(_amount_all, method=True, digits_compute= dp.get_precision('Sale Price'), string='Taxes',
92
'sale.order': (lambda self, cr, uid, ids, c=None: ids, ['order_line'], 10),
90
'sale.order': (lambda self, cr, uid, ids, c={}: ids, ['order_line'], 10),
93
91
'sale.order.line': (_get_order, ['price_unit', 'tax_id', 'discount', 'product_uom_qty'], 10),
95
93
multi='sums', help="The tax amount."),
96
94
'amount_total': fields.function(_amount_all, method=True, digits_compute= dp.get_precision('Sale Price'), string='Total',
98
'sale.order': (lambda self, cr, uid, ids, c=None: ids, ['order_line'], 10),
96
'sale.order': (lambda self, cr, uid, ids, c={}: ids, ['order_line'], 10),
99
97
'sale.order.line': (_get_order, ['price_unit', 'tax_id', 'discount', 'product_uom_qty'], 10),
101
99
multi='sums', help="The total amount."),
102
'state': fields.selection(SALE_ORDER_STATE_SELECTION, 'Order State', readonly=True, help="Gives the state of the quotation or sales order. \nThe exception state is automatically set when a cancel operation occurs in the invoice validation (Invoice Exception) or in the picking list process (Shipping Exception). \nThe 'Waiting Schedule' state is set when the invoice is confirmed but waiting for the scheduler to run on the date 'Ordered Date'.", select=True),
100
'state': fields.selection([
101
('procurement', 'Internal Supply Requirement'),
102
('draft', 'Quotation'),
103
('waiting_date', 'Waiting Schedule'),
104
('manual', 'Manual In Progress'),
105
('progress', 'In Progress'),
106
('shipping_except', 'Shipping Exception'),
107
('invoice_except', 'Invoice Exception'),
109
('cancel', 'Cancelled')
110
], 'Order State', readonly=True, help="Gives the state of the quotation or sales order. \nThe exception state is automatically set when a cancel operation occurs in the invoice validation (Invoice Exception) or in the picking list process (Shipping Exception). \nThe 'Waiting Schedule' state is set when the invoice is confirmed but waiting for the scheduler to run on the date 'Ordered Date'.", select=True),
106
'name': lambda obj, cr, uid, context: not context.get('procurement_request', False) and obj.pool.get('ir.sequence').get(cr, uid, 'sale.order') or obj.pool.get('ir.sequence').get(cr, uid, 'procurement.request'),
114
'name': lambda obj, cr, uid, context: not context.get('procurement_request', False) and obj.pool.get('ir.sequence').get(cr, uid, 'sale.order') or '',
107
115
'procurement_request': lambda obj, cr, uid, context: context.get('procurement_request', False),
109
'warehouse_id': lambda obj, cr, uid, context: len(obj.pool.get('stock.warehouse').search(cr, uid, [])) and obj.pool.get('stock.warehouse').search(cr, uid, [])[0],
116
'state': lambda self, cr, uid, c: c.get('procurement_request', False) and 'procurement' or 'draft',
112
def create(self, cr, uid, vals, context=None):
119
def create(self, cr, uid, vals, context={}):
116
if context.get('procurement_request') or vals.get('procurement_request', False):
123
if context.get('procurement_request'):
117
124
# Get the ISR number
118
125
if not vals.get('name', False):
119
126
vals.update({'name': self.pool.get('ir.sequence').get(cr, uid, 'procurement.request')})
145
152
for request in self.browse(cr, uid, ids, context=context):
146
if request.procurement_request and request.state in ['draft', 'cancel']:
153
if request.procurement_request and request.state in ['procurement', 'cancel']:
147
154
del_ids.append(request.id)
148
155
elif not request.procurement_request:
149
156
normal_ids.append(request.id)
151
raise osv.except_osv(_('Invalid action !'), _('Cannot delete Internal Request(s) which are already validated !'))
158
raise osv.except_osv(_('Invalid action !'), _('Cannot delete Procurement Request(s) which are already confirmed !'))
154
161
osv.osv.unlink(self, cr, uid, del_ids, context=context)
156
163
return super(procurement_request, self).unlink(cr, uid, normal_ids, context=context)
158
def search(self, cr, uid, args=None, offset=0, limit=None, order=None, context=None, count=False):
165
def search(self, cr, uid, args=[], offset=0, limit=None, order=None, context={}, count=False):
160
167
Adds automatically a domain to search only True sale orders if no procurement_request in context
168
171
if a[0] == 'procurement_request':
195
198
return super(osv.osv, self).copy(cr, uid, id, default, context=context)
197
def wkf_action_cancel(self, cr, uid, ids, context=None):
199
Cancel the procurement request and all lines
202
for req in self.browse(cr, uid, ids, context=context):
203
for line in req.order_line:
204
if line.id not in line_ids:
205
line_ids.append(line.id)
207
self.write(cr, uid, ids, {'state': 'cancel'}, context=context)
208
self.pool.get('sale.order.line').write(cr, uid, line_ids, {'state': 'cancel'}, context=context)
212
def validate_procurement(self, cr, uid, ids, context=None):
216
for req in self.browse(cr, uid, ids, context=context):
217
if len(req.order_line) <= 0:
218
raise osv.except_osv(_('Error'), _('You cannot validate an Internal request with no lines !'))
219
self.write(cr, uid, ids, {'state': 'validated'}, context=context)
223
def confirm_procurement(self, cr, uid, ids, context=None):
200
def confirm_procurement(self, cr, uid, ids, context={}):
225
202
Confirmed the request
230
self.write(cr, uid, ids, {'state': 'progress'}, context=context)
232
for request in self.browse(cr, uid, ids, context=context):
233
message = _("The internal request '%s' has been confirmed.") %(request.name,)
234
proc_view = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'procurement_request', 'procurement_request_form_view')
235
context.update({'view_id': proc_view and proc_view[1] or False})
236
self.log(cr, uid, request.id, message, context=context)
204
self.write(cr, uid, ids, {'state': 'progress'})
208
def procurement_done(self, cr, uid, ids, context={}):
210
Creates all procurement orders according to lines
238
212
self.action_ship_create(cr, uid, ids, context=context)
242
def procurement_done(self, cr, uid, ids, context=None):
244
Creates all procurement orders according to lines
246
213
self.write(cr, uid, ids, {'state': 'done'})
286
250
return super(procurement_request_line, self).create(cr, uid, vals, context=context)
289
'procurement_request': fields.boolean(string='Internal Request', readonly=True),
253
'procurement_request': fields.boolean(string='Procurement Request', readonly=True),
290
254
'latest': fields.char(size=64, string='Latest documents', readonly=True),
291
255
'price_subtotal': fields.function(_amount_line, method=True, string='Subtotal', digits_compute= dp.get_precision('Sale Price')),
292
'my_company_id': fields.many2one('res.company','Company',select=1),
293
'supplier': fields.many2one('res.partner', 'Supplier', domain="[('id', '!=', my_company_id)]"),
296
def _get_planned_date(self, cr, uid, c=None):
299
if 'procurement_request' in c:
300
return c.get('date_planned', False)
302
return super(procurement_request_line, self)._get_planned_date(cr, uid, c)
305
259
'procurement_request': lambda self, cr, uid, c: c.get('procurement_request', False),
306
'date_planned': _get_planned_date,
307
'my_company_id': lambda obj, cr, uid, context: obj.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id,
260
'date_planned': lambda self, cr, uid, c: c.get('date_planned', False),
310
def requested_product_id_change(self, cr, uid, ids, product_id, type, context=None):
263
def requested_product_id_change(self, cr, uid, ids, product_id, type, context={}):
312
265
Fills automatically the product_uom_id field on the line when the
313
266
product was changed.
317
268
product_obj = self.pool.get('product.product')
330
281
procurement_request_line()
332
class purchase_order(osv.osv):
333
_name = 'purchase.order'
334
_inherit = 'purchase.order'
336
def _hook_action_picking_create_modify_out_source_loc_check(self, cr, uid, ids, context=None, *args, **kwargs):
338
Please copy this to your module's method also.
339
This hook belongs to the action_picking_create method from purchase>purchase.py>purchase_order class
341
- allow to choose whether or not the source location of the corresponding outgoing stock move should
342
match the destination location of incoming stock move
344
order_line = kwargs['order_line']
345
move_id = kwargs['move_id']
346
proc_obj = self.pool.get('procurement.order')
347
move_obj = self.pool.get('stock.move')
348
sale_line_obj = self.pool.get('sale.order.line')
349
if order_line.move_dest_id:
350
proc_ids = proc_obj.search(cr, uid, [('move_id', '=', order_line.move_dest_id.id)], context=context)
351
so_line_ids = sale_line_obj.search(cr, uid, [('procurement_id', 'in', proc_ids)], context=context)
352
if all(not line.order_id or line.order_id.procurement_request for line in sale_line_obj.browse(cr, uid, so_line_ids, context=context)):
353
for proc in proc_obj.browse(cr, uid, proc_ids, context=context):
354
move_obj.write(cr, uid, [proc.move_id.id], {'state': 'draft'}, context=context)
355
move_obj.unlink(cr, uid, [proc.move_id.id], context=context)
356
proc_obj.write(cr, uid, [proc.id], {'move_id': move_id}, context=context)
358
return super(purchase_order, self)._hook_action_picking_create_modify_out_source_loc_check(cr, uid, ids, context, *args, **kwargs)
362
283
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: