_inherit = ['mail.thread']
_log_create = False
_columns = {
- 'name': fields.char('Reason', size=64, required=True, help='Procurement name.'),
+ 'name': fields.char('Description', required=True),
'origin': fields.char('Source Document', size=64,
help="Reference of the document that created this Procurement.\n"
"This is automatically completed by OpenERP."),
'move_id': fields.many2one('stock.move', 'Reservation', ondelete='set null'),
'close_move': fields.boolean('Close Move at end'),
'location_id': fields.many2one('stock.location', 'Location', required=True, states={'draft':[('readonly',False)]}, readonly=True),
- 'procure_method': fields.selection([('make_to_stock','from stock'),('make_to_order','on order')], 'Procurement Method', states={'draft':[('readonly',False)], 'confirmed':[('readonly',False)]},
+ 'procure_method': fields.selection([('make_to_stock','Make to Stock'),('make_to_order','Make to Order')], 'Procurement Method', states={'draft':[('readonly',False)], 'confirmed':[('readonly',False)]},
readonly=True, required=True, help="If you encode manually a Procurement, you probably want to use" \
" a make to order method."),
-
'note': fields.text('Note'),
'message': fields.char('Latest error', size=124, help="Exception occurred while computing procurement orders."),
'state': fields.selection([
('ready','Ready'),
('done','Done'),
('waiting','Waiting')], 'Status', required=True,
- help='When a procurement is created the state is set to \'Draft\'.\n If the procurement is confirmed, the state is set to \'Confirmed\'.\
- \nAfter confirming the state is set to \'Running\'.\n If any exception arises in the order then the state is set to \'Exception\'.\n Once the exception is removed the state becomes \'Ready\'.\n It is in \'Waiting\'. state when the procurement is waiting for another one to finish.'),
+ help='When a procurement is created the status is set to \'Draft\'.\n If the procurement is confirmed, the status is set to \'Confirmed\'.\
+ \nAfter confirming the status is set to \'Running\'.\n If any exception arises in the order then the status is set to \'Exception\'.\n Once the exception is removed the status becomes \'Ready\'.\n It is in \'Waiting\'. status when the procurement is waiting for another one to finish.'),
'note': fields.text('Note'),
'company_id': fields.many2one('res.company','Company',required=True),
}
move_obj = self.pool.get('stock.move')
for procurement in self.browse(cr, uid, ids, context=context):
if procurement.product_qty <= 0.00:
- raise osv.except_osv(_('Insufficient Data!'),
- _('Quantity in procurement order(s) must be greater than 0.'))
+ raise osv.except_osv(_('Data Insufficient !'),
+ _('Please check the quantity in procurement order(s) for the product "%s", it should not be 0 or less!' % procurement.product_id.name))
if procurement.product_id.type in ('product', 'consu'):
if not procurement.move_id:
source = procurement.location_id.id
""" Changes procurement state to Running and writes message.
@return: True
"""
- message = _('From stock: products assigned.')
+ message = _('Products reserved from stock.')
self.write(cr, uid, ids, {'state': 'running',
'message': message}, context=context)
self.message_post(cr, uid, ids, body=message, context=context)
- self.running_send_note(cr, uid, ids, context=context)
return True
def _check_make_to_stock_service(self, cr, uid, procurement, context=None):
order_point_id = self.pool.get('stock.warehouse.orderpoint').search(cr, uid, [('product_id', '=', procurement.product_id.id)], context=context)
if not order_point_id and not ok:
message = _("Not enough stock and no minimum orderpoint rule defined.")
- elif not order_point_id:
- message = _("No minimum orderpoint rule defined.")
elif not ok:
message = _("Not enough stock.")
"""
for procurement in self.browse(cr, uid, ids, context=context):
self.write(cr, uid, [procurement.id], {'state': 'running'})
- self.running_send_note(cr, uid, ids, context=None)
return True
def action_produce_assign_product(self, cr, uid, ids, context=None):
"""
return 0
+ # XXX action_cancel() should accept a context argument
def action_cancel(self, cr, uid, ids):
- """ Cancels procurement and writes move state to Assigned.
+ """Cancel Procurements and either cancel or assign the related Stock Moves, depending on the procurement configuration.
+
@return: True
"""
- todo = []
- todo2 = []
+ to_assign = []
+ to_cancel = []
move_obj = self.pool.get('stock.move')
for proc in self.browse(cr, uid, ids):
if proc.close_move and proc.move_id:
if proc.move_id.state not in ('done', 'cancel'):
- todo2.append(proc.move_id.id)
+ to_cancel.append(proc.move_id.id)
else:
if proc.move_id and proc.move_id.state == 'waiting':
- todo.append(proc.move_id.id)
- if len(todo2):
- move_obj.action_cancel(cr, uid, todo2)
- if len(todo):
- move_obj.write(cr, uid, todo, {'state': 'assigned'})
+ to_assign.append(proc.move_id.id)
+ if len(to_cancel):
+ move_obj.action_cancel(cr, uid, to_cancel)
+ if len(to_assign):
+ move_obj.write(cr, uid, to_assign, {'state': 'assigned'})
self.write(cr, uid, ids, {'state': 'cancel'})
self.cancel_send_note(cr, uid, ids, context=None)
wf_service = netsvc.LocalService("workflow")
@return: True
"""
res = self.write(cr, uid, ids, {'state': 'ready'})
- self.ready_send_note(cr, uid, ids, context=None)
return res
def action_done(self, cr, uid, ids):
return obj_id
def create_send_note(self, cr, uid, ids, context=None):
- self.message_post(cr, uid, ids, body=_("Procurement has been <b>created</b>."), context=context)
+ self.message_post(cr, uid, ids, body=_("Procurement <b>created</b>."), context=context)
def confirm_send_note(self, cr, uid, ids, context=None):
- self.message_post(cr, uid, ids, body=_("Procurement has been <b>confirmed</b>."), context=context)
-
- def running_send_note(self, cr, uid, ids, context=None):
- self.message_post(cr, uid, ids, body=_("Procurement has been set to <b>running</b>."), context=context)
-
- def ready_send_note(self, cr, uid, ids, context=None):
- self.message_post(cr, uid, ids, body=_("Procurement has been set to <b>ready</b>."), context=context)
+ self.message_post(cr, uid, ids, body=_("Procurement <b>confirmed</b>."), context=context)
def cancel_send_note(self, cr, uid, ids, context=None):
- self.message_post(cr, uid, ids, body=_("Procurement has been <b>cancelled</b>."), context=context)
+ self.message_post(cr, uid, ids, body=_("Procurement <b>cancelled</b>."), context=context)
def done_send_note(self, cr, uid, ids, context=None):
- self.message_post(cr, uid, ids, body=_("Procurement has been <b>done</b>."), context=context)
+ self.message_post(cr, uid, ids, body=_("Procurement <b>done</b>."), context=context)
procurement_order()
result[orderpoint.id] = procurement_ids
return result
+ def _check_product_uom(self, cr, uid, ids, context=None):
+ '''
+ Check if the UoM has the same category as the product standard UoM
+ '''
+ if not context:
+ context = {}
+
+ for rule in self.browse(cr, uid, ids, context=context):
+ if rule.product_id.uom_id.category_id.id != rule.product_uom.category_id.id:
+ return False
+
+ return True
+
_columns = {
'name': fields.char('Name', size=32, required=True),
'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the orderpoint without removing it."),
'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True),
'product_min_qty': fields.float('Minimum Quantity', required=True,
help="When the virtual stock goes below the Min Quantity specified for this field, OpenERP generates "\
- "a procurement to bring the virtual stock to the Max Quantity."),
+ "a procurement to bring the forecasted quantity to the Max Quantity."),
'product_max_qty': fields.float('Maximum Quantity', required=True,
help="When the virtual stock goes below the Min Quantity, OpenERP generates "\
- "a procurement to bring the virtual stock to the Quantity specified as Max Quantity."),
+ "a procurement to bring the forecasted quantity to the Quantity specified as Max Quantity."),
'qty_multiple': fields.integer('Qty Multiple', required=True,
help="The procurement quantity will be rounded up to this multiple."),
'procurement_id': fields.many2one('procurement.order', 'Latest procurement', ondelete="set null"),
_sql_constraints = [
('qty_multiple_check', 'CHECK( qty_multiple > 0 )', 'Qty Multiple must be greater than zero.'),
]
+ _constraints = [
+ (_check_product_uom, 'You have to select a product unit of measure in the same category than the default unit of measure of the product', ['product_id', 'product_uom']),
+ ]
def default_get(self, cr, uid, fields, context=None):
res = super(stock_warehouse_orderpoint, self).default_get(cr, uid, fields, context)
"""
if product_id:
prod = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
+ d = {'product_uom': [('category_id', '=', prod.uom_id.category_id.id)]}
v = {'product_uom': prod.uom_id.id}
- return {'value': v}
- return {}
+ return {'value': v, 'domain': d}
+ return {'domain': {'product_uom': []}}
def copy(self, cr, uid, id, default=None, context=None):
if not default:
})
return super(stock_warehouse_orderpoint, self).copy(cr, uid, id, default, context=context)
-stock_warehouse_orderpoint()
+class product_template(osv.osv):
+ _inherit="product.template"
+
+ _columns = {
+ 'type': fields.selection([('product','Stockable Product'),('consu', 'Consumable'),('service','Service')], 'Product Type', required=True, help="Consumable: Will not imply stock management for this product. \nStockable product: Will imply stock management for this product."),
+ 'procure_method': fields.selection([('make_to_stock','Make to Stock'),('make_to_order','Make to Order')], 'Procurement Method', required=True, help="Make to Stock: When needed, the product is taken from the stock or we wait for replenishment. \nMake to Order: When needed, the product is purchased or produced."),
+ 'supply_method': fields.selection([('produce','Manufacture'),('buy','Buy')], 'Supply Method', required=True, help="Manufacture: When procuring the product, a manufacturing order or a task will be generated, depending on the product type. \nBuy: When procuring the product, a purchase order will be generated."),
+ }
+ _defaults = {
+ 'procure_method': 'make_to_stock',
+ 'supply_method': 'buy',
+ }
class product_product(osv.osv):
_inherit="product.product"
'orderpoint_ids': fields.one2many('stock.warehouse.orderpoint', 'product_id', 'Minimum Stock Rules'),
}
-product_product()
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: