[WIP] Create procurement when Phantom
authorJosse Colpaert <jco@odoo.com>
Fri, 8 Aug 2014 15:22:14 +0000 (17:22 +0200)
committerJosse Colpaert <jco@odoo.com>
Wed, 3 Sep 2014 17:18:16 +0000 (19:18 +0200)
addons/mrp/mrp.py
addons/mrp/mrp_view.xml
addons/mrp/stock.py
addons/product/product.py
addons/sale_service/models/sale_service.py
addons/sale_stock/sale_stock.py
addons/stock_account/product_view.xml

index 2ede7b2..a8c39c7 100644 (file)
@@ -1115,6 +1115,26 @@ class mrp_production(osv.osv):
     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.
@@ -1126,7 +1146,11 @@ class mrp_production(osv.osv):
 
             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:
index bd622cb..81c7885 100644 (file)
                 <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)"/>
index 4b44207..cd66ae8 100644 (file)
@@ -65,6 +65,8 @@ class StockMove(osv.osv):
         """
         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)
@@ -72,24 +74,44 @@ class StockMove(osv.osv):
             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)
index 8c0a919..5d16651 100644 (file)
@@ -764,6 +764,9 @@ class product_template(osv.osv):
         return super(product_template, self).name_get(cr, user, ids, context)
 
 
+
+
+
 class product_product(osv.osv):
     _name = "product.product"
     _description = "Product"
@@ -1089,6 +1092,11 @@ class product_product(osv.osv):
         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"
index 3b0832a..386761f 100644 (file)
@@ -139,13 +139,22 @@ class project_task(osv.osv):
                 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'
index f2c6f52..6489690 100644 (file)
@@ -202,6 +202,17 @@ class sale_order(osv.osv):
         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'
 
index cf8af6b..97eb7a0 100644 (file)
@@ -26,7 +26,7 @@
             <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':['&amp;', ('valuation','=','real_time'), ('cost_method', 'in', ['standard', 'average'])]}" nolabel="1"/>
@@ -36,7 +36,7 @@
                     </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')]}"/>