[IMP] notifications in mrp,bom,product.

bzr revid: bth@tinyerp.com-20120306133816-59cs058o3oq8arro
This commit is contained in:
Bhumi Thakkar (Open ERP) 2012-03-06 19:08:16 +05:30
parent 526281d470
commit d83bf22983
7 changed files with 174 additions and 34 deletions

View File

@ -130,6 +130,7 @@ class mrp_bom(osv.osv):
""" """
_name = 'mrp.bom' _name = 'mrp.bom'
_description = 'Bill of Material' _description = 'Bill of Material'
_inherit = ['mail.thread']
def _child_compute(self, cr, uid, ids, name, arg, context=None): def _child_compute(self, cr, uid, ids, name, arg, context=None):
""" Gets child bom. """ Gets child bom.
@ -312,7 +313,7 @@ class mrp_bom(osv.osv):
phantom = False phantom = False
if bom.type == 'phantom' and not bom.bom_lines: if bom.type == 'phantom' and not bom.bom_lines:
newbom = self._bom_find(cr, uid, bom.product_id.id, bom.product_uom.id, properties) newbom = self._bom_find(cr, uid, bom.product_id.id, bom.product_uom.id, properties)
if newbom: if newbom:
res = self._bom_explode(cr, uid, self.browse(cr, uid, [newbom])[0], factor*bom.product_qty, properties, addthis=True, level=level+10) res = self._bom_explode(cr, uid, self.browse(cr, uid, [newbom])[0], factor*bom.product_qty, properties, addthis=True, level=level+10)
result = result + res[0] result = result + res[0]
@ -358,6 +359,19 @@ class mrp_bom(osv.osv):
default.update({'name': bom_data['name'] + ' ' + _('Copy'), 'bom_id':False}) default.update({'name': bom_data['name'] + ' ' + _('Copy'), 'bom_id':False})
return super(mrp_bom, self).copy_data(cr, uid, id, default, context=context) 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_notification(cr, uid, [obj_id], context=context)
return obj_id
def create_notification(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, ids, _('System notification'),
_("Bill of Material is <b>Created</b> for <em>%s</em> product.") % (prod.id.name_template), type='notification', context=context)
return True
mrp_bom() mrp_bom()
class mrp_bom_revision(osv.osv): class mrp_bom_revision(osv.osv):
@ -393,6 +407,7 @@ class mrp_production(osv.osv):
_name = 'mrp.production' _name = 'mrp.production'
_description = 'Manufacturing Order' _description = 'Manufacturing Order'
_date_name = 'date_planned' _date_name = 'date_planned'
_inherit = ['mail.thread']
def _production_calc(self, cr, uid, ids, prop, unknow_none, context=None): def _production_calc(self, cr, uid, ids, prop, unknow_none, context=None):
""" Calculates total hours and total no. of cycles for a production order. """ Calculates total hours and total no. of cycles for a production order.
@ -497,12 +512,54 @@ class mrp_production(osv.osv):
(_check_qty, 'Order quantity cannot be negative or zero!', ['product_qty']), (_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_notification(cr, uid, [obj_id], context=context)
return obj_id
def unlink(self, cr, uid, ids, context=None): def unlink(self, cr, uid, ids, context=None):
for production in self.browse(cr, uid, ids, context=context): for production in self.browse(cr, uid, ids, context=context):
if production.state not in ('draft', 'cancel'): if production.state not in ('draft', 'cancel'):
raise osv.except_osv(_('Invalid action !'), _('Cannot delete a manufacturing order in state \'%s\'') % production.state) raise osv.except_osv(_('Invalid action !'), _('Cannot delete a manufacturing order in state \'%s\'') % production.state)
return super(mrp_production, self).unlink(cr, uid, ids, context=context) return super(mrp_production, self).unlink(cr, uid, ids, context=context)
def create_notification(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
if obj.user_id.id :
self.message_subscribe(cr, uid, ids, [obj.user_id.id], context=context)
self.message_append_note(cr, uid, ids, _('System notification'),
_("Manufacturing Order is <b>Created</b>."), type='notification', need_action_user_id=obj.user_id.id, context=context)
else :
self.message_append_note(cr, uid, ids, _('System notification'),
_("Manufacturing Order is <b>Created</b>."), type='notification', context=context)
return True
def cancel_notification(self, cr, uid, ids, context=None):
message = _("Manufacturing order is <b>cancelled</b>.")
self.message_append_note(cr, uid, ids, '', message, context=context)
return True
def ready_notification(self, cr, uid, ids, context=None):
message = _("Manufacturing order is <b>ready to produce</b>.")
self.message_append_note(cr, uid, ids, '', message, context=context)
return True
def inproduction_notification(self, cr, uid, ids, context=None):
message = _("Manufacturing order is <b>in production</b>.")
self.message_append_note(cr, uid, ids, '', message, context=context)
return True
def done_notification(self, cr, uid, ids, context=None):
self.message_mark_done(cr, uid, ids, context)
message = _("Manufacturing order is <b>done</b>.")
self.message_append_note(cr, uid, ids, '', message, context=context)
return True
def waiting_notification(self, cr, uid, ids, context=None):
message = _("Manufacturing order is <b>waiting for goods</b>.")
self.message_append_note(cr, uid, ids, '', message, context=context)
return True
def copy(self, cr, uid, id, default=None, context=None): def copy(self, cr, uid, id, default=None, context=None):
if default is None: if default is None:
default = {} default = {}
@ -629,9 +686,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_created_ids])
move_obj.action_cancel(cr, uid, [x.id for x in production.move_lines]) move_obj.action_cancel(cr, uid, [x.id for x in production.move_lines])
self.write(cr, uid, ids, {'state': 'cancel'}) self.write(cr, uid, ids, {'state': 'cancel'})
self.cancel_notification(cr, uid, ids, context)
return True 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. """ Changes the production state to Ready and location id of stock move.
@return: True @return: True
""" """
@ -643,18 +701,18 @@ class mrp_production(osv.osv):
if production.move_prod_id: if production.move_prod_id:
move_obj.write(cr, uid, [production.move_prod_id.id], move_obj.write(cr, uid, [production.move_prod_id.id],
{'location_id': production.location_dest_id.id}) {'location_id': production.location_dest_id.id})
self.ready_notification(cr, uid, [production_id], context)
message = _("Manufacturing order '%s' is ready to produce.") % ( name,)
self.log(cr, uid, production_id, message)
return True 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. """ Changes production state to Finish and writes finished date.
@return: True @return: True
""" """
for production in self.browse(cr, uid, ids): for production in self.browse(cr, uid, ids):
self._costs_generate(cr, uid, production) self._costs_generate(cr, uid, production)
return self.write(cr, uid, ids, {'state': 'done', 'date_finished': time.strftime('%Y-%m-%d %H:%M:%S')}) self.write(cr, uid, ids, {'state': 'done', 'date_finished': time.strftime('%Y-%m-%d %H:%M:%S')})
self.done_notification(cr, uid, ids, context)
return True
def test_production_done(self, cr, uid, ids): def test_production_done(self, cr, uid, ids):
""" Tests whether production is done or not. """ Tests whether production is done or not.
@ -670,9 +728,9 @@ class mrp_production(osv.osv):
return res return res
def _get_subproduct_factor(self, cr, uid, production_id, move_id=None, context=None): def _get_subproduct_factor(self, cr, uid, production_id, move_id=None, context=None):
""" Compute the factor to compute the qty of procucts to produce for the given production_id. By default, """ Compute the factor to compute the qty of procucts to produce for the given production_id. By default,
it's always equal to the quantity encoded in the production order or the production wizard, but if the it's always equal to the quantity encoded in the production order or the production wizard, but if the
module mrp_subproduct is installed, then we must use the move_id to identify the product to produce module mrp_subproduct is installed, then we must use the move_id to identify the product to produce
and its quantity. and its quantity.
:param production_id: ID of the mrp.order :param production_id: ID of the mrp.order
:param move_id: ID of the stock move that needs to be produced. Will be used in mrp_subproduct. :param move_id: ID of the stock move that needs to be produced. Will be used in mrp_subproduct.
@ -698,7 +756,6 @@ class mrp_production(osv.osv):
if (produced_product.scrapped) or (produced_product.product_id.id <> production.product_id.id): if (produced_product.scrapped) or (produced_product.product_id.id <> production.product_id.id):
continue continue
produced_qty += produced_product.product_qty produced_qty += produced_product.product_qty
if production_mode in ['consume','consume_produce']: if production_mode in ['consume','consume_produce']:
consumed_data = {} consumed_data = {}
@ -733,7 +790,7 @@ class mrp_production(osv.osv):
prod_name = scheduled.product_id.name_get()[0][1] prod_name = scheduled.product_id.name_get()[0][1]
raise osv.except_osv(_('Warning!'), _('You are going to consume total %s quantities of "%s".\nBut you can only consume up to total %s quantities.') % (qty, prod_name, qty_avail)) raise osv.except_osv(_('Warning!'), _('You are going to consume total %s quantities of "%s".\nBut you can only consume up to total %s quantities.') % (qty, prod_name, qty_avail))
if qty <= 0.0: if qty <= 0.0:
# we already have more qtys consumed than we need # we already have more qtys consumed than we need
continue continue
raw_product[0].action_consume(qty, raw_product[0].location_id.id, context=context) raw_product[0].action_consume(qty, raw_product[0].location_id.id, context=context)
@ -819,11 +876,12 @@ class mrp_production(osv.osv):
} ) } )
return amount 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. """ Changes state to In Production and writes starting date.
@return: True @return: True
""" """
self.write(cr, uid, ids, {'state': 'in_production', 'date_start': time.strftime('%Y-%m-%d %H:%M:%S')}) self.write(cr, uid, ids, {'state': 'in_production', 'date_start': time.strftime('%Y-%m-%d %H:%M:%S')})
self.inproduction_notification(cr, uid, ids, context)
return True return True
def test_if_product(self, cr, uid, ids): def test_if_product(self, cr, uid, ids):
@ -890,14 +948,14 @@ class mrp_production(osv.osv):
'state': 'waiting', 'state': 'waiting',
'company_id': production.company_id.id, 'company_id': production.company_id.id,
}) })
def _make_production_internal_shipment(self, cr, uid, production, context=None): def _make_production_internal_shipment(self, cr, uid, production, context=None):
ir_sequence = self.pool.get('ir.sequence') ir_sequence = self.pool.get('ir.sequence')
stock_picking = self.pool.get('stock.picking') stock_picking = self.pool.get('stock.picking')
routing_loc = None routing_loc = None
pick_type = 'internal' pick_type = 'internal'
address_id = False address_id = False
# Take routing address as a Shipment Address. # Take routing address as a Shipment Address.
# If usage of routing location is a internal, make outgoing shipment otherwise internal shipment # If usage of routing location is a internal, make outgoing shipment otherwise internal shipment
if production.bom_id.routing_id and production.bom_id.routing_id.location_id: if production.bom_id.routing_id and production.bom_id.routing_id.location_id:
@ -926,7 +984,7 @@ class mrp_production(osv.osv):
stock_move = self.pool.get('stock.move') stock_move = self.pool.get('stock.move')
source_location_id = production.product_id.product_tmpl_id.property_stock_production.id source_location_id = production.product_id.product_tmpl_id.property_stock_production.id
destination_location_id = production.location_dest_id.id destination_location_id = production.location_dest_id.id
move_name = _('PROD: %s') + production.name move_name = _('PROD: %s') + production.name
data = { data = {
'name': move_name, 'name': move_name,
'date': production.date_planned, 'date': production.date_planned,
@ -983,7 +1041,7 @@ class mrp_production(osv.osv):
for production in self.browse(cr, uid, ids, context=context): for production in self.browse(cr, uid, ids, context=context):
shipment_id = self._make_production_internal_shipment(cr, uid, production, context=context) shipment_id = self._make_production_internal_shipment(cr, uid, production, context=context)
produce_move_id = self._make_production_produce_line(cr, uid, production, context=context) produce_move_id = self._make_production_produce_line(cr, uid, production, context=context)
# Take routing location as a Source Location. # Take routing location as a Source Location.
source_location_id = production.location_src_id.id source_location_id = production.location_src_id.id
if production.bom_id.routing_id and production.bom_id.routing_id.location_id: if production.bom_id.routing_id and production.bom_id.routing_id.location_id:
@ -994,14 +1052,14 @@ class mrp_production(osv.osv):
shipment_move_id = self._make_production_internal_shipment_line(cr, uid, line, shipment_id, consume_move_id,\ shipment_move_id = self._make_production_internal_shipment_line(cr, uid, line, shipment_id, consume_move_id,\
destination_location_id=source_location_id, context=context) destination_location_id=source_location_id, context=context)
self._make_production_line_procurement(cr, uid, line, shipment_move_id, context=context) self._make_production_line_procurement(cr, uid, line, shipment_move_id, context=context)
wf_service.trg_validate(uid, 'stock.picking', shipment_id, 'button_confirm', cr) wf_service.trg_validate(uid, 'stock.picking', shipment_id, 'button_confirm', cr)
production.write({'state':'confirmed'}, context=context) production.write({'state':'confirmed'}, context=context)
message = _("Manufacturing order '%s' is scheduled for the %s.") % ( message = _("Manufacturing order '%s' is scheduled for the %s.") % (
production.name, production.name,
datetime.strptime(production.date_planned,'%Y-%m-%d %H:%M:%S').strftime('%m/%d/%Y'), datetime.strptime(production.date_planned,'%Y-%m-%d %H:%M:%S').strftime('%m/%d/%Y'),
) )
self.log(cr, uid, production.id, message) self.waiting_notification(cr, uid, [production.id], context);
return shipment_id return shipment_id
def force_production(self, cr, uid, ids, *args): def force_production(self, cr, uid, ids, *args):
@ -1019,6 +1077,7 @@ class mrp_production_workcenter_line(osv.osv):
_name = 'mrp.production.workcenter.line' _name = 'mrp.production.workcenter.line'
_description = 'Work Order' _description = 'Work Order'
_order = 'sequence' _order = 'sequence'
_inherit = ['mail.thread']
_columns = { _columns = {
'name': fields.char('Work Order', size=64, required=True), 'name': fields.char('Work Order', size=64, required=True),

View File

@ -410,6 +410,7 @@
<field colspan="4" name="property_ids" nolabel="1" groups="base.group_extended"/> <field colspan="4" name="property_ids" nolabel="1" groups="base.group_extended"/>
</page> </page>
</notebook> </notebook>
<field name="message_ids_social" widget="ThreadView"/>
</form> </form>
</field> </field>
</record> </record>
@ -644,6 +645,7 @@
<label string="" colspan="2"/> <label string="" colspan="2"/>
<field name="product_uos_qty" groups="product.group_uos"/> <field name="product_uos_qty" groups="product.group_uos"/>
<field name="product_uos" groups="product.group_uos"/> <field name="product_uos" groups="product.group_uos"/>
<field name="user_id"/>
</group> </group>
<notebook colspan="4"> <notebook colspan="4">
@ -773,16 +775,14 @@
<field colspan="4" name="product_lines" nolabel="1" widget="one2many_list"/> <field colspan="4" name="product_lines" nolabel="1" widget="one2many_list"/>
</page> </page>
<page string="Extra Information"> <page string="Extra Information">
<field name="user_id"/>
<field name="company_id" groups="base.group_multi_company" widget="selection"/> <field name="company_id" groups="base.group_multi_company" widget="selection"/>
<field name="priority" groups="base.group_extended"/> <field name="priority" groups="base.group_extended"/>
<newline/> <newline/>
<field name="date_start"/>
<field name="date_finished"/>
<field name="picking_id" groups="base.group_extended"/> <field name="picking_id" groups="base.group_extended"/>
<field name="move_prod_id" groups="base.group_extended"/> <field name="move_prod_id" groups="base.group_extended"/>
</page> </page>
</notebook> </notebook>
<field name="message_ids_social" widget="ThreadView"/>
</form> </form>
</field> </field>
</record> </record>

View File

@ -156,11 +156,62 @@ class mrp_production_workcenter_line(osv.osv):
prod_obj.write(cr, uid, [prod.production_id.id], {'date_start':dstart}, context=context, mini=False) prod_obj.write(cr, uid, [prod.production_id.id], {'date_start':dstart}, context=context, mini=False)
return result return result
def draft_notification(self, cr, uid, ids):
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 = _("<em>%s</em> Work Order is <b>created</b>.") % (workorder.name)
prod_obj.message_append_note(cr, uid, [prod.id], '', message)
womessage = _("Work Order is <b>created</b> for <em>%s</em> production order.") % (prod.id.name)
self.message_append_note(cr, uid, ids, '', womessage)
return True
def start_notification(self, cr, uid, ids):
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 = _("<em>%s</em> Work Order is <b>started</b>.") % (workorder.name)
prod_obj.message_append_note(cr, uid, [prod.id], '', message)
womessage = _("Work Order is <b>started</b> for <em>%s</em> production order.") % (prod.id.name)
self.message_append_note(cr, uid, ids, '', womessage)
return True
def done_notification(self, cr, uid, ids):
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 = _("<em>%s</em>Work Order is <b>finished</b>.") % (workorder.name)
prod_obj.message_append_note(cr, uid, [prod.id], '', message)
womessage = _("Work Order is <b>done</b> for <em>%s</em> production order.") % (prod.id.name)
self.message_append_note(cr, uid, ids, '', womessage)
return True
def pending_notification(self, cr, uid, ids):
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 = _("<em>%s</em>Work Order is <b>pending</b>.") % (workorder.name)
prod_obj.message_append_note(cr, uid, [prod.id], '', message)
womessage = _("Work Order is <b>pending</b> for <em>%s</em> production order.") % (prod.id.name)
self.message_append_note(cr, uid, ids, '', womessage)
return True
def cancel_notification(self, cr, uid, ids):
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 = _("<em>%s</em>Work Order is <b>cancelled</b>.") % (workorder.name)
prod_obj.message_append_note(cr, uid, [prod.id], '', message)
womessage = _("Work Order is <b>cancelled</b> for <em>%s</em> production order.") % (prod.id.name)
self.message_append_note(cr, uid, ids, '', womessage)
return True
def action_draft(self, cr, uid, ids): def action_draft(self, cr, uid, ids):
""" Sets state to draft. """ Sets state to draft.
@return: True @return: True
""" """
self.write(cr, uid, ids, {'state':'draft'}) self.write(cr, uid, ids, {'state':'draft'})
self.draft_notification(cr, uid, ids)
return True return True
def action_start_working(self, cr, uid, ids): def action_start_working(self, cr, uid, ids):
@ -169,6 +220,7 @@ class mrp_production_workcenter_line(osv.osv):
""" """
self.modify_production_order_state(cr, uid, ids, 'start') 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.write(cr, uid, ids, {'state':'startworking', 'date_start': time.strftime('%Y-%m-%d %H:%M:%S')})
self.start_notification(cr, uid, ids)
return True return True
def action_done(self, cr, uid, ids): def action_done(self, cr, uid, ids):
@ -185,6 +237,7 @@ class mrp_production_workcenter_line(osv.osv):
delay += (date_finished-date_start).seconds / float(60*60) delay += (date_finished-date_start).seconds / float(60*60)
self.write(cr, uid, ids, {'state':'done', 'date_finished': date_now,'delay':delay}) self.write(cr, uid, ids, {'state':'done', 'date_finished': date_now,'delay':delay})
self.done_notification(cr, uid, ids)
self.modify_production_order_state(cr,uid,ids,'done') self.modify_production_order_state(cr,uid,ids,'done')
return True return True
@ -193,6 +246,7 @@ class mrp_production_workcenter_line(osv.osv):
@return: True @return: True
""" """
self.write(cr, uid, ids, {'state':'cancel'}) self.write(cr, uid, ids, {'state':'cancel'})
self.cancel_notification(cr, uid, ids)
return True return True
def action_pause(self, cr, uid, ids): def action_pause(self, cr, uid, ids):
@ -200,6 +254,7 @@ class mrp_production_workcenter_line(osv.osv):
@return: True @return: True
""" """
self.write(cr, uid, ids, {'state':'pause'}) self.write(cr, uid, ids, {'state':'pause'})
self.pending_notification(cr, uid, ids)
return True return True
def action_resume(self, cr, uid, ids): def action_resume(self, cr, uid, ids):
@ -207,6 +262,7 @@ class mrp_production_workcenter_line(osv.osv):
@return: True @return: True
""" """
self.write(cr, uid, ids, {'state':'startworking'}) self.write(cr, uid, ids, {'state':'startworking'})
self.start_notification(cr, uid, ids)
return True return True
mrp_production_workcenter_line() mrp_production_workcenter_line()
@ -251,7 +307,7 @@ class mrp_production(osv.osv):
if prod.workcenter_lines: if prod.workcenter_lines:
wf_service.trg_validate(uid, 'mrp.production.workcenter.line', prod.workcenter_lines[0].id, 'button_start_working', cr) 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) return super(mrp_production,self).action_in_production(cr, uid, ids)
def action_cancel(self, cr, uid, ids, context=None): def action_cancel(self, cr, uid, ids, context=None):
""" Cancels work order if production order is canceled. """ Cancels work order if production order is canceled.
@return: Super method @return: Super method

View File

@ -118,6 +118,7 @@
</group> </group>
</page> </page>
</notebook> </notebook>
<field name="message_ids_social" widget="ThreadView"/>
</form> </form>
</field> </field>
</record> </record>

View File

@ -167,7 +167,7 @@ class product_uom(osv.osv):
if value == 'reference': if value == 'reference':
return {'value': {'factor': 1, 'factor_inv': 1}} return {'value': {'factor': 1, 'factor_inv': 1}}
return {} return {}
def write(self, cr, uid, ids, vals, context=None): def write(self, cr, uid, ids, vals, context=None):
if 'category_id' in vals: if 'category_id' in vals:
for uom in self.browse(cr, uid, ids, context=context): for uom in self.browse(cr, uid, ids, context=context):
@ -231,7 +231,7 @@ class product_category(osv.osv):
_parent_store = True _parent_store = True
_parent_order = 'sequence, name' _parent_order = 'sequence, name'
_order = 'parent_left' _order = 'parent_left'
def _check_recursion(self, cr, uid, ids, context=None): def _check_recursion(self, cr, uid, ids, context=None):
level = 100 level = 100
while len(ids): while len(ids):
@ -259,7 +259,7 @@ class product_template(osv.osv):
_description = "Product Template" _description = "Product Template"
def _get_main_product_supplier(self, cr, uid, product, context=None): 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 returning the corresponding ``supplierinfo`` record, or False
if none were found. The default strategy is to select the if none were found. The default strategy is to select the
supplier with the highest priority (i.e. smallest sequence). supplier with the highest priority (i.e. smallest sequence).
@ -503,6 +503,7 @@ class product_product(osv.osv):
_description = "Product" _description = "Product"
_table = "product_product" _table = "product_product"
_inherits = {'product.template': 'product_tmpl_id'} _inherits = {'product.template': 'product_tmpl_id'}
_inherit = ['mail.thread']
_order = 'default_code,name_template' _order = 'default_code,name_template'
_columns = { _columns = {
'qty_available': fields.function(_product_qty_available, type='float', string='Quantity On Hand'), 'qty_available': fields.function(_product_qty_available, type='float', string='Quantity On Hand'),
@ -526,7 +527,18 @@ class product_product(osv.osv):
'color': fields.integer('Color Index'), 'color': fields.integer('Color Index'),
'product_image': fields.binary('Image'), '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_notification(cr, uid, [obj_id], context=context)
return obj_id
def create_notification(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
self.message_append_note(cr, uid, ids, _('System notification'),
_("Product is <b>Created</b>."), type='notification', context=context)
return True
def unlink(self, cr, uid, ids, context=None): def unlink(self, cr, uid, ids, context=None):
unlink_ids = [] unlink_ids = []
unlink_product_tmpl_ids = [] unlink_product_tmpl_ids = []

View File

@ -87,7 +87,7 @@
</group> </group>
<group colspan="1" col="1"> <group colspan="1" col="1">
<field name="product_image" widget='image' nolabel="1"/> <field name="product_image" widget='image' nolabel="1"/>
</group> </group>
</group> </group>
<notebook colspan="4"> <notebook colspan="4">
@ -192,6 +192,7 @@
</field> </field>
</page> </page>
</notebook> </notebook>
<field name="message_ids_social" widget="ThreadView"/>
</form> </form>
</field> </field>
</record> </record>
@ -257,24 +258,24 @@
<field name="view_mode">tree,form,kanban</field> <field name="view_mode">tree,form,kanban</field>
<field name="view_type">form</field> <field name="view_type">form</field>
<field name="context">{"search_default_filter_to_sell":1}</field> <field name="context">{"search_default_filter_to_sell":1}</field>
<field name="view_id" ref="product_product_tree_view"/> <field name="view_id" ref="product_product_tree_view"/>
<field name="search_view_id" ref="product_search_form_view"/> <field name="search_view_id" ref="product_search_form_view"/>
<field name="help">You must define a Product for everything you buy or sell. Products can be raw materials, stockable products, consumables or services. The Product form contains detailed information about your products related to procurement logistics, sales price, product category, suppliers and so on.</field> <field name="help">You must define a Product for everything you buy or sell. Products can be raw materials, stockable products, consumables or services. The Product form contains detailed information about your products related to procurement logistics, sales price, product category, suppliers and so on.</field>
</record> </record>
<record id="open_view_product_tree1" model="ir.actions.act_window.view"> <record id="open_view_product_tree1" model="ir.actions.act_window.view">
<field name="sequence" eval="1"/> <field name="sequence" eval="1"/>
<field name="view_mode">tree</field> <field name="view_mode">tree</field>
<field name="view_id" ref="product_product_tree_view"/> <field name="view_id" ref="product_product_tree_view"/>
<field name="act_window_id" ref="product_normal_action_sell"/> <field name="act_window_id" ref="product_normal_action_sell"/>
</record> </record>
<record id="open_view_product_form1" model="ir.actions.act_window.view"> <record id="open_view_product_form1" model="ir.actions.act_window.view">
<field name="sequence" eval="2"/> <field name="sequence" eval="2"/>
<field name="view_mode">form</field> <field name="view_mode">form</field>
<field name="view_id" ref="product_normal_form_view"/> <field name="view_id" ref="product_normal_form_view"/>
<field name="act_window_id" ref="product_normal_action_sell"/> <field name="act_window_id" ref="product_normal_action_sell"/>
</record> </record>
<menuitem id="base.menu_product" name="Products" parent="base.menu_base_partner" sequence="9"/> <menuitem id="base.menu_product" name="Products" parent="base.menu_base_partner" sequence="9"/>
<menuitem action="product.product_normal_action_sell" id="product.menu_products" parent="base.menu_product" sequence="1"/> <menuitem action="product.product_normal_action_sell" id="product.menu_products" parent="base.menu_product" sequence="1"/>

View File

@ -26,6 +26,7 @@ import tools
class stock_change_product_qty(osv.osv_memory): class stock_change_product_qty(osv.osv_memory):
_name = "stock.change.product.qty" _name = "stock.change.product.qty"
_inherit = ['mail.thread']
_description = "Change Product Quantity" _description = "Change Product Quantity"
_columns = { _columns = {
'product_id' : fields.many2one('product.product', 'Product'), 'product_id' : fields.many2one('product.product', 'Product'),
@ -98,9 +99,19 @@ class stock_change_product_qty(osv.osv_memory):
inventry_obj.action_confirm(cr, uid, [inventory_id], context=context) inventry_obj.action_confirm(cr, uid, [inventory_id], context=context)
inventry_obj.action_done(cr, uid, [inventory_id], context=context) inventry_obj.action_done(cr, uid, [inventory_id], context=context)
self.quantity_change_notification(cr, uid, [data.id], context)
return {} return {}
def quantity_change_notification (self, cr, uid, ids, context=None):
prod_obj = self.pool.get('product.product')
location_obj = self.pool.get('stock.location')
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):
message = _("<b>Quantity is changed</b> to <em>%s</em> for <em>%s</em> location.") % (data.new_quantity,location_name)
prod_obj.message_append_note(cr, uid, [prod.id], '', message)
stock_change_product_qty() stock_change_product_qty()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: