[MERGE] Merged with bth MRP branch

bzr revid: tde@openerp.com-20120403104751-y1iep9psdtn8cphp
This commit is contained in:
Thibault Delavallée
2012-04-03 12:47:51 +02:00
7 changed files with 191 additions and 46 deletions
+79 -13
View File
@@ -130,6 +130,7 @@ class mrp_bom(osv.osv):
"""
_name = 'mrp.bom'
_description = 'Bill of Material'
_inherit = ['mail.thread']
def _child_compute(self, cr, uid, ids, name, arg, context=None):
""" Gets child bom.
@@ -358,6 +359,18 @@ class mrp_bom(osv.osv):
default.update({'name': bom_data['name'] + ' ' + _('Copy'), 'bom_id':False})
return super(mrp_bom, self).copy_data(cr, uid, id, default, context=context)
def create(self, cr, uid, vals, context=None):
obj_id = super(mrp_bom, self).create(cr, uid, vals, context=context)
self.create_send_note(cr, uid, [obj_id], context=context)
return obj_id
def create_send_note(self, cr, uid, ids, context=None):
prod_obj = self.pool.get('product.product')
for obj in self.browse(cr, uid, ids, context=context):
for prod in prod_obj.browse(cr, uid, [obj.product_id], context=context):
self.message_append_note(cr, uid, [obj.id], body=_("Bill of Material has been <b>created</b> for <em>%s</em> product.") % (prod.id.name_template), context=context)
return True
mrp_bom()
class mrp_bom_revision(osv.osv):
@@ -393,6 +406,7 @@ class mrp_production(osv.osv):
_name = 'mrp.production'
_description = 'Manufacturing Order'
_date_name = 'date_planned'
_inherit = ['ir.needaction', 'mail.thread']
def _production_calc(self, cr, uid, ids, prop, unknow_none, context=None):
""" Calculates total hours and total no. of cycles for a production order.
@@ -497,6 +511,11 @@ class mrp_production(osv.osv):
(_check_qty, 'Order quantity cannot be negative or zero!', ['product_qty']),
]
def create(self, cr, uid, vals, context=None):
obj_id = super(mrp_production, self).create(cr, uid, vals, context=context)
self.create_send_note(cr, uid, [obj_id], context=context)
return obj_id
def unlink(self, cr, uid, ids, context=None):
for production in self.browse(cr, uid, ids, context=context):
if production.state not in ('draft', 'cancel'):
@@ -629,9 +648,10 @@ class mrp_production(osv.osv):
move_obj.action_cancel(cr, uid, [x.id for x in production.move_created_ids])
move_obj.action_cancel(cr, uid, [x.id for x in production.move_lines])
self.write(cr, uid, ids, {'state': 'cancel'})
self.action_cancel_send_note(cr, uid, ids, context)
return True
def action_ready(self, cr, uid, ids):
def action_ready(self, cr, uid, ids, context=None):
""" Changes the production state to Ready and location id of stock move.
@return: True
"""
@@ -643,18 +663,18 @@ class mrp_production(osv.osv):
if production.move_prod_id:
move_obj.write(cr, uid, [production.move_prod_id.id],
{'location_id': production.location_dest_id.id})
message = _("Manufacturing order '%s' is ready to produce.") % ( name,)
self.log(cr, uid, production_id, message)
self.action_ready_send_note(cr, uid, [production_id], context)
return True
def action_production_end(self, cr, uid, ids):
def action_production_end(self, cr, uid, ids, context=None):
""" Changes production state to Finish and writes finished date.
@return: True
"""
for production in self.browse(cr, uid, ids):
self._costs_generate(cr, uid, production)
return self.write(cr, uid, ids, {'state': 'done', 'date_finished': time.strftime('%Y-%m-%d %H:%M:%S')})
write_res = self.write(cr, uid, ids, {'state': 'done', 'date_finished': time.strftime('%Y-%m-%d %H:%M:%S')})
self.action_done_send_note(cr, uid, ids, context)
return write_res
def test_production_done(self, cr, uid, ids):
""" Tests whether production is done or not.
@@ -698,7 +718,6 @@ class mrp_production(osv.osv):
if (produced_product.scrapped) or (produced_product.product_id.id <> production.product_id.id):
continue
produced_qty += produced_product.product_qty
if production_mode in ['consume','consume_produce']:
consumed_data = {}
@@ -819,11 +838,12 @@ class mrp_production(osv.osv):
} )
return amount
def action_in_production(self, cr, uid, ids):
def action_in_production(self, cr, uid, ids, context=None):
""" Changes state to In Production and writes starting date.
@return: True
"""
self.write(cr, uid, ids, {'state': 'in_production', 'date_start': time.strftime('%Y-%m-%d %H:%M:%S')})
self.action_in_production_send_note(cr, uid, ids, context)
return True
def test_if_product(self, cr, uid, ids):
@@ -997,11 +1017,7 @@ class mrp_production(osv.osv):
wf_service.trg_validate(uid, 'stock.picking', shipment_id, 'button_confirm', cr)
production.write({'state':'confirmed'}, context=context)
message = _("Manufacturing order '%s' is scheduled for the %s.") % (
production.name,
datetime.strptime(production.date_planned,'%Y-%m-%d %H:%M:%S').strftime('%m/%d/%Y'),
)
self.log(cr, uid, production.id, message)
self.action_confirm_send_note(cr, uid, [production.id], context);
return shipment_id
def force_production(self, cr, uid, ids, *args):
@@ -1012,6 +1028,55 @@ class mrp_production(osv.osv):
pick_obj = self.pool.get('stock.picking')
pick_obj.force_assign(cr, uid, [prod.picking_id.id for prod in self.browse(cr, uid, ids)])
return True
# ---------------------------------------------------
# OpenChatter methods and notifications
# ---------------------------------------------------
def get_needaction_user_ids(self, cr, uid, ids, context=None):
result = dict.fromkeys(ids, [])
for obj in self.browse(cr, uid, ids, context=context):
if obj.state == 'draft' and obj.user_id:
result[obj.id] = [obj.user_id.id]
return result
def message_get_subscribers(self, cr, uid, ids, context=None):
sub_ids = self.message_get_subscribers_ids(cr, uid, ids, context=context);
for obj in self.browse(cr, uid, ids, context=context):
if obj.user_id:
sub_ids.append(obj.user_id.id)
return self.pool.get('res.users').read(cr, uid, sub_ids, context=context)
def create_send_note(self, cr, uid, ids, context=None):
self.message_append_note(cr, uid, ids, body=_("Manufacturing order has been <b>created</b>."), context=context)
return True
def action_cancel_send_note(self, cr, uid, ids, context=None):
message = _("Manufacturing order has been <b>canceled</b>.")
self.message_append_note(cr, uid, ids, body=message, context=context)
return True
def action_ready_send_note(self, cr, uid, ids, context=None):
message = _("Manufacturing order is <b>ready to produce</b>.")
self.message_append_note(cr, uid, ids, body=message, context=context)
return True
def action_in_production_send_note(self, cr, uid, ids, context=None):
message = _("Manufacturing order is <b>in production</b>.")
self.message_append_note(cr, uid, ids, body=message, context=context)
return True
def action_done_send_note(self, cr, uid, ids, context=None):
message = _("Manufacturing order has been <b>done</b>.")
self.message_append_note(cr, uid, ids, body=message, context=context)
return True
def action_confirm_send_note(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
message = _("Manufacturing order has been <b>confirmed</b> and is <b>scheduled</b> for the <em>%s</em>.") % (obj.date_planned)
self.message_append_note(cr, uid, [obj.id], body=message, context=context)
return True
mrp_production()
@@ -1019,6 +1084,7 @@ class mrp_production_workcenter_line(osv.osv):
_name = 'mrp.production.workcenter.line'
_description = 'Work Order'
_order = 'sequence'
_inherit = ['mail.thread']
_columns = {
'name': fields.char('Work Order', size=64, required=True),
+4 -1
View File
@@ -410,6 +410,8 @@
<field colspan="4" name="property_ids" nolabel="1" groups="base.group_extended"/>
</page>
</notebook>
<newline/>
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
</form>
</field>
</record>
@@ -644,6 +646,7 @@
<label string="" colspan="2"/>
<field name="product_uos_qty" groups="product.group_uos"/>
<field name="product_uos" groups="product.group_uos"/>
<field name="user_id"/>
</group>
<notebook colspan="4">
@@ -773,7 +776,6 @@
<field colspan="4" name="product_lines" nolabel="1" widget="one2many_list"/>
</page>
<page string="Extra Information">
<field name="user_id"/>
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
<field name="priority" groups="base.group_extended"/>
<newline/>
@@ -783,6 +785,7 @@
<field name="move_prod_id" groups="base.group_extended"/>
</page>
</notebook>
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
</form>
</field>
</record>
+57 -7
View File
@@ -156,22 +156,24 @@ class mrp_production_workcenter_line(osv.osv):
prod_obj.write(cr, uid, [prod.production_id.id], {'date_start':dstart}, context=context, mini=False)
return result
def action_draft(self, cr, uid, ids):
def action_draft(self, cr, uid, ids, context=None):
""" Sets state to draft.
@return: True
"""
self.write(cr, uid, ids, {'state':'draft'})
self.action_draft_send_note(cr, uid, ids, context=context)
return True
def action_start_working(self, cr, uid, ids):
def action_start_working(self, cr, uid, ids, context=None):
""" Sets state to start working and writes starting date.
@return: True
"""
self.modify_production_order_state(cr, uid, ids, 'start')
self.write(cr, uid, ids, {'state':'startworking', 'date_start': time.strftime('%Y-%m-%d %H:%M:%S')})
self.action_start_send_note(cr, uid, ids, context=context)
return True
def action_done(self, cr, uid, ids):
def action_done(self, cr, uid, ids, context=None):
""" Sets state to done, writes finish date and calculates delay.
@return: True
"""
@@ -185,28 +187,76 @@ class mrp_production_workcenter_line(osv.osv):
delay += (date_finished-date_start).seconds / float(60*60)
self.write(cr, uid, ids, {'state':'done', 'date_finished': date_now,'delay':delay})
self.action_done_send_note(cr, uid, ids, context=context)
self.modify_production_order_state(cr,uid,ids,'done')
return True
def action_cancel(self, cr, uid, ids):
def action_cancel(self, cr, uid, ids, context=None):
""" Sets state to cancel.
@return: True
"""
self.write(cr, uid, ids, {'state':'cancel'})
self.action_cancel_send_note(cr, uid, ids, context=context)
return True
def action_pause(self, cr, uid, ids):
def action_pause(self, cr, uid, ids, context=None):
""" Sets state to pause.
@return: True
"""
self.write(cr, uid, ids, {'state':'pause'})
self.action_pending_send_note(cr, uid, ids, context=context)
return True
def action_resume(self, cr, uid, ids):
def action_resume(self, cr, uid, ids, context=None):
""" Sets state to startworking.
@return: True
"""
self.write(cr, uid, ids, {'state':'startworking'})
self.action_start_send_note(cr, uid, ids, context=context)
return True
# -------------------------------------------------------
# OpenChatter methods and notifications
# -------------------------------------------------------
def action_draft_send_note(self, cr, uid, ids, context=None):
prod_obj = self.pool.get('mrp.production')
for workorder in self.browse(cr, uid, ids):
for prod in prod_obj.browse(cr, uid, [workorder.production_id]):
message = _("Work order has been <b>created</b> for production order <em>%s</em>.") % (prod.id.name)
self.message_append_note(cr, uid, [workorder.id], body=message, context=context)
return True
def action_start_send_note(self, cr, uid, ids, context=None):
prod_obj = self.pool.get('mrp.production')
for workorder in self.browse(cr, uid, ids):
for prod in prod_obj.browse(cr, uid, [workorder.production_id]):
message = _("Work order has been <b>started</b> for production order <em>%s</em>.") % (prod.id.name)
self.message_append_note(cr, uid, [workorder.id], body=message, context=context)
return True
def action_done_send_note(self, cr, uid, ids, context=None):
prod_obj = self.pool.get('mrp.production')
for workorder in self.browse(cr, uid, ids):
for prod in prod_obj.browse(cr, uid, [workorder.production_id]):
message = _("Work order has been <b>done</b> for production order <em>%s</em>.") % (prod.id.name)
self.message_append_note(cr, uid, [workorder.id], body=message, context=context)
return True
def action_pending_send_note(self, cr, uid, ids, context=None):
prod_obj = self.pool.get('mrp.production')
for workorder in self.browse(cr, uid, ids):
for prod in prod_obj.browse(cr, uid, [workorder.production_id]):
message = _("Work order is <b>pending</b> for production order <em>%s</em>.") % (prod.id.name)
self.message_append_note(cr, uid, [workorder.id], body=message, context=context)
return True
def action_cancel_send_note(self, cr, uid, ids, context=None):
prod_obj = self.pool.get('mrp.production')
for workorder in self.browse(cr, uid, ids):
for prod in prod_obj.browse(cr, uid, [workorder.production_id]):
message = _("Work order has been <b>cancelled</b> for production order <em>%s</em>.") % (prod.id.name)
self.message_append_note(cr, uid, [workorder.id], body=message, context=context)
return True
mrp_production_workcenter_line()
@@ -251,7 +301,7 @@ class mrp_production(osv.osv):
if prod.workcenter_lines:
wf_service.trg_validate(uid, 'mrp.production.workcenter.line', prod.workcenter_lines[0].id, 'button_start_working', cr)
return super(mrp_production,self).action_in_production(cr, uid, ids)
def action_cancel(self, cr, uid, ids, context=None):
""" Cancels work order if production order is canceled.
@return: Super method
@@ -118,6 +118,7 @@
</group>
</page>
</notebook>
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
</form>
</field>
</record>
+13 -4
View File
@@ -167,7 +167,7 @@ class product_uom(osv.osv):
if value == 'reference':
return {'value': {'factor': 1, 'factor_inv': 1}}
return {}
def write(self, cr, uid, ids, vals, context=None):
if 'category_id' in vals:
for uom in self.browse(cr, uid, ids, context=context):
@@ -231,7 +231,7 @@ class product_category(osv.osv):
_parent_store = True
_parent_order = 'sequence, name'
_order = 'parent_left'
def _check_recursion(self, cr, uid, ids, context=None):
level = 100
while len(ids):
@@ -259,7 +259,7 @@ class product_template(osv.osv):
_description = "Product Template"
def _get_main_product_supplier(self, cr, uid, product, context=None):
"""Determines the main (best) product supplier for ``product``,
"""Determines the main (best) product supplier for ``product``,
returning the corresponding ``supplierinfo`` record, or False
if none were found. The default strategy is to select the
supplier with the highest priority (i.e. smallest sequence).
@@ -503,6 +503,7 @@ class product_product(osv.osv):
_description = "Product"
_table = "product_product"
_inherits = {'product.template': 'product_tmpl_id'}
_inherit = ['mail.thread']
_order = 'default_code,name_template'
_columns = {
'qty_available': fields.function(_product_qty_available, type='float', string='Quantity On Hand'),
@@ -526,7 +527,15 @@ class product_product(osv.osv):
'color': fields.integer('Color Index'),
'product_image': fields.binary('Image'),
}
def create(self, cr, uid, vals, context=None):
obj_id = super(product_product, self).create(cr, uid, vals, context=context)
self.create_send_note(cr, uid, [obj_id], context=context)
return obj_id
def create_send_note(self, cr, uid, ids, context=None):
return self.message_append_note(cr, uid, ids, body=_("Product has been <b>created</b>."), context=context)
def unlink(self, cr, uid, ids, context=None):
unlink_ids = []
unlink_product_tmpl_ids = []
+20 -20
View File
@@ -69,27 +69,26 @@
<field eval="7" name="priority"/>
<field name="arch" type="xml">
<form string="Product">
<group colspan="4" col="8">
<group colspan="4" col="2">
<separator string="Name" colspan="2"/>
<field name="name"/>
<field groups="product.group_product_variant" name="variants" />
<group colspan="4" col="8">
<group colspan="4" col="2">
<separator string="Name" colspan="2"/>
<field name="name"/>
<field groups="product.group_product_variant" name="variants" />
</group>
<group colspan="1" col="2">
<separator string="Codes" colspan="2"/>
<field name="default_code"/>
<field name="ean13" groups="base.group_extended"/>
</group>
<group colspan="1" col="2">
<separator string="Characteristics" colspan="2"/>
<field name="sale_ok"/>
<field name="purchase_ok"/>
</group>
<group colspan="1" col="1">
<field name="product_image" widget='image' nolabel="1"/>
</group>
</group>
<group colspan="1" col="2">
<separator string="Codes" colspan="2"/>
<field name="default_code"/>
<field name="ean13" groups="base.group_extended"/>
</group>
<group colspan="1" col="2">
<separator string="Characteristics" colspan="2"/>
<field name="sale_ok"/>
<field name="purchase_ok"/>
</group>
<group colspan="1" col="1">
<field name="product_image" widget='image' nolabel="1"/>
</group>
</group>
<notebook colspan="4">
<page string="Information">
<group colspan="2" col="2">
@@ -192,6 +191,7 @@
</field>
</page>
</notebook>
<field name="message_ids_social" colspan="4" widget="ThreadView" nolabel="1"/>
</form>
</field>
</record>
@@ -26,6 +26,7 @@ import tools
class stock_change_product_qty(osv.osv_memory):
_name = "stock.change.product.qty"
_inherit = ['mail.thread']
_description = "Change Product Quantity"
_columns = {
'product_id' : fields.many2one('product.product', 'Product'),
@@ -98,9 +99,24 @@ class stock_change_product_qty(osv.osv_memory):
inventry_obj.action_confirm(cr, uid, [inventory_id], context=context)
inventry_obj.action_done(cr, uid, [inventory_id], context=context)
self.change_product_qty_send_note(cr, uid, [data.id], context)
return {}
def change_product_qty_send_note (self, cr, uid, ids, context=None):
prod_obj = self.pool.get('product.product')
location_obj = self.pool.get('stock.location')
prod_temp_obj = self.pool.get('product.template')
uom_obj = self.pool.get('product.uom')
for data in self.browse(cr, uid, ids, context=context):
for location in location_obj.browse(cr, uid, [data.location_id.id], context=context):
location_name = location.name
for prod in prod_obj.browse(cr, uid, [data.product_id.id], context=context):
for prod_temp in prod_temp_obj.browse(cr, uid, [prod.product_tmpl_id.id], context=context):
for uom in uom_obj.browse(cr, uid, [prod_temp.uom_id.id], context=context):
message = _("<b>Quantity has been changed</b> to <em>%s %s </em> for <em>%s</em> location.") % (data.new_quantity,uom.name,location_name)
prod_obj.message_append_note(cr, uid, [prod.id], body=message, context=context)
stock_change_product_qty()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: