def _make_production_consume_line(self, cr, uid, line, context=None):
return self._make_consume_line_from_data(cr, uid, line.production_id, line.product_id, line.product_uom.id, line.product_qty, line.product_uos.id, line.product_uos_qty, context=context)
+
+ def _make_service_procurement(self, cr, uid, line, context=None):
+ prod_obj = self.pool.get('product.product')
+ if prod_obj.need_procurement(cr, uid, [line.product_id.id], context=context):
+ vals = {
+ 'name': line.production_id.name,
+ 'origin': line.production_id.name,
+ 'company_id': line.production_id.company_id.id,
+ 'date_planned': line.production_id.date_planned,
+ 'product_id': line.product_id.id,
+ 'product_qty': line.product_qty,
+ 'product_uom': line.product_uom.id,
+ 'product_uos_qty': line.product_uos_qty,
+ 'product_uos': line.product_uos.id,
+ }
+ proc_obj = self.pool.get("procurement.order")
+ proc = proc_obj.create(cr, uid, vals, context=context)
+ proc_obj.run(cr, uid, [proc], context=context)
+
+
def action_confirm(self, cr, uid, ids, context=None):
""" Confirms production order.
@return: Newly generated Shipment Id.
stock_moves = []
for line in production.product_lines:
- stock_move_id = self._make_production_consume_line(cr, uid, line, context=context)
+ if line.product_id.type != 'service':
+ stock_move_id = self._make_production_consume_line(cr, uid, line, context=context)
+ else:
+ self._make_service_procurement(cr, uid, line, context=context)
+ stock_move_id = False
if stock_move_id:
stock_moves.append(stock_move_id)
if stock_moves:
<form string="Bill of Material">
<group>
<group>
- <field name="product_tmpl_id" on_change="onchange_product_tmpl_id(product_tmpl_id, product_qty, context)"/>
- <field name="product_id"/>
- <field name="product_uom" class="oe_inline" on_change="onchange_uom(product_tmpl_id, product_uom)" groups="product.group_uom"/>
+ <field name="product_tmpl_id" domain="[('type', '!=', 'service')]" on_change="onchange_product_tmpl_id(product_tmpl_id, product_qty, context)"/>
+ <field name="product_id" domain="[('type', '!=', 'service')]"/>
<label for="product_qty" string="Quantity"/>
<div>
<field name="product_qty" class="oe_inline" on_change="onchange_product_tmpl_id(product_tmpl_id, product_qty, context)"/>
</div>
<group>
<group>
- <field name="product_id" on_change="product_id_change(product_id, product_qty)" domain="[('bom_ids','!=',False),('bom_ids.type','!=','phantom')]" class="oe_inline" context='{"default_type": "product"}'/>
+ <field name="product_id" on_change="product_id_change(product_id, product_qty)" domain="[('bom_ids','!=',False),('bom_ids.type','!=','phantom'),('type','!=','service')]" class="oe_inline" context='{"default_type": "product"}'/>
<label for="product_qty"/>
<div>
<field name="product_qty" class="oe_inline" on_change="product_id_change(product_id, product_qty)"/>
"""
bom_obj = self.pool.get('mrp.bom')
move_obj = self.pool.get('stock.move')
+ prod_obj = self.pool.get("product.product")
+ proc_obj = self.pool.get("procurement.order")
to_explode_again_ids = []
processed_ids = []
bis = self._check_phantom_bom(cr, uid, move, context=context)
factor = move.product_qty
bom_point = bom_obj.browse(cr, SUPERUSER_ID, bis[0], context=context)
res = bom_obj._bom_explode(cr, SUPERUSER_ID, bom_point, move.product_id, factor, [])
+
state = 'confirmed'
if move.state == 'assigned':
state = 'assigned'
for line in res[0]:
- valdef = {
- 'picking_id': move.picking_id.id if move.picking_id else False,
- 'product_id': line['product_id'],
- 'product_uom': line['product_uom'],
- 'product_uom_qty': line['product_qty'],
- 'product_uos': line['product_uos'],
- 'product_uos_qty': line['product_uos_qty'],
- 'state': state,
- 'name': line['name'],
- 'procurement_id': move.procurement_id.id,
- 'split_from': move.id, #Needed in order to keep purchase connection, but will be removed by unlink
- }
- mid = move_obj.copy(cr, uid, move.id, default=valdef)
- to_explode_again_ids.append(mid)
+ product = prod_obj.browse(cr, uid, line['product_id'], context=context)
+ if product.type != 'service':
+ valdef = {
+ 'picking_id': move.picking_id.id if move.picking_id else False,
+ 'product_id': line['product_id'],
+ 'product_uom': line['product_uom'],
+ 'product_uom_qty': line['product_qty'],
+ 'product_uos': line['product_uos'],
+ 'product_uos_qty': line['product_uos_qty'],
+ 'state': state,
+ 'name': line['name'],
+ 'procurement_id': move.procurement_id.id,
+ 'split_from': move.id, #Needed in order to keep purchase connection, but will be removed by unlink
+ }
+ mid = move_obj.copy(cr, uid, move.id, default=valdef)
+ to_explode_again_ids.append(mid)
+ else:
+ if prod_obj.need_procurement(cr, uid, [product.id], context=context):
+ vals = {
+ 'name': move.rule_id and move.rule_id.name or "/",
+ 'origin': move.origin,
+ 'company_id': move.company_id and move.company_id.id or False,
+ 'date_planned': move.date,
+ 'product_id': line['product_id'],
+ 'product_qty': line['product_qty'],
+ 'product_uom': line['product_uom'],
+ 'product_uos_qty': line['product_uos_qty'],
+ 'product_uos': line['product_uos'],
+ 'group_id': move.group_id.id,
+ 'priority': move.priority,
+ }
+ proc = proc_obj.create(cr, uid, vals, context=context)
+ proc_obj.run(cr, uid, [proc], context=context)
#delete the move with original product which is not relevant anymore
move_obj.unlink(cr, SUPERUSER_ID, [move.id], context=context)
return super(product_template, self).name_get(cr, user, ids, context)
+
+
+
class product_product(osv.osv):
_name = "product.product"
_description = "Product"
return super(product_product, self).create(cr, uid, vals, context=ctx)
+
+ def need_procurement(self, cr, uid, ids, context=None):
+ return False
+
+
class product_packaging(osv.osv):
_name = "product.packaging"
_description = "Packaging"
self._validate_subflows(cr, uid, ids, context=context)
return res
-class product_product(osv.osv):
+class product_template(osv.osv):
_inherit = "product.template"
_columns = {
'project_id': fields.many2one('project.project', 'Project', ondelete='set null',),
'auto_create_task': fields.boolean('Create Task Automatically', help="Thick this option if you want to create a task automatically each time this product is sold"),
}
+class product_product(osv.osv):
+ _inherit = "product.product"
+
+ def need_procurement(self, cr, uid, ids, context=None):
+ for product in self.browse(cr, uid, ids, context=context):
+ if product.type == 'service' and product.auto_create_task:
+ return True
+ return super(product_product, self).need_procurement(cr, uid, ids, context=context)
+
class sale_order_line(osv.osv):
_inherit = 'sale.order.line'
return False
+class product_product(osv.osv):
+ _inherit = 'product.product'
+
+ def need_procurement(self, cr, uid, ids, context=None):
+ #when sale is installed alone, there is no need to create procurements, but with sale_stock
+ #we must create a procurement for each product that is not a service.
+ for product in self.browse(cr, uid, ids, context=context):
+ if product.type != 'service':
+ return True
+ return super(product_product, self).need_procurement(cr, uid, ids, context=context)
+
class sale_order_line(osv.osv):
_inherit = 'sale.order.line'
<field name="inherit_id" ref="product.product_template_form_view"/>
<field name="arch" type="xml">
<field name="standard_price" position="replace">
- <field name="cost_method" groups="stock_account.group_inventory_valuation"/>
+ <field name="cost_method" groups="stock_account.group_inventory_valuation" attrs="{'invisible': [('type','=','service')]}"/>
<label string="Cost Price" for="standard_price" align="1.0" groups="base.group_user"/>
<div groups="base.group_user">
<field name="standard_price" attrs="{'readonly':['&', ('valuation','=','real_time'), ('cost_method', 'in', ['standard', 'average'])]}" nolabel="1"/>
</div>
</field>
<xpath expr="//group[@name='properties']" position="before">
- <group groups="stock_account.group_inventory_valuation">
+ <group groups="stock_account.group_inventory_valuation" attrs="{'invisible': [('type','=','service')]}">
<separator string="Inventory Valuation" colspan="4"/>
<group colspan="2" col="2">
<field name="valuation" attrs="{'readonly':[('type', '=', 'service')]}"/>