[MERGE] Merged with uco-dev-addons1:

Following are the changes:
Task 819: mrp_procurement->procurement
Task 808: To add doc string to MRP & related modules
Task 813: To add doc string to stock and related modules with wizards
Task 909: multilevel bom: * Put multi_level_bom = True on demo data for product appearing into Manufacturing/Master Data/Master Bill of Materials. * Put domain = [('multi_level_bom','=',True)] on menu Manufacturing/Master Data/Master Bill of Materials
Task 290: Write YAML scenario for mrp and mrp related modules.

bzr revid: uco@tinyerp.com-20100609114330-pcupocwrfocbyop2
This commit is contained in:
uco (OpenERP)
2010-06-09 17:13:30 +05:30
96 changed files with 1324 additions and 786 deletions
+3 -1
View File
@@ -27,7 +27,9 @@
'author': 'Tiny',
'website': 'http://www.openerp.com',
'depends': ['base'],
'init_xml': [],
'init_xml': [
'base_action_rule_data.xml'
],
'update_xml': [
'base_action_rule_view.xml',
'security/ir.model.access.csv',
+19 -22
View File
@@ -136,7 +136,7 @@ the rule to mark CC(mail to any other person defined in actions)."),
def pre_action(self, cr, uid, ids, model, context=None):
# Searching for action rules
cr.execute("SELECT m.model, r.id from base_action_rule r left join ir_model m on (m.id = r.name)")
cr.execute("SELECT model.model, rule.id FROM base_action_rule rule LEFT JOIN ir_model model on (model.id = rule.name)")
res = cr.fetchall()
# Check if any rule matching with current object
for obj_name, rule_id in res:
@@ -147,7 +147,7 @@ the rule to mark CC(mail to any other person defined in actions)."),
self._action(cr, uid, [rule_id], obj.browse(cr, uid, ids, context=context))
return True
def new_create(self, old_create, model, context=None):
def _create(self, old_create, model, context=None):
if not context:
context = {}
def make_call_old(cr, uid, vals, context=context):
@@ -157,7 +157,7 @@ the rule to mark CC(mail to any other person defined in actions)."),
return new_id
return make_call_old
def new_write(self, old_write, model, context=None):
def _write(self, old_write, model, context=None):
if not context:
context = {}
def make_call_old(cr, uid, ids, vals, context=context):
@@ -168,38 +168,35 @@ the rule to mark CC(mail to any other person defined in actions)."),
return old_write(cr, uid, ids, vals, context=context)
return make_call_old
def create(self, cr, uid, vals, context=None):
def _register_hook(self, cr, uid, ids, context=None):
if not context:
context = {}
res_id = super(base_action_rule, self).create(cr, uid, vals, context)
model_pool = self.pool.get('ir.model')
model = model_pool.browse(cr, uid, vals.get('name'), context=context).model
obj_pool = self.pool.get(model)
obj_pool.__setattr__('old_create', obj_pool.create)
obj_pool.__setattr__('old_write', obj_pool.write)
obj_pool.__setattr__('create', self.new_create(obj_pool.create, model, context=context))
obj_pool.__setattr__('write', self.new_write(obj_pool.write, model, context=context))
for action_rule in self.browse(cr, uid, ids, context=context):
model = action_rule.name.model
obj_pool = self.pool.get(model)
obj_pool.__setattr__('create', self._create(obj_pool.create, model, context=context))
obj_pool.__setattr__('write', self._write(obj_pool.write, model, context=context))
return True
def create(self, cr, uid, vals, context=None):
res_id = super(base_action_rule, self).create(cr, uid, vals, context)
self._register_hook(cr, uid, [res_id], context=context)
return res_id
def write(self, cr, uid, ids, vals, context=None):
res = super(base_action_rule, self).write(cr, uid, ids, vals, context)
model_pool = self.pool.get('ir.model')
if not context:
context = {}
for rule in self.browse(cr, uid, ids, context=context):
model = model_pool.browse(cr, uid, rule.name.id, context=context).model
obj_pool = self.pool.get(model)
obj_pool.__setattr__('old_create', obj_pool.create)
obj_pool.__setattr__('old_write', obj_pool.write)
obj_pool.__setattr__('create', self.new_create(obj_pool.create, model, context=context))
obj_pool.__setattr__('write', self.new_write(obj_pool.write, model, context=context))
self._register_hook(cr, uid, ids, context=context)
return res
def _check(self, cr, uid, automatic=False, use_new_cursor=False, \
context=None):
"""
This Function is call by scheduler.
"""
rule_pool= self.pool.get('base.action.rule')
rule_ids = rule_pool.search(cr, uid, [], context=context)
return rule_pool.write(cr, uid, rule_ids, {}, context=context)
return self._register_hook(cr, uid, rule_ids, context=context)
def format_body(self, body):
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record id="ir_cron_crm_action" model="ir.cron">
<field name="name">Check Action Rules</field>
<field name="interval_number">4</field>
<field name="interval_type">hours</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
<field eval="'base.action.rule'" name="model"/>
<field eval="'_check'" name="function"/>
<field eval="'()'" name="args"/>
</record>
</data>
</openerp>
@@ -14,8 +14,8 @@
<hpaned position="100">
<child1>
<action colspan="4" height="200" name="%(mrp.mrp_production_action2)d" string="Next production orders" width="510"/>
<action colspan="4" name="%(stock.action_picking_all)d" string="Deliveries (Out picking)" domain="[('state','=','assigned'),('type','=','out')]"/>
<action colspan="4" name="%(mrp_procurement.mrp_procurement_action4)d" string="Procurements in Exception"/>
<action colspan="4" name="%(stock.action_picking_tree)d" string="Deliveries (Out picking)" domain="[('state','=','assigned'),('type','=','out')]"/>
<action colspan="4" name="%(procurement.procurement_action4)d" string="Procurements in Exception"/>
</child1>
@@ -23,7 +23,7 @@
<form string="Warehouse board">
<hpaned position="100">
<child1>
<action colspan="4" name="%(mrp_procurement.mrp_procurement_action5)d" string="Procurement Exceptions" width="510" />
<action colspan="4" name="%(procurement.procurement_action5)d" string="Procurement Exceptions" width="510" />
<action colspan="4" name="%(action_reception_picking_move_board)d" string="Products To Receive" />
</child1>
+1 -10
View File
@@ -7,16 +7,7 @@
</record>
<record id="ir_cron_crm_action" model="ir.cron">
<field name="name">Check cases rules</field>
<field name="interval_number">4</field>
<field name="interval_type">hours</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
<field eval="'crm.case'" name="model"/>
<field eval="'_check'" name="function"/>
<field eval="'()'" name="args"/>
</record>
</data>
</openerp>
+1 -1
View File
@@ -26,6 +26,6 @@ import installer
import wizard
import report
import company
import mrp_procurement
import procurement
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+2 -2
View File
@@ -26,7 +26,7 @@
"author" : "Tiny",
"website" : "http://www.openerp.com",
"category" : "Generic Modules/Production",
"depends" : ["mrp_procurement", "stock", "resource", "purchase", "product","process"],
"depends" : ["procurement", "stock", "resource", "purchase", "product","process"],
"description": """
This is the base module to manage the manufacturing process in Open ERP.
@@ -76,7 +76,7 @@
'report/mrp_report_view.xml',
'report/mrp_production_order_view.xml',
],
'demo_xml': ['mrp_demo.xml', 'mrp_order_point.xml'],
'demo_xml': ['mrp_demo.xml'],
'test': [
'test/mrp_phantom_bom.yml',
'test/mrp_production_order.yml',
+2 -16
View File
@@ -460,18 +460,6 @@ class mrp_production(osv.osv):
result[prod.id] = prod.date_planned[:10]
return result
def _ref_calc(self, cr, uid, ids, field_names=None, arg=False, context={}):
""" Finds reference sale order for production order.
@param field_names: Names of fields.
@param arg: User defined arguments
@return: Dictionary of values.
"""
res = {}
for f in field_names:
for order_id in ids:
res[order_id] = {f:False}
return res
_columns = {
'name': fields.char('Reference', size=64, required=True),
'origin': fields.char('Source Document', size=64, help="Reference of the document that generated this production order request."),
@@ -512,8 +500,6 @@ class mrp_production(osv.osv):
'hour_total': fields.function(_production_calc, method=True, type='float', string='Total Hours', multi='workorder'),
'cycle_total': fields.function(_production_calc, method=True, type='float', string='Total Cycles', multi='workorder'),
'sale_name': fields.function(_ref_calc, method=True, multi='sale_name', type='char', string='Sale Name', help='Indicate the name of sale order.'),
'sale_ref': fields.function(_ref_calc, method=True, multi='sale_ref', type='char', string='Sale Reference', help='Indicate the Customer Reference from sale order.'),
'company_id': fields.many2one('res.company','Company',required=True),
}
_defaults = {
@@ -831,7 +817,7 @@ class mrp_production(osv.osv):
seq_obj = self.pool.get('ir.sequence')
pick_obj = self.pool.get('stock.picking')
move_obj = self.pool.get('stock.move')
proc_obj = self.pool.get('mrp.procurement')
proc_obj = self.pool.get('procurement.order')
wf_service = netsvc.LocalService("workflow")
for production in self.browse(cr, uid, ids):
if not production.product_lines:
@@ -925,7 +911,7 @@ class mrp_production(osv.osv):
'move_id': move_id,
'company_id': production.company_id.id,
})
wf_service.trg_validate(uid, 'mrp.procurement', proc_id, 'button_confirm', cr)
wf_service.trg_validate(uid, 'procurement.order', proc_id, 'button_confirm', cr)
proc_ids.append(proc_id)
wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr)
self.write(cr, uid, [production.id], {'picking_id': picking_id, 'move_lines': [(6,0,moves)], 'state':'confirmed'})
-15
View File
@@ -16,20 +16,5 @@
<field name="number_increment">1</field>
</record>
<record id="sequence_mrp_op_type" model="ir.sequence.type">
<field name="name">Stock orderpoint</field>
<field name="code">mrp.warehouse.orderpoint</field>
</record>
<record id="sequence_mrp_op" model="ir.sequence">
<field name="name">Stock orderpoint</field>
<field name="code">mrp.warehouse.orderpoint</field>
<field name="prefix">OP/</field>
<field name="padding">5</field>
<field name="number_next">1</field>
<field name="number_increment">1</field>
</record>
</data>
</openerp>
+13
View File
@@ -171,6 +171,7 @@
<field name="routing_id" ref="mrp_routing_2"/>
<field name="type">normal</field>
<field model="product.product" name="product_id" ref="product.product_product_cpu_gen"/>
<field name="multi_level_bom">True</field>
</record>
<record id="mrp_bom_1" model="mrp.bom">
@@ -180,6 +181,7 @@
<field name="product_qty">1.0</field>
<field name="routing_id" ref="mrp_routing_0"/>
<field model="product.product" name="product_id" ref="product.product_product_pc2" />
<field name="multi_level_bom">True</field>
</record>
<record id="mrp_bom_2" model="mrp.bom">
<field name="name">Assembly Medium PC</field>
@@ -187,6 +189,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field model="product.product" name="product_id" ref="product.product_product_pc3"/>
<field name="multi_level_bom">True</field>
</record>
<record id="mrp_bom_3" model="mrp.bom">
<field name="name">Assembly Customizable PC</field>
@@ -194,6 +197,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field model="product.product" name="product_id" ref="product.product_product_pc4"/>
<field name="multi_level_bom">True</field>
</record>
<record id="mrp_bom_4" model="mrp.bom">
<field name="name">HDD on demand</field>
@@ -202,6 +206,7 @@
<field name="product_qty">1.0</field>
<field name="type">phantom</field>
<field model="product.product" name="product_id" ref="product.product_product_20"/>
<field name="multi_level_bom">True</field>
</record>
<record id="mrp_bom_5" model="mrp.bom">
<field name="name">RAM on demand</field>
@@ -210,6 +215,7 @@
<field name="product_qty">1.0</field>
<field name="type">phantom</field>
<field model="product.product" name="product_id" ref="product.product_product_21"/>
<field name="multi_level_bom">True</field>
</record>
<record id="mrp_bom_6" model="mrp.bom">
<field name="name">HDD on demand</field>
@@ -218,6 +224,7 @@
<field name="product_qty">1.0</field>
<field name="type">phantom</field>
<field model="product.product" name="product_id" ref="product.product_product_20"/>
<field name="multi_level_bom">True</field>
</record>
<record id="mrp_bom_7" model="mrp.bom">
<field name="name">HDD on demand</field>
@@ -226,6 +233,7 @@
<field name="product_qty">1.0</field>
<field name="type">phantom</field>
<field model="product.product" name="product_id" ref="product.product_product_20"/>
<field name="multi_level_bom">True</field>
</record>
<record id="mrp_bom_8" model="mrp.bom">
<field name="name">HDD Seagate</field>
@@ -234,6 +242,7 @@
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field model="product.product" name="product_id" ref="product.product_product_hdd1"/>
<field name="multi_level_bom">True</field>
</record>
<record id="mrp_bom_9" model="mrp.bom">
<field name="name">Assembly Basic PC</field>
@@ -243,6 +252,7 @@
<field name="routing_id" ref="mrp_routing_0"/>
<field name="type">normal</field>
<field model="product.product" name="product_id" ref="product.product_product_pc1"/>
<field name="multi_level_bom">True</field>
</record>
<record id="mrp_bom_10" model="mrp.bom">
<field name="name">Complete PC with peripherals</field>
@@ -250,6 +260,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field model="product.product" name="product_id" ref="product.product_product_23"/>
<field name="multi_level_bom">True</field>
</record>
<record id="mrp_bom_11" model="mrp.bom">
<field name="name">RAM on demand</field>
@@ -258,6 +269,7 @@
<field name="product_qty">1.0</field>
<field name="type">phantom</field>
<field model="product.product" name="product_id" ref="product.product_product_23"/>
<field name="multi_level_bom">True</field>
</record>
<record id="mrp_bom_13" model="mrp.bom">
@@ -266,6 +278,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field model="product.product" name="product_id" ref="product.product_product_cpu3"/>
<field name="multi_level_bom">True</field>
</record>
<record id="mrp_bom_kit" model="mrp.bom">
+10 -12
View File
@@ -255,12 +255,12 @@
<field name="product_uos" groups="product.group_uos,base.group_extended" widget="selection"/>
<field name="product_uos_qty" groups="product.group_uos,base.group_extended" />
<newline/>
<field name="multi_level_bom" />
<field name="multi_level_bom"/>
<field name="type" groups="base.group_extended"/>
<field name="company_id" select="1" groups="base.group_multi_company" widget="selection"/>
</group>
<notebook colspan="4" >
<page string="Components" attrs="{'invisible': [('bom_id','!=',False),('multi_level_bom','=',False)]}">
<page string="Components" attrs="{'invisible': [('multi_level_bom','=',False)]}">
<field colspan="4" name="bom_lines" nolabel="1" widget="one2many_list" />
</page>
<page string="Revisions" groups="base.group_extended" attrs="{'invisible': [('bom_id','!=',False),('multi_level_bom','=',False)]}">
@@ -329,7 +329,7 @@
<field name="type">ir.actions.act_window</field>
<field name="res_model">mrp.bom</field>
<field name="view_type">form</field>
<field name="domain">[('bom_id','=',False)]</field>
<field name="domain">[('bom_id','=',False),('multi_level_bom','=',True)]</field>
<field name="search_view_id" ref="view_mrp_bom_filter"/>
</record>
<record id="mrp_bom_form_action2" model="ir.actions.act_window">
@@ -406,18 +406,18 @@
Procurement
-->
<menuitem action="mrp_procurement.mrp_procurement_action" id="menu_mrp_procurement_action"
<menuitem action="procurement.procurement_action" id="menu_mrp_procurement_action"
parent="mrp.menu_mrp_manufacturing" sequence="2" />
<!-- <menuitem action="mrp_procurement.mrp_procurement_action5" id="menu_mrp_procurement_exception_action"-->
<!-- <menuitem action="procurement.procurement_action5" id="menu_mrp_procurement_exception_action"-->
<!-- parent="mrp.menu_mrp_control" sequence="1" />-->
<menuitem id="menu_mrp_scheduler" name="Schedulers" parent="base.menu_mrp_root" sequence="4"/>
<menuitem action="mrp_procurement.action_compute_schedulers" id="mrp_Sched_all" parent="mrp.menu_mrp_scheduler" sequence="90"/>
<menuitem action="procurement.action_compute_schedulers" id="mrp_Sched_all" parent="mrp.menu_mrp_scheduler" sequence="90"/>
<!--
Order Point
-->
<menuitem action="mrp_procurement.action_orderpoint_form" id="menu_action_orderpoint_form" parent="mrp.menu_mrp_reordering"/>
<menuitem action="procurement.action_orderpoint_form" id="menu_action_orderpoint_form" parent="mrp.menu_mrp_reordering"/>
<!--
Production Management
@@ -640,8 +640,6 @@
<field name="date_finnished"/>
<field name="picking_id" groups="base.group_extended"/>
<field name="move_prod_id" groups="base.group_extended"/>
<field name="sale_name" groups="base.group_extended"/>
<field name="sale_ref" groups="base.group_extended"/>
</page>
</notebook>
</form>
@@ -813,9 +811,9 @@
-->
<record id="view_procurement_form_inherit" model="ir.ui.view">
<field name="name">mrp.procurement.form.inherit</field>
<field name="model">mrp.procurement</field>
<field name="inherit_id" ref="mrp_procurement.mrp_procurement_form_view"/>
<field name="name">procurement.order.form.inherit</field>
<field name="model">procurement.order</field>
<field name="inherit_id" ref="procurement.procurement_form_view"/>
<field name="type">form</field>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page/field[@name='move_id']" position="before">
+4 -4
View File
@@ -117,7 +117,7 @@
<!-- Procurement -->
<record id="act_produce" model="workflow.activity">
<field name="wkf_id" ref="mrp_procurement.wkf_procurement"/>
<field name="wkf_id" ref="procurement.wkf_procurement"/>
<field name="name">produce</field>
<field name="kind">subflow</field>
<field name="subflow_id" search="[('osv','=','mrp.production')]"/>
@@ -125,20 +125,20 @@
</record>
<record id="trans_product_check_produce" model="workflow.transition">
<field name="act_from" ref="mrp_procurement.act_produce_check"/>
<field name="act_from" ref="procurement.act_produce_check"/>
<field name="act_to" ref="act_produce"/>
<field name="condition">check_product()</field>
</record>
<record id="trans_produce_cancel" model="workflow.transition">
<field name="act_from" ref="act_produce"/>
<field name="act_to" ref="mrp_procurement.act_cancel"/>
<field name="act_to" ref="procurement.act_cancel"/>
<field name="signal">subflow.cancel</field>
</record>
<record id="trans_produce_make_done" model="workflow.transition">
<field name="act_from" ref="act_produce"/>
<field name="act_to" ref="mrp_procurement.act_make_done"/>
<field name="act_to" ref="procurement.act_make_done"/>
<field name="signal">subflow.done</field>
</record>
+18 -18
View File
@@ -4,11 +4,11 @@
<record id="process_node_procureproducts0" model="process.node">
<field name="menu_id" ref="mrp.menu_mrp_procurement_action"/>
<field name="model_id" ref="mrp_procurement.model_mrp_procurement"/>
<field name="model_id" ref="procurement.model_procurement_order"/>
<field eval="&quot;&quot;&quot;state&quot;&quot;&quot;" name="kind"/>
<field eval="&quot;&quot;&quot;The way to procurement depends on the product type.&quot;&quot;&quot;" name="note"/>
<field eval="&quot;&quot;&quot;Procure Products&quot;&quot;&quot;" name="name"/>
<field name="process_id" ref="mrp_procurement.process_process_procurementprocess0"/>
<field name="process_id" ref="procurement.process_process_procurementprocess0"/>
<field eval="&quot;&quot;&quot;object.state in ('draft', 'confirmed', 'cancel', 'exception', 'running', 'done', 'waiting')&quot;&quot;&quot;" name="model_states"/>
<field eval="0" name="flow_start"/>
</record>
@@ -19,94 +19,94 @@
<field eval="&quot;&quot;&quot;state&quot;&quot;&quot;" name="kind"/>
<field eval="&quot;&quot;&quot;Drives the procurement orders for raw material.&quot;&quot;&quot;" name="note"/>
<field eval="&quot;&quot;&quot;Production Order&quot;&quot;&quot;" name="name"/>
<field name="process_id" ref="mrp_procurement.process_process_procurementprocess0"/>
<field name="process_id" ref="procurement.process_process_procurementprocess0"/>
<field eval="&quot;&quot;&quot;object.state in ('draft', 'picking_except', 'confirmed', 'ready', 'in_production', 'cancel', 'done')&quot;&quot;&quot;" name="model_states"/>
<field eval="1" name="flow_start"/>
</record>
<record id="process_node_procureproducts0" model="process.node">
<field name="menu_id" ref="mrp.menu_mrp_procurement_action"/>
<field name="model_id" ref="mrp.model_mrp_procurement"/>
<field name="model_id" ref="mrp.model_procurement_order"/>
<field eval="&quot;&quot;&quot;state&quot;&quot;&quot;" name="kind"/>
<field eval="&quot;&quot;&quot;The way to procurement depends on the product type.&quot;&quot;&quot;" name="note"/>
<field eval="&quot;&quot;&quot;Procure Products&quot;&quot;&quot;" name="name"/>
<field name="process_id" ref="mrp_procurement.process_process_procurementprocess0"/>
<field name="process_id" ref="procurement.process_process_procurementprocess0"/>
<field eval="&quot;&quot;&quot;object.state in ('draft', 'confirmed', 'cancel', 'exception', 'running', 'done', 'waiting')&quot;&quot;&quot;" name="model_states"/>
<field eval="0" name="flow_start"/>
</record>
<record id="process_node_minimumstockrule0" model="process.node">
<field name="menu_id" ref="mrp.menu_action_orderpoint_form"/>
<field name="model_id" ref="mrp_procurement.model_stock_warehouse_orderpoint"/>
<field name="model_id" ref="procurement.model_stock_warehouse_orderpoint"/>
<field eval="&quot;&quot;&quot;state&quot;&quot;&quot;" name="kind"/>
<field eval="&quot;&quot;&quot;Linked to the 'Minimum stock rule' supplying method.&quot;&quot;&quot;" name="note"/>
<field eval="&quot;&quot;&quot;Minimum Stock&quot;&quot;&quot;" name="name"/>
<field name="process_id" ref="mrp_procurement.process_process_procurementprocess0"/>
<field name="process_id" ref="procurement.process_process_procurementprocess0"/>
<field eval="1" name="flow_start"/>
</record>
<record id="process_node_stockproduct0" model="process.node">
<field name="menu_id" ref="mrp.menu_mrp_procurement_action"/>
<field name="model_id" ref="mrp.model_mrp_procurement"/>
<field name="model_id" ref="mrp.model_procurement_order"/>
<field eval="&quot;&quot;&quot;subflow&quot;&quot;&quot;" name="kind"/>
<field eval="&quot;&quot;&quot;Product type is Stockable or Consumable.&quot;&quot;&quot;" name="note"/>
<field eval="&quot;&quot;&quot;Stockable Product&quot;&quot;&quot;" name="name"/>
<field name="subflow_id" ref="process_process_stockableproductprocess0"/>
<field name="process_id" ref="mrp_procurement.process_process_procurementprocess0"/>
<field name="process_id" ref="procurement.process_process_procurementprocess0"/>
<field eval="&quot;&quot;&quot;object.state in ('draft', 'confirmed', 'cancel', 'exception', 'running', 'done', 'waiting')&quot;&quot;&quot;" name="model_states"/>
<field eval="0" name="flow_start"/>
</record>
<record id="process_node_stockproduct1" model="process.node">
<field name="menu_id" ref="mrp.menu_mrp_procurement_action"/>
<field name="model_id" ref="mrp.model_mrp_procurement"/>
<field name="model_id" ref="mrp.model_procurement_order"/>
<field eval="&quot;&quot;&quot;subflow&quot;&quot;&quot;" name="kind"/>
<field eval="&quot;&quot;&quot;For stockable products and consumables&quot;&quot;&quot;" name="note"/>
<field eval="&quot;&quot;&quot;Stockable Product&quot;&quot;&quot;" name="name"/>
<field name="process_id" ref="mrp.process_process_stockableproductprocess0"/>
<field name="subflow_id" ref="mrp_procurement.process_process_procurementprocess0"/>
<field name="subflow_id" ref="procurement.process_process_procurementprocess0"/>
<field eval="&quot;&quot;&quot;object.state in ('draft', 'confirmed', 'cancel', 'exception', 'running', 'done', 'waiting')&quot;&quot;&quot;" name="model_states"/>
<field eval="1" name="flow_start"/>
</record>
<record id="process_node_serviceproduct0" model="process.node">
<field name="menu_id" ref="mrp.menu_mrp_procurement_action"/>
<field name="model_id" ref="mrp.model_mrp_procurement"/>
<field name="model_id" ref="mrp.model_procurement_order"/>
<field eval="&quot;&quot;&quot;subflow&quot;&quot;&quot;" name="kind"/>
<field eval="&quot;&quot;&quot;Product type is service&quot;&quot;&quot;" name="note"/>
<field eval="&quot;&quot;&quot;Service&quot;&quot;&quot;" name="name"/>
<field name="subflow_id" ref="process_process_serviceproductprocess0"/>
<field name="process_id" ref="mrp_procurement.process_process_procurementprocess0"/>
<field name="process_id" ref="procurement.process_process_procurementprocess0"/>
<field eval="&quot;&quot;&quot;object.state in ('draft', 'confirmed', 'cancel', 'exception', 'running', 'done', 'waiting')&quot;&quot;&quot;" name="model_states"/>
<field eval="0" name="flow_start"/>
</record>
<record id="process_node_serviceproduct1" model="process.node">
<field name="menu_id" ref="mrp.menu_mrp_procurement_action"/>
<field name="model_id" ref="mrp.model_mrp_procurement"/>
<field name="model_id" ref="mrp.model_procurement_order"/>
<field eval="&quot;&quot;&quot;subflow&quot;&quot;&quot;" name="kind"/>
<field eval="&quot;&quot;&quot;For Services.&quot;&quot;&quot;" name="note"/>
<field eval="&quot;&quot;&quot;Service&quot;&quot;&quot;" name="name"/>
<field name="process_id" ref="mrp.process_process_serviceproductprocess0"/>
<field name="subflow_id" ref="mrp_procurement.process_process_procurementprocess0"/>
<field name="subflow_id" ref="procurement.process_process_procurementprocess0"/>
<field eval="&quot;&quot;&quot;object.state in ('draft', 'confirmed', 'cancel', 'exception', 'running', 'done', 'waiting')&quot;&quot;&quot;" name="model_states"/>
<field eval="1" name="flow_start"/>
</record>
<record id="process_node_purchaseprocure0" model="process.node">
<field name="menu_id" ref="mrp.menu_mrp_procurement_action"/>
<field name="model_id" ref="mrp.model_mrp_procurement"/>
<field name="model_id" ref="mrp.model_procurement_order"/>
<field eval="&quot;&quot;&quot;subflow&quot;&quot;&quot;" name="kind"/>
<field eval="&quot;&quot;&quot;Procurement Orders&quot;&quot;&quot;" name="name"/>
<field eval="&quot;&quot;&quot;For purchased material&quot;&quot;&quot;" name="note"/>
<field name="subflow_id" ref="mrp_procurement.process_process_procurementprocess0"/>
<field name="subflow_id" ref="procurement.process_process_procurementprocess0"/>
<field name="process_id" ref="purchase.process_process_purchaseprocess0"/>
<field eval="1" name="flow_start"/>
</record>
<record id="process_node_productminimumstockrule0" model="process.node">
<field name="menu_id" ref="mrp.menu_action_orderpoint_form"/>
<field name="model_id" ref="mrp_procurement.model_stock_warehouse_orderpoint"/>
<field name="model_id" ref="procurement.model_stock_warehouse_orderpoint"/>
<field eval="&quot;&quot;&quot;state&quot;&quot;&quot;" name="kind"/>
<field eval="&quot;&quot;&quot;Minimum Stock&quot;&quot;&quot;" name="name"/>
<field eval="&quot;&quot;&quot;Automatic procurement rule&quot;&quot;&quot;" name="note"/>
@@ -8,7 +8,7 @@
<record id="process_process_serviceproductprocess0" model="process.process">
<field eval="&quot;&quot;&quot;Service&quot;&quot;&quot;" name="name"/>
<field name="model_id" ref="mrp.model_mrp_procurement"/>
<field name="model_id" ref="mrp.model_procurement_order"/>
<field eval="1" name="active"/>
</record>
@@ -18,7 +18,7 @@
<record id="process_node_serviceonorder0" model="process.node">
<field name="menu_id" ref="mrp.menu_mrp_procurement_action"/>
<field name="model_id" ref="mrp.model_mrp_procurement"/>
<field name="model_id" ref="mrp.model_procurement_order"/>
<field eval="&quot;&quot;&quot;state&quot;&quot;&quot;" name="kind"/>
<field eval="&quot;&quot;&quot;Assignment from Production or Purchase Order.&quot;&quot;&quot;" name="note"/>
<field eval="&quot;&quot;&quot;Make to Order&quot;&quot;&quot;" name="name"/>
@@ -29,7 +29,7 @@
<record id="process_node_servicemts0" model="process.node">
<field name="menu_id" ref="mrp.menu_mrp_procurement_action"/>
<field name="model_id" ref="mrp.model_mrp_procurement"/>
<field name="model_id" ref="mrp.model_procurement_order"/>
<field eval="&quot;&quot;&quot;state&quot;&quot;&quot;" name="kind"/>
<field eval="&quot;&quot;&quot;Assignment from stock.&quot;&quot;&quot;" name="note"/>
<field eval="&quot;&quot;&quot;Make to stock&quot;&quot;&quot;" name="name"/>
@@ -8,7 +8,7 @@
<record id="process_process_stockableproductprocess0" model="process.process">
<field eval="&quot;&quot;&quot;Stockable Product&quot;&quot;&quot;" name="name"/>
<field name="model_id" ref="mrp.model_mrp_procurement"/>
<field name="model_id" ref="mrp.model_procurement_order"/>
<field eval="1" name="active"/>
</record>
@@ -18,7 +18,7 @@
<record id="process_node_mts0" model="process.node">
<field name="menu_id" ref="mrp.menu_mrp_procurement_action"/>
<field name="model_id" ref="mrp.model_mrp_procurement"/>
<field name="model_id" ref="mrp.model_procurement_order"/>
<field eval="&quot;&quot;&quot;state&quot;&quot;&quot;" name="kind"/>
<field eval="&quot;&quot;&quot;Assignment from stock.&quot;&quot;&quot;" name="note"/>
<field eval="&quot;&quot;&quot;Make to Stock&quot;&quot;&quot;" name="name"/>
@@ -29,7 +29,7 @@
<record id="process_node_stock0" model="process.node">
<field name="menu_id" ref="mrp.menu_mrp_procurement_action"/>
<field name="model_id" ref="mrp.model_mrp_procurement"/>
<field name="model_id" ref="mrp.model_procurement_order"/>
<field eval="&quot;&quot;&quot;state&quot;&quot;&quot;" name="kind"/>
<field eval="&quot;&quot;&quot;Assignment from Production or Purchase Order.&quot;&quot;&quot;" name="note"/>
<field eval="&quot;&quot;&quot;Make to Order&quot;&quot;&quot;" name="name"/>
@@ -27,17 +27,20 @@ import ir
import netsvc
import time
class mrp_procurement(osv.osv):
_inherit = 'mrp.procurement'
class procurement_order(osv.osv):
_inherit = 'procurement.order'
_columns = {
'bom_id': fields.many2one('mrp.bom', 'BoM', ondelete='cascade', select=True),
}
def check_produce_product(self, cr, uid, procurement, context=[]):
""" Finds the bill of material for the product from procurement order.
@return: True or False
"""
properties = [x.id for x in procurement.property_ids]
bom_id = self.pool.get('mrp.bom')._bom_find(cr, uid, procurement.product_id.id, procurement.product_uom.id, properties)
if not bom_id:
cr.execute('update mrp_procurement set message=%s where id=%s', (_('No BoM defined for this product !'), procurement.id))
cr.execute('update procurement_order set message=%s where id=%s', (_('No BoM defined for this product !'), procurement.id))
return False
return True
@@ -45,7 +48,7 @@ class mrp_procurement(osv.osv):
""" This is action which call from workflow to assign production order to procurements
@return: True
"""
procurement_obj = self.pool.get('mrp.procurement')
procurement_obj = self.pool.get('procurement.order')
res = procurement_obj.make_mo(cr, uid, ids, context=context)
res = res.values()
return len(res) and res[0] or 0 #TO CHECK: why workflow is generated error if return not integer value
@@ -59,7 +62,7 @@ class mrp_procurement(osv.osv):
production_obj = self.pool.get('mrp.production')
move_obj = self.pool.get('stock.move')
wf_service = netsvc.LocalService("workflow")
procurement_obj = self.pool.get('mrp.procurement')
procurement_obj = self.pool.get('procurement.order')
for procurement in procurement_obj.browse(cr, uid, ids):
res_id = procurement.move_id.id
loc_id = procurement.location_id.id
@@ -88,6 +91,6 @@ class mrp_procurement(osv.osv):
{'location_id': procurement.location_id.id})
return res
mrp_procurement()
procurement_order()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+2 -2
View File
@@ -7,7 +7,7 @@
"access_mrp_production","mrp.production","model_mrp_production","mrp.group_mrp_user",1,1,1,1
"access_mrp_production_workcenter_line","mrp.production.workcenter.line","model_mrp_production_workcenter_line","mrp.group_mrp_user",1,1,1,1
"access_mrp_production_product_line","mrp.production.product.line","model_mrp_production_product_line","mrp.group_mrp_user",1,1,1,1
"access_mrp_procurement","mrp.procurement","model_mrp_procurement","mrp.group_mrp_user",1,1,1,1
"access_procurement","procurement.order","model_procurement_order","mrp.group_mrp_user",1,1,1,1
"access_mrp_workcenter_manager","mrp.workcenter.manager","model_mrp_workcenter","mrp.group_mrp_user",1,1,1,1
"access_mrp_routing_manager","mrp.routing.manager","model_mrp_routing","mrp.group_mrp_manager",1,1,1,1
"access_mrp_routing_workcenter_manager","mrp.routing.workcenter.manager","model_mrp_routing_workcenter","mrp.group_mrp_manager",1,1,1,1
@@ -22,7 +22,7 @@
"access_purchase_order_mrp_worker","purchase.order mrp_worker","purchase.model_purchase_order","mrp.group_mrp_user",1,0,0,0
"access_purchase_order_line_mrp_worker","purchase.order.line mrp_worker","purchase.model_purchase_order_line","mrp.group_mrp_user",1,0,0,0
"access_hr_timesheet_group_mrp_worker","resource.calendar mrp_worker","resource.model_resource_calendar","mrp.group_mrp_user",1,0,0,0
"access_mrp_procurement_stock_worker","mrp.procurement stock_worker","model_mrp_procurement","stock.group_stock_user",1,1,1,1
"access_procurement_stock_worker","procurement.order stock_worker","model_procurement_order","stock.group_stock_user",1,1,1,1
"access_mrp_production_stock_worker","mrp.production stock_worker","model_mrp_production","stock.group_stock_user",1,0,0,0
"access_mrp_installer","mrp.installer","model_mrp_installer","mrp.group_mrp_user",1,0,0,0
"access_mrp_product_produce","mrp.product.produce","model_mrp_product_produce","mrp.group_mrp_user",1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
7 access_mrp_production mrp.production model_mrp_production mrp.group_mrp_user 1 1 1 1
8 access_mrp_production_workcenter_line mrp.production.workcenter.line model_mrp_production_workcenter_line mrp.group_mrp_user 1 1 1 1
9 access_mrp_production_product_line mrp.production.product.line model_mrp_production_product_line mrp.group_mrp_user 1 1 1 1
10 access_mrp_procurement access_procurement mrp.procurement procurement.order model_mrp_procurement model_procurement_order mrp.group_mrp_user 1 1 1 1
11 access_mrp_workcenter_manager mrp.workcenter.manager model_mrp_workcenter mrp.group_mrp_user 1 1 1 1
12 access_mrp_routing_manager mrp.routing.manager model_mrp_routing mrp.group_mrp_manager 1 1 1 1
13 access_mrp_routing_workcenter_manager mrp.routing.workcenter.manager model_mrp_routing_workcenter mrp.group_mrp_manager 1 1 1 1
22 access_purchase_order_mrp_worker purchase.order mrp_worker purchase.model_purchase_order mrp.group_mrp_user 1 0 0 0
23 access_purchase_order_line_mrp_worker purchase.order.line mrp_worker purchase.model_purchase_order_line mrp.group_mrp_user 1 0 0 0
24 access_hr_timesheet_group_mrp_worker resource.calendar mrp_worker resource.model_resource_calendar mrp.group_mrp_user 1 0 0 0
25 access_mrp_procurement_stock_worker access_procurement_stock_worker mrp.procurement stock_worker procurement.order stock_worker model_mrp_procurement model_procurement_order stock.group_stock_user 1 1 1 1
26 access_mrp_production_stock_worker mrp.production stock_worker model_mrp_production stock.group_stock_user 1 0 0 0
27 access_mrp_installer mrp.installer model_mrp_installer mrp.group_mrp_user 1 0 0 0
28 access_mrp_product_produce mrp.product.produce model_mrp_product_produce mrp.group_mrp_user 1 0 0 0
+5 -75
View File
@@ -28,82 +28,12 @@ import netsvc
import time
class stock_warehouse_orderpoint(osv.osv):
"""
Defines Minimum stock rules.
"""
_name = "stock.warehouse.orderpoint"
_description = "Minimum Inventory Rule"
_columns = {
'name': fields.char('Name', size=32, required=True),
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the orderpoint without removing it."),
'logic': fields.selection([('max','Order to Max'),('price','Best price (not yet active!)')], 'Reordering Mode', required=True),
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', required=True, ondelete="cascade"),
'location_id': fields.many2one('stock.location', 'Location', required=True, ondelete="cascade"),
'product_id': fields.many2one('product.product', 'Product', required=True, ondelete='cascade', domain=[('type','=','product')]),
'product_uom': fields.many2one('product.uom', 'Product UOM', required=True),
'product_min_qty': fields.float('Min Quantity', required=True,
help="When the virtual stock goes belong the Min Quantity, Open ERP generates "\
"a procurement to bring the virtual stock to the Max Quantity."),
'product_max_qty': fields.float('Max Quantity', required=True,
help="When the virtual stock goes belong the Min Quantity, Open ERP generates "\
"a procurement to bring the virtual stock to the Max Quantity."),
'qty_multiple': fields.integer('Qty Multiple', required=True,
help="The procurement quantity will by rounded up to this multiple."),
'procurement_id': fields.many2one('mrp.procurement', 'Latest procurement', ondelete="set null"),
'company_id': fields.many2one('res.company','Company',required=True),
}
_defaults = {
'active': lambda *a: 1,
'logic': lambda *a: 'max',
'qty_multiple': lambda *a: 1,
'name': lambda x,y,z,c: x.pool.get('ir.sequence').get(y,z,'mrp.warehouse.orderpoint') or '',
'product_uom': lambda sel, cr, uid, context: context.get('product_uom', False),
'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.warehouse.orderpoint', context=c)
}
_sql_constraints = [
('qty_multiple_check', 'CHECK( qty_multiple > 0 )', _('Qty Multiple must be greater than zero.')),
]
def onchange_warehouse_id(self, cr, uid, ids, warehouse_id, context={}):
""" Finds location id for changed warehouse.
@param warehouse_id: Changed id of warehouse.
@return: Dictionary of values.
"""
if warehouse_id:
w = self.pool.get('stock.warehouse').browse(cr, uid, warehouse_id, context)
v = {'location_id': w.lot_stock_id.id}
return {'value': v}
return {}
def onchange_product_id(self, cr, uid, ids, product_id, context={}):
""" Finds UoM for changed product.
@param product_id: Changed id of product.
@return: Dictionary of values.
"""
if product_id:
prod = self.pool.get('product.product').browse(cr,uid,product_id)
v = {'product_uom': prod.uom_id.id}
return {'value': v}
return {}
def copy(self, cr, uid, id, default=None,context={}):
if not default:
default = {}
default.update({
'name': self.pool.get('ir.sequence').get(cr, uid, 'mrp.warehouse.orderpoint') or '',
})
return super(stock_warehouse_orderpoint, self).copy(cr, uid, id, default, context)
stock_warehouse_orderpoint()
class StockMove(osv.osv):
_inherit = 'stock.move'
_columns = {
'production_id': fields.many2one('mrp.production', 'Production', select=True),
'procurements': fields.one2many('mrp.procurement', 'move_id', 'Procurements'),
'procurements': fields.one2many('procurement.order', 'move_id', 'Procurements'),
}
def copy(self, cr, uid, id, default=None, context=None):
@@ -118,7 +48,7 @@ class StockMove(osv.osv):
"""
bom_obj = self.pool.get('mrp.bom')
move_obj = self.pool.get('stock.move')
procurement_obj = self.pool.get('mrp.procurement')
procurement_obj = self.pool.get('procurement.order')
product_obj = self.pool.get('product.product')
wf_service = netsvc.LocalService("workflow")
if move.product_id.supply_method == 'produce' and move.product_id.procure_method == 'make_to_order':
@@ -166,7 +96,7 @@ class StockMove(osv.osv):
'move_id': mid,
'company_id': line['company_id'],
})
wf_service.trg_validate(uid, 'mrp.procurement', proc_id, 'button_confirm', cr)
wf_service.trg_validate(uid, 'procurement.order', proc_id, 'button_confirm', cr)
move_obj.write(cr, uid, [move.id], {
'location_id': move.location_dest_id.id,
'auto_validate': True,
@@ -175,7 +105,7 @@ class StockMove(osv.osv):
'state': 'waiting'
})
for m in procurement_obj.search(cr, uid, [('move_id','=',move.id)], context):
wf_service.trg_validate(uid, 'mrp.procurement', m, 'button_wait_done', cr)
wf_service.trg_validate(uid, 'procurement.order', m, 'button_wait_done', cr)
return True
def action_consume(self, cr, uid, ids, product_qty, location_id=False, context=None):
@@ -231,7 +161,7 @@ class StockPicking(osv.osv):
for move in picking.move_lines:
if move.state == 'done' and move.procurements:
for procurement in move.procurements:
wf_service.trg_validate(user, 'mrp.procurement',
wf_service.trg_validate(user, 'procurement.order',
procurement.id, 'button_check', cursor)
return res
+23 -7
View File
@@ -9,6 +9,8 @@
factor: 1.0
name: Litre
rounding: 0.01
-
I create record for product Orange Juice.
-
!record {model: product.product, id: product_product_orangejuice0}:
categ_id: product.cat1
@@ -18,6 +20,8 @@
type: product
uom_id: product_uom_litre0
uom_po_id: product_uom_litre0
-
I create record for product Orange.
-
!record {model: product.product, id: product_product_orange0}:
categ_id: product.cat1
@@ -31,6 +35,8 @@
type: product
uom_id: product.product_uom_kgm
uom_po_id: product.product_uom_kgm
-
I create record for product Sugar.
-
!record {model: product.product, id: product_product_sugar0}:
categ_id: product.cat1
@@ -44,6 +50,8 @@
type: product
uom_id: product.product_uom_kgm
uom_po_id: product.product_uom_kgm
-
I create record for product Water.
-
!record {model: product.product, id: product_product_water0}:
categ_id: product.cat1
@@ -54,7 +62,7 @@
uom_id: product_uom_litre0
uom_po_id: product_uom_litre0
-
I define the BoM to produce an orange juice
I define the BoM to produce an orange juice.
-
!record {model: mrp.bom, id: mrp_bom_orangejuice0}:
company_id: base.main_company
@@ -64,6 +72,8 @@
product_qty: 1.0
product_uom: product_uom_litre0
type: phantom
-
I create bom lines for BoM for Orange Juice.
-
!record {model: mrp.bom, id: mrp_bom_orangejuice0}:
bom_lines:
@@ -92,7 +102,7 @@
product_uom: product_uom_litre0
type: normal
-
I define Minimum stock rules for my stockable products orange and sugar
I define Minimum stock rules for my stockable product "Orange".
-
!record {model: stock.warehouse.orderpoint, id: stock_warehouse_orderpoint_op0}:
company_id: base.main_company
@@ -105,6 +115,8 @@
product_uom: product.product_uom_kgm
qty_multiple: 1
warehouse_id: stock.warehouse0
-
I define Minimum stock rules for my stockable product "Sugar".
-
!record {model: stock.warehouse.orderpoint, id: stock_warehouse_orderpoint_op1}:
company_id: base.main_company
@@ -168,23 +180,23 @@
-
I am checking Procurement orders. There are 3 orders generated for Oranges, Sugar and Water.
-
!python {model: mrp.procurement}: |
!python {model: procurement.order}: |
from tools.translate import _
proc_ids = self.search(cr, uid, [('state','!=','cofirmed')])
assert proc_ids, _('No Procurements!')
-
The scheduler runs.
-
!function {model: mrp.procurement, name: run_scheduler}:
- model: mrp.procurement
search: "[('origin','=',':MO/00002')]"
!function {model: procurement.order, name: run_scheduler}:
- model: procurement.order
search: "[('state','!=','cofirmed')]"
-
I am checking Internal picking. I see one picking for Orange juice and its
stock moves for Oranges, Sugar and Water made correctly.
-
!python {model: stock.picking}: |
from tools.translate import _
pick_ids = self.search(cr, uid, [('origin','=',':MO/00002'),('type','=','internal')])
pick_ids = self.search(cr, uid, [('type','=','internal')])
assert pick_ids, _('No Internal Pickings!')
-
According to minimum stock rules. I have 2 purchase orders for
@@ -220,11 +232,15 @@
assert pick_ids, _('No Incoming Shipments found!')
-
I receive both the products. My incoming pickings are done.
-
I create record for the incoming picking wizard.
-
!record {model: stock.partial.picking, id: stock_partial_picking0}:
date: '2010-04-30 16:53:36'
partner_id: base.res_partner_asus
address_id: base.res_partner_address_tang
-
I make my pickings done.
-
!python {model: stock.partial.picking}: |
pick_obj = self.pool.get('stock.picking')
+29 -13
View File
@@ -4,7 +4,7 @@
-
I am creating products.
-
Creating a product.product record
I create record for product Shirt.
-
!record {model: product.product, id: product_product_shirt0}:
categ_id: product.cat1
@@ -27,7 +27,7 @@
weight: 0.0
weight_net: 0.0
-
Creating a product.product record
I create record for product Cloth.
-
!record {model: product.product, id: product_product_cloth0}:
categ_id: product.cat1
@@ -53,7 +53,7 @@
weight: 0.0
weight_net: 0.0
-
Creating a product.product record
I create record for product Buttons.
-
!record {model: product.product, id: product_product_buttons0}:
categ_id: product.cat1
@@ -81,7 +81,7 @@
-
I am creating bills of material for 'Shirt'.
-
Creating a mrp.bom record
I create bills of material for Shirt.
-
!record {model: mrp.bom, id: mrp_bom_shirt0}:
bom_lines:
@@ -129,7 +129,7 @@
-
I create a procurement order for product Shirt.
-
!record {model: mrp.procurement, id: mrp_procurement_shirt0}:
!record {model: procurement.order, id: procurement_order_shirt0}:
name: 'PROC: Shirt'
product_id: product_product_shirt0
product_qty: 5.00
@@ -138,11 +138,11 @@
-
I confirm the procurement order.
-
!workflow {model: mrp.procurement, action: button_confirm, ref: mrp_procurement_shirt0}
!workflow {model: procurement.order, action: button_confirm, ref: procurement_order_shirt0}
-
I run the procurement.
-
!workflow {model: mrp.procurement, action: button_check, ref: mrp_procurement_shirt0}
!workflow {model: procurement.order, action: button_check, ref: procurement_order_shirt0}
-
I see that there is a manufacturing order for Shirt.
-
@@ -153,15 +153,15 @@
-
I also check that there are two more procurement orders for sub products Cloth and Buttons.
-
!python {model: mrp.procurement}: |
!python {model: procurement.order}: |
from tools.translate import _
proc_ids = self.search(cr, uid, [('product_id','in',[ref('product_product_cloth0'),ref('product_product_buttons0')])])
assert proc_ids, 'No Procurements.'
-
The scheduler runs.
-
!function {model: mrp.procurement, name: run_scheduler}:
- model: mrp.procurement
!function {model: procurement.order, name: run_scheduler}:
- model: procurement.order
search: "[]"
-
I check that there is one purchase order for Cloth.
@@ -216,11 +216,15 @@
from tools.translate import _
pick_ids = self.search(cr, uid, [('address_id.name','=','Wong'),('state','=','assigned')])
assert pick_ids, _('No Incoming Shipments found!')
-
I create record for partial picking.
-
!record {model: stock.partial.picking, id: stock_partial_picking0}:
date: '2010-04-30 16:53:36'
partner_id: base.res_partner_maxtor
address_id: base.res_partner_address_wong
-
I make my picking done.
-
!python {model: stock.partial.picking}: |
pick_obj = self.pool.get('stock.picking')
@@ -245,17 +249,21 @@
})
pick_obj.do_partial(cr, uid, picking_ids, partial_datas, context=context)
-
I Check incoming shipments for buttons. And receive products.
I Check incoming shipments for buttons and receive products.
-
!python {model: stock.picking}: |
from tools.translate import _
pick_ids = self.search(cr, uid, [('address_id.name','=','Tang'),('state','=','assigned')])
assert pick_ids, _('No Incoming Shipments found!')
-
I create record for partial picking.
-
!record {model: stock.partial.picking, id: stock_partial_picking0}:
date: '2010-04-30 16:53:36'
partner_id: base.res_partner_maxtor
address_id: base.res_partner_address_wong
-
I make my picking done.
-
!python {model: stock.partial.picking}: |
pick_obj = self.pool.get('stock.picking')
@@ -282,8 +290,8 @@
-
Run scheduler again.
-
!function {model: mrp.procurement, name: run_scheduler}:
- model: mrp.procurement
!function {model: procurement.order, name: run_scheduler}:
- model: procurement.order
search: "[]"
-
Check state of manufacturing order for Shirt.
@@ -303,22 +311,30 @@
wf_service = netsvc.LocalService("workflow")
for p_id in prod_ids:
wf_service.trg_validate(uid, 'mrp.production', p_id, 'button_produce', cr)
-
I create record for producing products with quantity 5.00.
-
!record {model: mrp.product.produce, id: mrp_product_produce0}:
product_qty: 5.00
mode: 'consume_produce'
-
I produce 2 products with 5.00 quantities each.
-
!python {model: mrp.product.produce}: |
from tools.translate import _
prod_obj = self.pool.get('mrp.production')
prod_ids = prod_obj.search(cr, uid, [('product_id.name','=','Shirt')])
self.do_produce(cr, uid, [1], context={'active_ids': prod_ids})
-
I create record for remaining products with quantity 35.00.
-
!record {model: stock.move.consume, id: stock_move_consume0}:
product_id: product_product_buttons0
product_qty: 35.00
product_uom: product.product_uom_unit
location_id: stock.stock_location_stock
-
I produce remaining product Buttons with 35.00 quantity.
-
!python {model: stock.move.consume}: |
from tools.translate import _
+17 -11
View File
@@ -18,7 +18,7 @@
product_uom: product.product_uom_unit
product_uos_qty: 0.0
-
Creating a mrp.production.workcenter.line record
I create a record for Workcenter line.
-
!record {model: mrp.production.workcenter.line, id: mrp_production_workcenter_line_assemblyline0}:
cycle: 5.0
@@ -28,7 +28,7 @@
sequence: 0.0
workcenter_id: mrp.mrp_workcenter_0
-
Creating a mrp.production.product.line record
I create second record for Workcenter line.
-
!record {model: mrp.production.product.line, id: mrp_production_product_line_regularprocessorconfig0}:
name: Regular processor config
@@ -38,7 +38,7 @@
product_uos_qty: 0.0
production_id: mrp_production_mo0
-
Creating a mrp.production.product.line record
I create third record for Workcenter line.
-
!record {model: mrp.production.product.line, id: mrp_production_product_line_hddseagategb0}:
name: HDD Seagate 7200.8 80GB
@@ -48,7 +48,7 @@
product_uos_qty: 0.0
production_id: mrp_production_mo0
-
Creating a mrp.production.product.line record
I create fourth record for Workcenter line.
-
!record {model: mrp.production.product.line, id: mrp_production_product_line_atxmidsizetower0}:
name: ATX Mid-size Tower
@@ -58,7 +58,7 @@
product_uos_qty: 0.0
production_id: mrp_production_mo0
-
Creating a mrp.production.product.line record
I create a record for production line.
-
!record {model: mrp.production.product.line, id: mrp_production_product_line_mouse0}:
name: Mouse
@@ -68,7 +68,7 @@
product_uos_qty: 0.0
production_id: mrp_production_mo0
-
Creating a mrp.production.product.line record
I create second record for production line.
-
!record {model: mrp.production.product.line, id: mrp_production_product_line_keyboard0}:
name: Keyboard
@@ -84,15 +84,15 @@
-
I am checking Procurement orders.
-
!python {model: mrp.procurement}: |
!python {model: procurement.order}: |
from tools.translate import _
proc_ids = self.search(cr, uid, [('state','!=','confirmed')])
assert proc_ids, _('No Procurements!')
-
The scheduler runs.
-
!function {model: mrp.procurement, name: run_scheduler}:
- model: mrp.procurement
!function {model: procurement.order, name: run_scheduler}:
- model: procurement.order
search: "[('state','=','confirmed')]"
-
I am checking Internal picking.
@@ -102,7 +102,7 @@
pick_ids = self.search(cr, uid, [('state','!=','done'),('type','=','internal')])
assert pick_ids, _('No Internal Pickings!')
-
I see that there is a manufacturing order for the subproduct of PC1 with ready state.
I see that there is a manufacturing order for the sub product of PC1 with ready state.
-
!python {model: mrp.production}: |
from tools.translate import _
@@ -110,17 +110,21 @@
assert order_ids, _('No manufacturing order!')
-
I start producing that product first. So I marked it as started.
-
I create record for producing products with quantity 5.00.
-
!record {model: mrp.product.produce, id: mrp_product_produce0}:
product_qty: 5.00
mode: 'consume_produce'
-
I produce the product.
-
!python {model: mrp.product.produce}: |
prod_obj = self.pool.get('mrp.production')
prod_ids = prod_obj.search(cr, uid, [('state','=','confirmed')])
self.do_produce(cr, uid, [1], context={'active_ids': prod_ids})
-
Now the manufacturing order for subproduct CPU_GEN is done. And manufacturing
Now the manufacturing order for subproduct CPU_GEN is done and manufacturing
order for PC1 is in ready state.
-
!python {model: mrp.production}: |
@@ -131,6 +135,8 @@
I start producing the product PC1.
-
!workflow {model: mrp.production, action: button_produce, ref: mrp_production_mo0}
-
Finally my production order is done.
-
!python {model: mrp.product.produce}: |
from tools.translate import _
+1 -1
View File
@@ -40,7 +40,7 @@
""",
'author': 'Tiny',
'depends': ['mrp_procurement'],
'depends': ['procurement'],
'update_xml': ['mrp_jit.xml'],
'demo_xml': [],
'installable': True,
+1 -1
View File
@@ -2,7 +2,7 @@
<openerp>
<data>
<record model="workflow.transition" id="mrp_procurement.trans_confirm_confirm_wait">
<record model="workflow.transition" id="procurement.trans_confirm_confirm_wait">
<field name="signal" eval="False"/>
</record>
+1
View File
@@ -61,6 +61,7 @@
'process/mrp_operation_process.xml'
],
'demo_xml': ['mrp_operation_data.xml'],
'test': ['test/mrp_operations.yml'],
'installable': True,
'active': False,
'certificate': '0056233813133',
+100 -33
View File
@@ -47,6 +47,9 @@ stock_move()
class mrp_production_workcenter_line(osv.osv):
def _get_date_date(self, cr, uid, ids, field_name, arg, context):
""" Finds starting date.
@return: Dictionary of values.
"""
res={}
for op in self.browse(cr, uid, ids, context=context):
if op.date_start:
@@ -54,7 +57,11 @@ class mrp_production_workcenter_line(osv.osv):
else:
res[op.id]=False
return res
def _get_date_end(self, cr, uid, ids, field_name, arg, context):
""" Finds ending date.
@return: Dictionary of values.
"""
res = {}
for op in self.browse(cr, uid, ids, context=context):
res[op.id]= False
@@ -66,8 +73,10 @@ class mrp_production_workcenter_line(osv.osv):
else:
res[op.id] = op.date_planned
return res
_inherit = 'mrp.production.workcenter.line'
_order = "sequence, date_planned"
_columns = {
'state': fields.selection([('draft','Draft'),('startworking', 'In Progress'),('pause','Pause'),('cancel','Canceled'),('done','Finished')],'State', readonly=True,
help="* When a work order is created it is set in 'Draft' state.\n" \
@@ -90,16 +99,21 @@ class mrp_production_workcenter_line(osv.osv):
'qty':fields.related('production_id','product_qty',type='float',string='Qty',readonly=True),
'uom':fields.related('production_id','product_uom',type='many2one',relation='product.uom',string='UOM',readonly=True),
}
_defaults = {
'state': lambda *a: 'draft',
'delay': lambda *a: 0.0
}
def modify_production_order_state(self,cr,uid,ids,action):
def modify_production_order_state(self, cr, uid, ids, action):
""" Modifies production order state if work order state is changed.
@param action: Action to perform.
@return: Nothing
"""
wf_service = netsvc.LocalService("workflow")
oper_obj=self.browse(cr,uid,ids)[0]
prod_obj=oper_obj.production_id
if action=='start':
oper_obj = self.browse(cr, uid, ids)[0]
prod_obj = oper_obj.production_id
if action == 'start':
if prod_obj.state =='confirmed':
self.pool.get('mrp.production').force_production(cr, uid, [prod_obj.id])
wf_service.trg_validate(uid, 'mrp.production', prod_obj.id, 'button_produce', cr)
@@ -110,12 +124,12 @@ class mrp_production_workcenter_line(osv.osv):
else:
raise osv.except_osv(_('Error!'),_('Production Order Cannot start in [%s] state') % (prod_obj.state,))
else:
oper_ids=self.search(cr,uid,[('production_id','=',prod_obj.id)])
obj=self.browse(cr,uid,oper_ids)
flag=True
oper_ids = self.search(cr,uid,[('production_id','=',prod_obj.id)])
obj = self.browse(cr,uid,oper_ids)
flag = True
for line in obj:
if line.state!='done':
flag=False
if line.state != 'done':
flag = False
if flag:
wf_service.trg_validate(uid, 'mrp.production', oper_obj.production_id.id, 'button_produce_done', cr)
return
@@ -132,15 +146,24 @@ class mrp_production_workcenter_line(osv.osv):
return result
def action_draft(self, cr, uid, ids):
""" Sets state to draft.
@return: True
"""
self.write(cr, uid, ids, {'state':'draft'})
return True
def action_start_working(self, cr, uid, ids):
self.modify_production_order_state(cr,uid,ids,'start')
""" 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')})
return True
def action_done(self, cr, uid, ids):
""" Sets state to done, writes finish date and calculates delay.
@return: True
"""
delay = 0.0
date_now = time.strftime('%Y-%m-%d %H:%M:%S')
obj_line = self.browse(cr, uid, ids[0])
@@ -155,14 +178,23 @@ class mrp_production_workcenter_line(osv.osv):
return True
def action_cancel(self, cr, uid, ids):
""" Sets state to cancel.
@return: True
"""
self.write(cr, uid, ids, {'state':'cancel'})
return True
def action_pause(self, cr, uid, ids):
""" Sets state to pause.
@return: True
"""
self.write(cr, uid, ids, {'state':'pause'})
return True
def action_resume(self, cr, uid, ids):
""" Sets state to startworking.
@return: True
"""
self.write(cr, uid, ids, {'state':'startworking'})
return True
@@ -175,6 +207,9 @@ class mrp_production(osv.osv):
}
def _production_date_end(self, cr, uid, ids, prop, unknow_none, context={}):
""" Calculates planned end date of production order.
@return: Dictionary of values
"""
result = {}
for prod in self.browse(cr, uid, ids, context=context):
result[prod.id] = prod.date_planned
@@ -183,10 +218,13 @@ class mrp_production(osv.osv):
return result
def action_production_end(self, cr, uid, ids):
obj=self.browse(cr,uid,ids)[0]
""" Finishes work order if production order is done.
@return: Super method
"""
obj = self.browse(cr, uid, ids)[0]
for workcenter_line in obj.workcenter_lines:
tmp = self.pool.get('mrp.production.workcenter.line').action_done(cr,uid,[workcenter_line.id])
return super(mrp_production,self).action_production_end(cr,uid,ids)
tmp = self.pool.get('mrp.production.workcenter.line').action_done(cr, uid, [workcenter_line.id])
return super(mrp_production,self).action_production_end(cr, uid, ids)
def action_in_production(self, cr, uid, ids):
""" Changes state to In Production and writes starting date.
@@ -199,12 +237,18 @@ class mrp_production(osv.osv):
return super(mrp_production,self).action_in_production(cr, uid, ids)
def action_cancel(self, cr, uid, ids):
obj=self.browse(cr,uid,ids)[0]
""" Cancels work order if production order is canceled.
@return: Super method
"""
obj = self.browse(cr, uid, ids)[0]
for workcenter_line in obj.workcenter_lines:
tmp=self.pool.get('mrp.production.workcenter.line').action_cancel(cr,uid,[workcenter_line.id])
tmp = self.pool.get('mrp.production.workcenter.line').action_cancel(cr, uid, [workcenter_line.id])
return super(mrp_production,self).action_cancel(cr,uid,ids)
def _compute_planned_workcenter(self, cr, uid, ids, context={}, mini=False):
""" Computes planned and finished dates for work order.
@return: Calculated date
"""
dt_end = DateTime.now()
for po in self.browse(cr, uid, ids, context=context):
dt_end = DateTime.strptime(po.date_start or po.date_planned, '%Y-%m-%d %H:%M:%S')
@@ -241,6 +285,9 @@ class mrp_production(osv.osv):
return dt_end
def _move_pass(self, cr, uid, ids, context={}):
""" Calculates start date for stock moves finding interval from resource calendar.
@return: True
"""
for po in self.browse(cr, uid, ids, context):
if po.allow_reorder:
continue
@@ -251,7 +298,7 @@ class mrp_production(osv.osv):
if l.state in ('done','cancel','draft'):
continue
todo += l.move_dest_id_lines
if l.production_id and (l.production_id.date_finnished>dt):
if l.production_id and (l.production_id.date_finnished > dt):
if l.production_id.state not in ('done','cancel'):
for wc in l.production_id.workcenter_lines:
i = self.pool.get('resource.calendar').interval_min_get(
@@ -261,11 +308,14 @@ class mrp_production(osv.osv):
dt, wc.hour or 0.0
)
dt = i[0][0]
if l.production_id.date_start>dt.strftime('%Y-%m-%d %H:%M:%S'):
if l.production_id.date_start > dt.strftime('%Y-%m-%d %H:%M:%S'):
self.write(cr, uid, [l.production_id.id], {'date_start':dt.strftime('%Y-%m-%d %H:%M:%S')}, mini=True)
return True
def _move_futur(self, cr, uid, ids, context={}):
""" Calculates start date for stock moves.
@return: True
"""
for po in self.browse(cr, uid, ids, context):
if po.allow_reorder:
continue
@@ -277,8 +327,8 @@ class mrp_production(osv.osv):
break
if l.production_id.state in ('done','cancel'):
break
if l.production_id and (l.production_id.date_start<po.date_finnished):
self.write(cr, uid, [l.production_id.id], {'date_start':po.date_finnished})
if l.production_id and (l.production_id.date_start < po.date_finnished):
self.write(cr, uid, [l.production_id.id], {'date_start': po.date_finnished})
break
@@ -291,17 +341,21 @@ class mrp_production(osv.osv):
if (vals.get('workcenter_lines', False) or vals.get('date_start', False)) and update:
self._compute_planned_workcenter(cr, uid, ids, context=context, mini=mini)
for d in direction:
if direction[d]==1:
if direction[d] == 1:
# the production order has been moved to the passed
self._move_pass(cr, uid, [d], context=context)
pass
elif direction[d]==-1:
elif direction[d] == -1:
self._move_futur(cr, uid, [d], context=context)
# the production order has been moved to the future
pass
return result
def action_compute(self, cr, uid, ids, properties=[]):
""" Computes bills of material of a product and planned date of work order.
@param properties: List containing dictionaries of properties.
@return: No. of products.
"""
result = super(mrp_production, self).action_compute(cr, uid, ids, properties=properties)
self._compute_planned_workcenter(cr, uid, ids, context={})
return result
@@ -321,25 +375,34 @@ class mrp_operations_operation(osv.osv):
_name="mrp_operations.operation"
def _order_date_search_production(self, cr, uid, ids, context=None):
operation_ids=self.pool.get('mrp_operations.operation').search(cr, uid, [('production_id','=',ids[0])], context=context)
""" Finds operations for a production order.
@return: List of ids
"""
operation_ids = self.pool.get('mrp_operations.operation').search(cr, uid, [('production_id','=',ids[0])], context=context)
return operation_ids
def _get_order_date(self, cr, uid, ids, field_name, arg, context):
""" Calculates planned date for an operation.
@return: Dictionary of values
"""
res={}
operation_obj=self.browse(cr, uid, ids, context=context)
operation_obj = self.browse(cr, uid, ids, context=context)
for operation in operation_obj:
res[operation.id]=operation.production_id.date_planned
res[operation.id] = operation.production_id.date_planned
return res
def calc_delay(self,cr,uid,vals):
code_lst=[]
time_lst=[]
def calc_delay(self, cr, uid, vals):
""" Calculates delay of work order.
@return: Delay
"""
code_lst = []
time_lst = []
code_ids=self.pool.get('mrp_operations.operation.code').search(cr,uid,[('id','=',vals['code_id'])])
code=self.pool.get('mrp_operations.operation.code').browse(cr,uid,code_ids)[0]
code_ids = self.pool.get('mrp_operations.operation.code').search(cr, uid, [('id','=',vals['code_id'])])
code = self.pool.get('mrp_operations.operation.code').browse(cr, uid, code_ids)[0]
oper_ids=self.search(cr,uid,[('production_id','=',vals['production_id']),('workcenter_id','=',vals['workcenter_id'])])
oper_objs=self.browse(cr,uid,oper_ids)
oper_ids = self.search(cr,uid,[('production_id','=',vals['production_id']),('workcenter_id','=',vals['workcenter_id'])])
oper_objs = self.browse(cr,uid,oper_ids)
for oper in oper_objs:
code_lst.append(oper.code_id.start_stop)
@@ -349,7 +412,7 @@ class mrp_operations_operation(osv.osv):
time_lst.append(vals['date_start'])
diff = 0
for i in range(0,len(code_lst)):
if code_lst[i]=='pause' or code_lst[i]=='done' or code_lst[i]=='cancel':
if code_lst[i] == 'pause' or code_lst[i] == 'done' or code_lst[i] == 'cancel':
if not i: continue
if code_lst[i-1] not in ('resume','start'):
continue
@@ -359,7 +422,11 @@ class mrp_operations_operation(osv.osv):
diff += (b-a).seconds / float(60*60)
return diff
def check_operation(self,cr,uid,vals):
def check_operation(self, cr, uid, vals):
""" Finds which operation is called ie. start, pause, done, cancel.
@param vals: Dictionary of values.
@return: True or False
"""
code_ids=self.pool.get('mrp_operations.operation.code').search(cr,uid,[('id','=',vals['code_id'])])
code=self.pool.get('mrp_operations.operation.code').browse(cr,uid,code_ids)[0]
code_lst = []
@@ -0,0 +1,151 @@
-
In order to test mrp_operations module in OpenERP I will put a Production order
and check its effects on Work orders.
-
I create a production order.
-
!record {model: mrp.production, id: mrp_production_mo0}:
company_id: base.main_company
date_planned: '2010-05-25 11:17:34'
location_dest_id: stock.stock_location_stock
location_src_id: stock.stock_location_stock
name: MO/00002
product_id: product.product_product_pc1
product_qty: 5.0
product_uom: product.product_uom_unit
product_uos_qty: 0.0
-
I am computing the data.
-
!python {model: mrp.production}: |
self.action_compute(cr, uid, [ref("mrp_production_mo0")], {"lang": "en_US", "tz":
False, "search_default_current": 1, "active_model": "ir.ui.menu", "active_ids":
[ref("mrp.menu_mrp_production_action")], "active_id": ref("mrp.menu_mrp_production_action"),
})
-
Now I confirm my production order.
-
!workflow {model: mrp.production, action: button_confirm, ref: mrp_production_mo0}
-
I check that there is one Work order generated related to my production order.
-
!python {model: mrp.production.workcenter.line}: |
from tools.translate import _
order_id = self.search(cr, uid, [('production_id','=', ref('mrp_production_mo0')),('state','=','draft')])
assert order_id, _('No Work order!')
-
I am checking Procurement orders.
-
!python {model: procurement.order}: |
from tools.translate import _
proc_ids = self.search(cr, uid, [('state','=','confirmed')])
assert proc_ids, _('No Procurements!')
-
The scheduler runs.
-
!function {model: procurement.order, name: run_scheduler}:
- model: procurement.order
search: "[('state','=','confirmed')]"
-
I am checking Internal picking.
-
!python {model: stock.picking}: |
from tools.translate import _
pick_ids = self.search(cr, uid, [('state','!=','done'),('type','=','internal')])
assert pick_ids, _('No Internal Pickings!')
-
I see that there is a manufacturing order for the sub product CPU_GEN of PC1 with ready state.
-
!python {model: mrp.production}: |
from tools.translate import _
order_ids = self.search(cr, uid, [('state','=','ready')])
assert order_ids, _('No new manufacturing order!')
-
I check that there one more work order created for new production order.
-
!python {model: mrp.production.workcenter.line}: |
from tools.translate import _
prod_obj = self.pool.get('mrp.production')
prod_order_ids = prod_obj.search(cr, uid, [('state','=','ready')])
workorder_id = self.search(cr, uid, [('production_id','=', prod_order_ids[0]),('state','=','draft')])
assert workorder_id, _('No Work order!')
-
I start the second production order of the CPU_GEN product.
-
!python {model: mrp.production}: |
import netsvc
wf_service = netsvc.LocalService("workflow")
prod_order_ids = self.search(cr, uid, [('state','=','ready')])
for po in prod_order_ids:
wf_service.trg_validate(uid, 'mrp.production', po, 'button_produce', cr)
-
I am creating a mrp.product.produce record
-
!record {model: mrp.product.produce, id: mrp_product_produce_0}:
mode: consume_produce
product_qty: 5.0
-
I produce the product CPU_GEN.
-
!python {model: mrp.product.produce}: |
prod_obj = self.pool.get('mrp.production')
prod_order_ids = prod_obj.search(cr, uid, [('state','=','in_production')])
self.do_produce(cr, uid, [ref("mrp_product_produce_0")], {"lang": "en_US", "tz":
False, "search_default_current": 1, "active_model": "mrp.production", "active_ids":
prod_order_ids, "active_id": prod_order_ids[0], })
-
I check that my production order and its related work order is in done state.
-
!python {model: mrp.production.workcenter.line}: |
from tools.translate import _
prod_obj = self.pool.get('mrp.production')
prod_order_ids = prod_obj.search(cr, uid, [('state','=','done')])
workorder_id = self.search(cr, uid, [('production_id','=', prod_order_ids[0]),('state','=','done')])
assert workorder_id, _('Work order is not done!')
-
Now I check my original production order is now ready.
-
!python {model: mrp.production}: |
from tools.translate import _
prod_ids = self.search(cr, uid, [('id','=',ref('mrp_production_mo0')),('state','=','ready')])
assert prod_ids, _('Production order is not ready!')
-
I check that both internal pickings are done.
-
!python {model: stock.picking}: |
from tools.translate import _
pick_ids = self.search(cr, uid, [('state','=','done'),('type','=','internal')])
assert pick_ids, _('Internal pickings are not done!')
-
Now I start my first production order.
-
!workflow {model: mrp.production, action: button_produce, ref: mrp_production_mo0}
-
I check that the related work order is in progress state.
-
!python {model: mrp.production.workcenter.line}: |
from tools.translate import _
order_id = self.search(cr, uid, [('production_id','=', ref('mrp_production_mo0')),('state','=','startworking')])
assert order_id, _('Work order not started yet!')
-
I am creating a mrp.product.produce record.
-
!record {model: mrp.product.produce, id: mrp_product_produce_0}:
mode: consume_produce
product_qty: 5.0
-
I produce the product PC1.
-
!python {model: mrp.product.produce}: |
prod_obj = self.pool.get('mrp.production')
prod_order_ids = prod_obj.search(cr, uid, [('state','=','in_production')])
self.do_produce(cr, uid, [ref("mrp_product_produce_0")], {"lang": "en_US", "tz":
False, "search_default_current": 1, "active_model": "mrp.production", "active_ids":
[ref("mrp_production_mo0")], "active_id": ref("mrp_production_mo0"), })
-
I check the related work order is done.
-
!python {model: mrp.production.workcenter.line}: |
from tools.translate import _
order_id = self.search(cr, uid, [('production_id','=', ref('mrp_production_mo0')),('state','=','done')])
assert order_id, _('Work order not done yet!')
+1 -1
View File
@@ -44,7 +44,7 @@ class repair_cancel(osv.osv_memory):
if repair_order.invoiced or repair_order.invoice_method == 'none':
repair_order_obj.action_cancel(cr, uid, [record_id], context=context)
else:
raise osv.except_osv(_('Warning!'),_('Repair is not cancelled. It is not invoiced.'))
raise osv.except_osv(_('Warning!'),_('Repair order is not invoiced.'))
return {}
+16 -7
View File
@@ -35,10 +35,15 @@ class mrp_subproduct(osv.osv):
_defaults={
'subproduct_type': lambda *args: 'fixed'
}
def onchange_product_id(self, cr, uid, ids, product_id,context={}):
""" Changes UoM if product_id changes.
@param product_id: Changed product_id
@return: Dictionary of changed values
"""
if product_id:
prod=self.pool.get('product.product').browse(cr,uid,product_id)
v = {'product_uom':prod.uom_id.id}
prod = self.pool.get('product.product').browse(cr, uid, product_id)
v = {'product_uom': prod.uom_id.id}
return {'value': v}
return {}
@@ -48,6 +53,7 @@ class mrp_bom(osv.osv):
_name = 'mrp.bom'
_description = 'Bill of Material'
_inherit='mrp.bom'
_columns={
'sub_products':fields.one2many('mrp.subproduct', 'bom_id', 'sub_products'),
}
@@ -59,7 +65,10 @@ class mrp_production(osv.osv):
_inherit= 'mrp.production'
def action_confirm(self, cr, uid, ids):
picking_id=super(mrp_production,self).action_confirm(cr, uid, ids)
""" Confirms production order and calculates quantity based on subproduct_type.
@return: Newly generated picking Id.
"""
picking_id = super(mrp_production,self).action_confirm(cr, uid, ids)
for production in self.browse(cr, uid, ids):
source = production.product_id.product_tmpl_id.property_stock_production.id
if not production.bom_id:
@@ -67,13 +76,13 @@ class mrp_production(osv.osv):
for sub_product in production.bom_id.sub_products:
qty1 = sub_product.product_qty
qty2 = production.product_uos and production.product_uos_qty or False
if sub_product.subproduct_type=='variable':
if sub_product.subproduct_type == 'variable':
if production.product_qty:
qty1 *= production.product_qty / (production.bom_id.product_qty or 1.0)
if production.product_uos_qty:
qty2 *= production.product_uos_qty / (production.bom_id.product_uos_qty or 1.0)
data = {
'name':'PROD:'+production.name,
'name': 'PROD:'+production.name,
'date_planned': production.date_planned,
'product_id': sub_product.product_id.id,
'product_qty': qty1,
@@ -84,9 +93,9 @@ class mrp_production(osv.osv):
'location_dest_id': production.location_dest_id.id,
'move_dest_id': production.move_prod_id.id,
'state': 'waiting',
'production_id':production.id
'production_id': production.id
}
sub_prod_ids=self.pool.get('stock.move').create(cr, uid,data)
sub_prod_ids = self.pool.get('stock.move').create(cr, uid, data)
return picking_id
mrp_production()
+6 -6
View File
@@ -95,7 +95,7 @@
ref('stock.menu_action_picking_tree7'),
ref('stock.menu_action_picking_tree8'),
ref('stock.menu_action_picking_tree9'),
ref('mrp_procurement.menu_mrp_procurement_action3'),
ref('procurement.menu_mrp_procurement_action3'),
ref('point_of_sale.menu_point_root')])]" name="menu_access"/>
<field eval="[(6,0,[ref('res_users_shopuser0'),ref('res_users_shopuser1')])]" name="users"/>
<field eval="[(6,0,[ref('point_of_sale.ir_rule_group_point0'),ref('point_of_sale.ir_rule_group_poslinecompany0'),ref('point_of_sale.ir_rule_group_posreporting0')])]" name="rule_groups"/>
@@ -132,7 +132,7 @@
</record>
<record id="ir_modelsmrp_pdt0" model="ir.model.access">
<field name="model_id" ref="mrp_procurement.model_mrp_procurement"/>
<field name="model_id" ref="procurement.model_procurement_order"/>
<field eval="1" name="perm_read"/>
<field eval="&quot;&quot;&quot;MRP - Procurement&quot;&quot;&quot;" name="name"/>
<field eval="0" name="perm_unlink"/>
@@ -206,7 +206,7 @@
<field name="group_id" ref="res_groups_posuser0"/>
</record>
<record id="ir_model_access_stockwarehouseorderpoint0" model="ir.model.access">
<field name="model_id" ref="mrp_procurement.model_stock_warehouse_orderpoint"/>
<field name="model_id" ref="procurement.model_stock_warehouse_orderpoint"/>
<field eval="1" name="perm_read"/>
<field eval="&quot;&quot;&quot;stock.warehouse.orderpoint&quot;&quot;&quot;" name="name"/>
<field eval="0" name="perm_unlink"/>
@@ -474,12 +474,12 @@
<field name="group_id" ref="res_groups_posuser0"/>
</record>
<record id="ir_model_access_procurement0" model="ir.model.access">
<field name="model_id" ref="mrp_procurement.model_mrp_procurement" />
<field name="model_id" ref="procurement.model_procurement_order" />
<field eval="1" name="perm_read" />
<field eval="1" name="perm_write" />
<field eval="1" name="perm_create" />
<field eval="0" name="perm_unlink" />
<field name="name" eval="&quot;&quot;&quot;mrp.procurement&quot;&quot;&quot;" />
<field name="name" eval="&quot;&quot;&quot;procurement.order&quot;&quot;&quot;" />
<field name="group_id" ref="res_groups_posuser0"/>
</record>
<record id="ir_model_access_tax0" model="ir.model.access">
@@ -497,7 +497,7 @@
name="Reporting"
parent="stock.menu_stock_root" groups="base.group_user"/>
<menuitem action="stock.action_picking_tree" id="stock.menu_action_picking_tree" parent="stock.menu_stock_warehouse_mgmt" sequence="19" groups="res_groups_posuser0"/>
<!-- <menuitem id="mrp_procurement.menu_mrp_reordering" name="Automatic Procurements" parent="stock.menu_stock_root" sequence="4" groups="base.group_user"/>-->
<!-- <menuitem id="procurement.menu_mrp_reordering" name="Automatic Procurements" parent="stock.menu_stock_root" sequence="4" groups="base.group_user"/>-->
<menuitem parent="stock.next_id_61" action="stock.action_stock_line_date" id="stock.menu_report_stock_line_date" groups="base.group_user"/>
</data>
+4 -4
View File
@@ -177,7 +177,7 @@
ref('stock.menu_action_picking_tree7'),
ref('stock.menu_action_picking_tree8'),
ref('stock.menu_action_picking_tree9'),
ref('mrp_procurement.menu_mrp_procurement_action3'),
ref('procurement.menu_mrp_procurement_action3'),
ref('point_of_sale.menu_point_root')])]" name="menu_access"/>
<field eval="[(6,0,[ref('point_of_sale.ir_rule_group_point0'),ref('point_of_sale.ir_rule_group_poslinecompany0'),ref('point_of_sale.ir_rule_group_posreporting0')])]" name="rule_groups"/>
<field eva="[(6,0,[ref('res_users_shopuser0'),ref('res_users_shopuser1')])]" name="users"/>
@@ -214,7 +214,7 @@
</record>
<record id="ir_modelsmrp_pdt0" model="ir.model.access">
<field name="model_id" ref="mrp_procurement.model_mrp_procurement"/>
<field name="model_id" ref="procurement.model_procurement_order"/>
<field eval="1" name="perm_read"/>
<field eval="&quot;&quot;&quot;MRP - Procurement&quot;&quot;&quot;" name="name"/>
<field eval="0" name="perm_unlink"/>
@@ -557,12 +557,12 @@
<field name="group_id" ref="res_groups_posuser0"/>
</record>
<record id="ir_model_access_procurement0" model="ir.model.access">
<field name="model_id" ref="mrp_procurement.model_mrp_procurement" />
<field name="model_id" ref="procurement.model_procurement_order" />
<field eval="1" name="perm_read" />
<field eval="1" name="perm_write" />
<field eval="1" name="perm_create" />
<field eval="0" name="perm_unlink" />
<field name="name" eval="&quot;&quot;&quot;mrp.procurement&quot;&quot;&quot;" />
<field name="name" eval="&quot;&quot;&quot;procurement.order&quot;&quot;&quot;" />
<field name="group_id" ref="res_groups_posuser0"/>
</record>
<record id="ir_model_access_tax0" model="ir.model.access">
+1 -1
View File
@@ -33,7 +33,7 @@
<field eval="1" name="global"/>
</record>
<record id="point_of_sale.res_groups_posuser0" model="res.groups">
<field eval="[(6,0,[ref('product.menu_config_product'),ref('product.menu_product_category_action_form'),ref('point_of_sale.menu_point_ofsale'),ref('point_of_sale.menu_point_config'),ref('point_of_sale.menu_statement_tree_all'),ref('stock.menu_stock_root'),ref('stock.menu_action_location_form'),ref('stock.menu_action_location_tree'),ref('stock.menu_picking_waiting'),ref('stock.menu_action_picking_tree3'),ref('stock.menu_action_picking_tree5'),ref('stock.menu_action_picking_form'),ref('stock.menu_action_picking_tree7'),ref('stock.menu_action_picking_tree8'),ref('stock.menu_action_picking_tree9'),ref('mrp_procurement.menu_mrp_procurement_action3'),ref('mrp_procurement.menu_mrp_procurement_new'),ref('mrp.next_id_77'),ref('mrp.menu_report_workcenter_load'),ref('mrp.menu_report_in_out_picking'),ref('base.menu_sales'),ref('sale.menu_action_shop_form'),ref('sale.menu_sale_order'),ref('sale.menu_action_order_tree'),ref('sale.menu_action_order_tree_all'),ref('sale.menu_action_order_tree2'),ref('sale.menu_action_order_tree3'),ref('sale.menu_action_order_tree7'),ref('sale.menu_action_order_tree8'),ref('sale.menu_action_order_line_tree1'),ref('delivery.menu_action_delivery_carrier_form'),ref('delivery.menu_action_delivery_grid_form'),ref('point_of_sale.menu_point_root')])]" name="menu_access"/>
<field eval="[(6,0,[ref('product.menu_config_product'),ref('product.menu_product_category_action_form'),ref('point_of_sale.menu_point_ofsale'),ref('point_of_sale.menu_point_config'),ref('point_of_sale.menu_statement_tree_all'),ref('stock.menu_stock_root'),ref('stock.menu_action_location_form'),ref('stock.menu_action_location_tree'),ref('stock.menu_picking_waiting'),ref('stock.menu_action_picking_tree3'),ref('stock.menu_action_picking_tree5'),ref('stock.menu_action_picking_form'),ref('stock.menu_action_picking_tree7'),ref('stock.menu_action_picking_tree8'),ref('stock.menu_action_picking_tree9'),ref('procurement.menu_mrp_procurement_action3'),ref('procurement.menu_mrp_procurement_new'),ref('mrp.next_id_77'),ref('mrp.menu_report_workcenter_load'),ref('mrp.menu_report_in_out_picking'),ref('base.menu_sales'),ref('sale.menu_action_shop_form'),ref('sale.menu_sale_order'),ref('sale.menu_action_order_tree'),ref('sale.menu_action_order_tree_all'),ref('sale.menu_action_order_tree2'),ref('sale.menu_action_order_tree3'),ref('sale.menu_action_order_tree7'),ref('sale.menu_action_order_tree8'),ref('sale.menu_action_order_line_tree1'),ref('delivery.menu_action_delivery_carrier_form'),ref('delivery.menu_action_delivery_grid_form'),ref('point_of_sale.menu_point_root')])]" name="menu_access"/>
<field eval="[(6,0,[ref('ir_rule_group_bankstatementcompany0'),ref('ir_rule_group_bankstatementlinecompany0'),ref('point_of_sale.ir_rule_group_point0'),ref('point_of_sale.ir_rule_group_poslinecompany0'),ref('point_of_sale.ir_rule_group_posreporting0')])]" name="rule_groups"/>
<field eval="&quot;&quot;&quot;POS_user&quot;&quot;&quot;" name="name"/>
</record>
@@ -19,7 +19,7 @@
#
##############################################################################
import mrp_procurement
import procurement
import wizard
import schedulers
import company
@@ -33,18 +33,18 @@
'init_xml': [],
'update_xml': [
'security/ir.model.access.csv',
'security/mrp_procurement_security.xml',
'mrp_procurement_data.xml',
'security/procurement_security.xml',
'procurement_data.xml',
'wizard/make_procurement_view.xml',
'wizard/mrp_procurement_view.xml',
'wizard/orderpoint_procurement_view.xml',
'mrp_procurement_view.xml',
'procurement_view.xml',
'wizard/schedulers_all_view.xml',
'mrp_procurement_workflow.xml',
'procurement_workflow.xml',
'process/procurement_process.xml',
"company_view.xml",
],
# 'demo_xml': [],
'demo_xml': ['stock_orderpoint.xml'],
'installable': True,
'active': False,
'certificate': '',
@@ -8,7 +8,7 @@
<record id="process_process_procurementprocess0" model="process.process">
<field eval="&quot;&quot;&quot;Procurement&quot;&quot;&quot;" name="name"/>
<field name="model_id" ref="mrp_procurement.model_mrp_procurement"/>
<field name="model_id" ref="procurement.model_procurement_order"/>
<field eval="1" name="active"/>
</record>
@@ -62,11 +62,11 @@ mrp_property()
# Produce, Buy or Find products and place a move
# then wizard for picking lists & move
#
class mrp_procurement(osv.osv):
class procurement_order(osv.osv):
"""
Procurement Orders
"""
_name = "mrp.procurement"
_name = "procurement.order"
_description = "Procurement"
_order = 'priority,date_planned desc'
_log_create = False
@@ -92,7 +92,7 @@ class mrp_procurement(osv.osv):
'note': fields.text('Note'),
'property_ids': fields.many2many('mrp.property', 'mrp_procurement_property_rel', 'procurement_id','property_id', 'Properties'),
'property_ids': fields.many2many('mrp.property', 'procurement_property_rel', 'procurement_id','property_id', 'Properties'),
'message': fields.char('Latest error', size=64, help="Exception occurred while computing procurement orders."),
'state': fields.selection([
@@ -115,7 +115,7 @@ class mrp_procurement(osv.osv):
'date_planned': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'close_move': lambda *a: 0,
'procure_method': lambda *a: 'make_to_order',
'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'mrp.procurement', context=c)
'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'procurement.order', context=c)
}
def unlink(self, cr, uid, ids, context=None):
@@ -176,7 +176,7 @@ class mrp_procurement(osv.osv):
return res
#
# This method may be overrided by objects that override mrp.procurment
# This method may be overrided by objects that override procurement.order
# for computing their own purpose
#
def _quantity_compute_get(self, cr, uid, proc, context={}):
@@ -287,7 +287,7 @@ class mrp_procurement(osv.osv):
if procurement.product_id.product_tmpl_id.supply_method <> 'buy':
return False
if not procurement.product_id.seller_ids:
cr.execute('update mrp_procurement set message=%s where id=%s', (_('No supplier defined for this product !'), procurement.id))
cr.execute('update procurement_order set message=%s where id=%s', (_('No supplier defined for this product !'), procurement.id))
return False
partner_list = sorted([(partner_id.sequence, partner_id) for partner_id in procurement.product_id.seller_ids if partner_id and partner_id.sequence])
partner = partner_list and partner_list[0] and partner_list[0][1] and partner_list[0][1].name or False
@@ -297,7 +297,7 @@ class mrp_procurement(osv.osv):
return False
address_id = partner_obj.address_get(cr, uid, [partner.id], ['delivery'])['delivery']
if not address_id:
cr.execute('update mrp_procurement set message=%s where id=%s', (_('No address defined for the supplier'), procurement.id))
cr.execute('update procurement_order set message=%s where id=%s', (_('No address defined for the supplier'), procurement.id))
return False
return True
@@ -361,7 +361,7 @@ class mrp_procurement(osv.osv):
ok = ok and self.pool.get('stock.move').action_assign(cr, uid, [id])
cr.execute('select count(id) from stock_warehouse_orderpoint where product_id=%s', (procurement.product_id.id,))
if not cr.fetchone()[0]:
cr.execute('update mrp_procurement set message=%s where id=%s', (_('Stock is not enough and No minimum orderpoint rule defined'), procurement.id))
cr.execute('update procurement_order set message=%s where id=%s', (_('Stock is not enough and No minimum orderpoint rule defined'), procurement.id))
return ok
def action_produce_assign_service(self, cr, uid, ids, context={}):
@@ -406,7 +406,7 @@ class mrp_procurement(osv.osv):
self.write(cr, uid, ids, {'state': 'cancel'})
wf_service = netsvc.LocalService("workflow")
for id in ids:
wf_service.trg_trigger(uid, 'mrp.procurement', id, cr)
wf_service.trg_trigger(uid, 'procurement.order', id, cr)
return True
def action_check_finnished(self, cr, uid, ids):
@@ -442,7 +442,7 @@ class mrp_procurement(osv.osv):
res = self.write(cr, uid, ids, {'state': 'done', 'date_close': time.strftime('%Y-%m-%d')})
wf_service = netsvc.LocalService("workflow")
for id in ids:
wf_service.trg_trigger(uid, 'mrp.procurement', id, cr)
wf_service.trg_trigger(uid, 'procurement.order', id, cr)
return res
def run_scheduler(self, cr, uid, automatic=False, use_new_cursor=False, context=None):
@@ -455,7 +455,7 @@ class mrp_procurement(osv.osv):
self._procure_orderpoint_confirm(cr, uid, automatic=automatic,\
use_new_cursor=use_new_cursor, context=context)
mrp_procurement()
procurement_order()
class stock_warehouse_orderpoint(osv.osv):
@@ -463,16 +463,16 @@ class stock_warehouse_orderpoint(osv.osv):
Defines Minimum stock rules.
"""
_name = "stock.warehouse.orderpoint"
_description = "Orderpoint minimum rule"
_description = "Minimum Inventory Rule"
_columns = {
'name': fields.char('Name', size=32, required=True),
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the orderpoint without removing it."),
'logic': fields.selection([('max','Order to Max'),('price','Best price (not yet active!)')], 'Reordering Mode', required=True),
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', required=True),
'location_id': fields.many2one('stock.location', 'Location', required=True),
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', required=True, ondelete="cascade"),
'location_id': fields.many2one('stock.location', 'Location', required=True, ondelete="cascade"),
'product_id': fields.many2one('product.product', 'Product', required=True, ondelete='cascade', domain=[('type','=','product')]),
'product_uom': fields.many2one('product.uom', 'Product UOM', required=True ),
'product_uom': fields.many2one('product.uom', 'Product UOM', required=True),
'product_min_qty': fields.float('Min Quantity', required=True,
help="When the virtual stock goes belong the Min Quantity, Open ERP generates "\
"a procurement to bring the virtual stock to the Max Quantity."),
@@ -481,18 +481,21 @@ class stock_warehouse_orderpoint(osv.osv):
"a procurement to bring the virtual stock to the Max Quantity."),
'qty_multiple': fields.integer('Qty Multiple', required=True,
help="The procurement quantity will by rounded up to this multiple."),
'procurement_id': fields.many2one('mrp.procurement', 'Latest procurement'),
'procurement_id': fields.many2one('procurement.order', 'Latest procurement', ondelete="set null"),
'company_id': fields.many2one('res.company','Company',required=True),
}
_defaults = {
'active': lambda *a: 1,
'logic': lambda *a: 'max',
'qty_multiple': lambda *a: 1,
'name': lambda x,y,z,c: x.pool.get('ir.sequence').get(y,z,'mrp.warehouse.orderpoint') or '',
'name': lambda x,y,z,c: x.pool.get('ir.sequence').get(y,z,'stock.orderpoint') or '',
'product_uom': lambda sel, cr, uid, context: context.get('product_uom', False),
'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.warehouse.orderpoint', context=c)
}
_sql_constraints = [
('qty_multiple_check', 'CHECK( qty_multiple > 0 )', _('Qty Multiple must be greater than zero.')),
]
def onchange_warehouse_id(self, cr, uid, ids, warehouse_id, context={}):
""" Finds location id for changed warehouse.
@param warehouse_id: Changed id of warehouse.
@@ -503,7 +506,7 @@ class stock_warehouse_orderpoint(osv.osv):
v = {'location_id': w.lot_stock_id.id}
return {'value': v}
return {}
def onchange_product_id(self, cr, uid, ids, product_id, context={}):
""" Finds UoM for changed product.
@param product_id: Changed id of product.
@@ -514,14 +517,14 @@ class stock_warehouse_orderpoint(osv.osv):
v = {'product_uom': prod.uom_id.id}
return {'value': v}
return {}
def copy(self, cr, uid, id, default=None,context={}):
if not default:
default = {}
default.update({
'name': self.pool.get('ir.sequence').get(cr, uid, 'mrp.warehouse.orderpoint') or '',
'name': self.pool.get('ir.sequence').get(cr, uid, 'stock.orderpoint') or '',
})
return super(stock_warehouse_orderpoint, self).copy(cr, uid, id, default, context)
stock_warehouse_orderpoint()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -10,10 +10,23 @@
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
<field eval="'mrp.procurement'" name="model"/>
<field eval="'procurement.order'" name="model"/>
<field eval="'run_scheduler'" name="function"/>
<field eval="'(False,)'" name="args"/>
</record>
<record id="sequence_mrp_op_type" model="ir.sequence.type">
<field name="name">Stock orderpoint</field>
<field name="code">stock.orderpoint</field>
</record>
<record id="sequence_mrp_op" model="ir.sequence">
<field name="name">Stock orderpoint</field>
<field name="code">stock.orderpoint</field>
<field name="prefix">OP/</field>
<field name="padding">5</field>
<field name="number_next">1</field>
<field name="number_increment">1</field>
</record>
</data>
</openerp>
@@ -5,9 +5,9 @@
Procurement
-->
<record id="mrp_procurement_tree_view" model="ir.ui.view">
<field name="name">mrp.procurement.tree</field>
<field name="model">mrp.procurement</field>
<record id="procurement_tree_view" model="ir.ui.view">
<field name="name">procurement.order.tree</field>
<field name="model">procurement.order</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Procurement Lines" colors="red:date_planned&lt;current_date and state in ('exception');black:state=='running';green:state=='confirmed';gray:state in ['done','cancel'];blue:state in ('ready')">
@@ -22,9 +22,9 @@
</tree>
</field>
</record>
<record id="mrp_procurement_form_view" model="ir.ui.view">
<field name="name">mrp.procurement.form</field>
<field name="model">mrp.procurement</field>
<record id="procurement_form_view" model="ir.ui.view">
<field name="name">procurement.order.form</field>
<field name="model">procurement.order</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Procurement">
@@ -66,7 +66,7 @@
<field name="move_id" groups="base.group_extended"/>
<field name="date_close"/>
<field name="close_move" groups="base.group_extended"/>
<group colspan="4" groups="base.group_extended">
<group colspan="4" groups="base.group_extended" expand="1">
<separator colspan="4" string="Properties" />
<field colspan="4" name="property_ids" nolabel="1"/>
</group>
@@ -79,9 +79,9 @@
</form>
</field>
</record>
<record id="view_mrp_procurement_filter" model="ir.ui.view">
<field name="name">mrp.procurement.select</field>
<field name="model">mrp.procurement</field>
<record id="view_procurement_filter" model="ir.ui.view">
<field name="name">procurement.order.select</field>
<field name="model">procurement.order</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Search Procurement">
@@ -109,51 +109,51 @@
</search>
</field>
</record>
<record id="mrp_procurement_action" model="ir.actions.act_window">
<record id="procurement_action" model="ir.actions.act_window">
<field name="name">Procurement Orders</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">mrp.procurement</field>
<field name="res_model">procurement.order</field>
<field name="view_type">form</field>
<field name="view_id" eval="False"/>
<field name="context">{'search_default_current':1}</field>
<field name="search_view_id" ref="view_mrp_procurement_filter"/>
<field name="search_view_id" ref="view_procurement_filter"/>
<field name="context">{'search_default_Current':1}</field>
</record>
<record id="mrp_procurement_action3" model="ir.actions.act_window">
<record id="procurement_action3" model="ir.actions.act_window">
<field name="name">Procurements</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">mrp.procurement</field>
<field name="res_model">procurement.order</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="view_mrp_procurement_filter"/>
<field name="search_view_id" ref="view_procurement_filter"/>
<field name="domain">[]</field>
<field name="context">{}</field>
</record>
<record id="mrp_procurement_action5" model="ir.actions.act_window">
<record id="procurement_action5" model="ir.actions.act_window">
<field name="name">Procurement Exceptions</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">mrp.procurement</field>
<field name="res_model">procurement.order</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('state','=','exception')]</field>
</record>
<record id="mrp_procurement_action4" model="ir.actions.act_window">
<record id="procurement_action4" model="ir.actions.act_window">
<field name="name">Procurement Exceptions to Fix</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">mrp.procurement</field>
<field name="res_model">procurement.order</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('state','=','exception'), ('message', '&lt;&gt;', '')]</field>
<field name="filter" eval="True"/>
</record>
<record id="mrp_procurement_action11" model="ir.actions.act_window">
<record id="procurement_action11" model="ir.actions.act_window">
<field name="name">Temporary Procurement Exceptions</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">mrp.procurement</field>
<field name="res_model">procurement.order</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('state','=','exception'), ('message', '=', '')]</field>
@@ -255,17 +255,17 @@
<act_window
context="{'product_uom': locals().has_key('uom_id') and uom_id}"
domain="[('product_id', '=', active_id)]"
id="act_mrp_procurement_2_stock_warehouse_orderpoint"
id="act_procurement_2_stock_warehouse_orderpoint"
name="Minimum Stock Rules"
res_model="stock.warehouse.orderpoint"
src_model="mrp.procurement"/>
src_model="procurement.order"/>
<act_window
domain="[('id', '=', product_id)]"
id="act_product_product_2_stock_warehouse_orderpoint"
name="Product"
res_model="product.product"
src_model="mrp.procurement"/>
src_model="procurement.order"/>
</data>
</openerp>
@@ -3,8 +3,8 @@
<data>
<record id="wkf_procurement" model="workflow">
<field name="name">mrp.procurement.basic</field>
<field name="osv">mrp.procurement</field>
<field name="name">procurement.order.basic</field>
<field name="osv">procurement.order</field>
<field name="on_create">True</field>
</record>
@@ -26,8 +26,8 @@ from mx import DateTime
import time
class mrp_procurement(osv.osv):
_inherit = 'mrp.procurement'
class procurement_order(osv.osv):
_inherit = 'procurement.order'
def _procure_confirm(self, cr, uid, ids=None, use_new_cursor=False, context=None):
'''
@@ -40,11 +40,11 @@ class mrp_procurement(osv.osv):
cr = pooler.get_db(use_new_cursor).cursor()
wf_service = netsvc.LocalService("workflow")
procurement_obj = self.pool.get('mrp.procurement')
procurement_obj = self.pool.get('procurement.order')
if not ids:
ids = procurement_obj.search(cr, uid, [], order="date_planned")
for id in ids:
wf_service.trg_validate(uid, 'mrp.procurement', id, 'button_restart', cr)
wf_service.trg_validate(uid, 'procurement.order', id, 'button_restart', cr)
if use_new_cursor:
cr.commit()
@@ -57,11 +57,11 @@ class mrp_procurement(osv.osv):
report_except = 0
report_later = 0
while True:
cr.execute('select id from mrp_procurement where state=%s and procure_method=%s order by priority,date_planned limit 500 offset %s', ('confirmed', 'make_to_order', offset))
cr.execute('select id from procurement_order where state=%s and procure_method=%s order by priority,date_planned limit 500 offset %s', ('confirmed', 'make_to_order', offset))
ids = map(lambda x: x[0], cr.fetchall())
for proc in procurement_obj.browse(cr, uid, ids):
if (maxdate.strftime('%Y-%m-%d') >= proc.date_planned):
wf_service.trg_validate(uid, 'mrp.procurement', proc.id, 'button_check', cr)
wf_service.trg_validate(uid, 'procurement.order', proc.id, 'button_check', cr)
else:
offset += 1
report_later += 1
@@ -84,7 +84,7 @@ class mrp_procurement(osv.osv):
ids = procurement_obj.search(cr, uid, [('state', '=', 'confirmed'), ('procure_method', '=', 'make_to_stock')], offset=offset)
for proc in procurement_obj.browse(cr, uid, ids):
if ((maxdate).strftime('%Y-%m-%d') >= proc.date_planned) :
wf_service.trg_validate(uid, 'mrp.procurement', proc.id, 'button_check', cr)
wf_service.trg_validate(uid, 'procurement.order', proc.id, 'button_check', cr)
report_ids.append(proc.id)
else:
report_later += 1
@@ -129,7 +129,7 @@ class mrp_procurement(osv.osv):
if not context:
context = {}
product_obj = self.pool.get('product.product')
proc_obj = self.pool.get('mrp.procurement')
proc_obj = self.pool.get('procurement.order')
warehouse_obj = self.pool.get('stock.warehouse')
wf_service = netsvc.LocalService("workflow")
@@ -161,8 +161,8 @@ class mrp_procurement(osv.osv):
'location_id': location_id,
'procure_method': 'make_to_order',
})
wf_service.trg_validate(uid, 'mrp.procurement', proc_id, 'button_confirm', cr)
wf_service.trg_validate(uid, 'mrp.procurement', proc_id, 'button_check', cr)
wf_service.trg_validate(uid, 'procurement.order', proc_id, 'button_confirm', cr)
wf_service.trg_validate(uid, 'procurement.order', proc_id, 'button_check', cr)
def _procure_orderpoint_confirm(self, cr, uid, automatic=False,\
use_new_cursor=False, context=None, user_id=False):
@@ -175,7 +175,7 @@ class mrp_procurement(osv.osv):
cr = pooler.get_db(use_new_cursor).cursor()
orderpoint_obj = self.pool.get('stock.warehouse.orderpoint')
location_obj = self.pool.get('stock.location')
procurement_obj = self.pool.get('mrp.procurement')
procurement_obj = self.pool.get('procurement.order')
request_obj = self.pool.get('res.request')
wf_service = netsvc.LocalService("workflow")
report = []
@@ -186,8 +186,9 @@ class mrp_procurement(osv.osv):
while ids:
ids = orderpoint_obj.search(cr, uid, [], offset=offset, limit=100)
for op in orderpoint_obj.browse(cr, uid, ids):
if op.procurement_id and op.procurement_id.purchase_id and op.procurement_id.purchase_id.state in ('draft', 'confirmed'):
continue
if op.procurement_id.state != 'exception':
if op.procurement_id and op.procurement_id.purchase_id and op.procurement_id.purchase_id.state in ('draft', 'confirmed'):
continue
prods = location_obj._product_virtual_get(cr, uid,
op.location_id.id, [op.product_id.id],
{'uom': op.product_uom.id})[op.product_id.id]
@@ -217,9 +218,9 @@ class mrp_procurement(osv.osv):
'procure_method': 'make_to_order',
'origin': op.name
})
wf_service.trg_validate(uid, 'mrp.procurement', proc_id,
wf_service.trg_validate(uid, 'procurement.order', proc_id,
'button_confirm', cr)
wf_service.trg_validate(uid, 'mrp.procurement', proc_id,
wf_service.trg_validate(uid, 'procurement.order', proc_id,
'button_check', cr)
orderpoint_obj.write(cr, uid, [op.id],
{'procurement_id': proc_id})
@@ -237,6 +238,6 @@ class mrp_procurement(osv.osv):
cr.commit()
cr.close()
return {}
mrp_procurement()
procurement_order()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -22,7 +22,7 @@
import xmlrpclib
sock = xmlrpclib.ServerProxy('http://localhost:8069/xmlrpc/wizard')
wiz_id = sock.create('trunk', 1, 'admin', 'mrp.procurement.compute.all')
wiz_id = sock.create('trunk', 1, 'admin', 'procurement.order.compute.all')
sock.execute('trunk', 1, 'admin', wiz_id, {'form': {'po_cycle': 1.0, 'po_lead': 1.0, 'user_id': 3, 'schedule_cycle': 1.0, 'picking_lead': 1.0, 'security_lead': 50.0, 'automatic': False}, 'ids': [], 'report_type': 'pdf', 'model': 'ir.ui.menu', 'id': False}, 'compute', {})
@@ -1,9 +1,9 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_mrp_property_group","mrp.property.group","model_mrp_property_group",,1,0,0,0
"access_mrp_property","mrp.property","model_mrp_property",,1,0,0,0
"access_mrp_procurement","mrp.procurement","model_mrp_procurement",,1,0,0,0
"access_procurement","procurement.order","model_procurement_order",,1,0,0,0
"access_stock_warehouse_orderpoint","stock.warehouse.orderpoint","model_stock_warehouse_orderpoint",,1,0,0,0
"access_mrp_procurement_compute_all","mrp.procurement.compute.all","model_mrp_procurement_compute_all",,1,0,0,0
"access_mrp_procurement_orderpoint_compute","mrp.procurement.orderpoint.compute","model_mrp_procurement_orderpoint_compute",,1,0,0,0
"access_procurement_compute_all","procurement.order.compute.all","model_procurement_order_compute_all",,1,0,0,0
"access_procurement_orderpoint_compute","procurement.orderpoint.compute","model_procurement_orderpoint_compute",,1,0,0,0
"access_mrp_make_procurement","make.procurement","model_make_procurement",,1,0,0,0
"access_mrp_make_procurement","mrp.procurement.compute","model_mrp_procurement_compute",,1,0,0,0
"access_mrp_make_procurement","procurement.order.compute","model_procurement_order_compute",,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_mrp_property_group mrp.property.group model_mrp_property_group 1 0 0 0
3 access_mrp_property mrp.property model_mrp_property 1 0 0 0
4 access_mrp_procurement access_procurement mrp.procurement procurement.order model_mrp_procurement model_procurement_order 1 0 0 0
5 access_stock_warehouse_orderpoint stock.warehouse.orderpoint model_stock_warehouse_orderpoint 1 0 0 0
6 access_mrp_procurement_compute_all access_procurement_compute_all mrp.procurement.compute.all procurement.order.compute.all model_mrp_procurement_compute_all model_procurement_order_compute_all 1 0 0 0
7 access_mrp_procurement_orderpoint_compute access_procurement_orderpoint_compute mrp.procurement.orderpoint.compute procurement.orderpoint.compute model_mrp_procurement_orderpoint_compute model_procurement_orderpoint_compute 1 0 0 0
8 access_mrp_make_procurement make.procurement model_make_procurement 1 0 0 0
9 access_mrp_make_procurement mrp.procurement.compute procurement.order.compute model_mrp_procurement_compute model_procurement_order_compute 1 0 0 0
@@ -2,9 +2,9 @@
<openerp>
<data noupdate="0">
<record model="ir.rule" id="mrp_procurement_rule">
<field name="name">mrp_procurement multi-company</field>
<field name="model_id" search="[('model','=','mrp.procurement')]" model="ir.model"/>
<record model="ir.rule" id="procurement_rule">
<field name="name">procurement multi-company</field>
<field name="model_id" search="[('model','=','procurement.order')]" model="ir.model"/>
<field name="global" eval="True"/>
<field name="domain_force">['|',('company_id','child_of',[user.company_id.id]),('company_id','=',False)]</field>
</record>
@@ -64,7 +64,7 @@ class make_procurement(osv.osv_memory):
"""
user = self.pool.get('res.users').browse(cr, uid, uid, context).login
wh_obj = self.pool.get('stock.warehouse')
procurement_obj = self.pool.get('mrp.procurement')
procurement_obj = self.pool.get('procurement.order')
wf_service = netsvc.LocalService("workflow")
data_obj = self.pool.get('ir.model.data')
@@ -80,11 +80,11 @@ class make_procurement(osv.osv_memory):
'procure_method':'make_to_order',
})
wf_service.trg_validate(uid, 'mrp.procurement', procure_id, 'button_confirm', cr)
wf_service.trg_validate(uid, 'procurement.order', procure_id, 'button_confirm', cr)
id2 = data_obj._get_id(cr, uid, 'mrp_procurement', 'mrp_procurement_tree_view')
id3 = data_obj._get_id(cr, uid, 'mrp_procurement', 'mrp_procurement_form_view')
id2 = data_obj._get_id(cr, uid, 'procurement', 'procurement_tree_view')
id3 = data_obj._get_id(cr, uid, 'procurement', 'procurement_form_view')
if id2:
id2 = data_obj.browse(cr, uid, id2, context=context).res_id
@@ -94,7 +94,7 @@ class make_procurement(osv.osv_memory):
return {
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'mrp.procurement',
'res_model': 'procurement.order',
'res_id' : procure_id,
'views': [(id3,'form'),(id2,'tree')],
'type': 'ir.actions.act_window',
@@ -23,12 +23,12 @@ import threading
from osv import osv, fields
class procurement_compute(osv.osv_memory):
_name = 'mrp.procurement.compute'
_name = 'procurement.order.compute'
_description = 'Compute Procurement'
def _procure_calculation_procure(self, cr, uid, ids, context):
try:
proc_obj = self.pool.get('mrp.procurement')
proc_obj = self.pool.get('procurement.order')
proc_obj._procure_confirm(cr, uid, use_new_cursor=cr.dbname, context=context)
finally:
cr.close()
@@ -6,7 +6,7 @@
<record id="view_compute_procurment_wizard" model="ir.ui.view">
<field name="name">Compute Procurements</field>
<field name="model">mrp.procurement.compute</field>
<field name="model">procurement.order.compute</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Parameters">
@@ -23,8 +23,8 @@
</record>
<!-- <act_window name="Compute Procurements" -->
<!-- res_model="mrp.procurement.compute"-->
<!-- src_model="mrp.procurement"-->
<!-- res_model="procurement.order.compute"-->
<!-- src_model="procurement.order"-->
<!-- view_mode="form"-->
<!-- target="new" -->
<!-- key2="client_action_multi" -->
@@ -28,7 +28,7 @@ import threading
from osv import fields,osv
class procurement_compute(osv.osv_memory):
_name = 'mrp.procurement.orderpoint.compute'
_name = 'procurement.orderpoint.compute'
_description = 'Automatic Order Point'
_columns = {
@@ -47,7 +47,7 @@ class procurement_compute(osv.osv_memory):
@param ids: List of IDs selected
@param context: A standard dictionary
"""
proc_obj = self.pool.get('mrp.procurement')
proc_obj = self.pool.get('procurement.order')
for proc in self.browse(cr, uid, ids):
proc_obj._procure_orderpoint_confirm(cr, uid, automatic=proc.automatic, use_new_cursor=cr.dbname, context=context)
@@ -6,7 +6,7 @@
<record id="view_procurement_compute_wizard" model="ir.ui.view">
<field name="name">Compute Stock Minimum Rules Only</field>
<field name="model">mrp.procurement.orderpoint.compute</field>
<field name="model">procurement.orderpoint.compute</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Parameters">
@@ -23,8 +23,8 @@
</record>
<act_window name="Compute Stock Minimum Rules Only"
res_model="mrp.procurement.orderpoint.compute"
src_model="mrp.procurement"
res_model="procurement.orderpoint.compute"
src_model="procurement.order"
view_mode="form"
target="new"
key2="client_action_multi"
@@ -23,8 +23,8 @@ import threading
from osv import osv, fields
class procurement_compute(osv.osv_memory):
_name = 'mrp.procurement.compute.all'
class procurement_compute_all(osv.osv_memory):
_name = 'procurement.order.compute.all'
_description = 'Compute all schedulers'
_columns = {
@@ -43,7 +43,7 @@ class procurement_compute(osv.osv_memory):
@param ids: List of IDs selected
@param context: A standard dictionary
"""
proc_obj = self.pool.get('mrp.procurement')
proc_obj = self.pool.get('procurement.order')
for proc in self.browse(cr, uid, ids):
proc_obj.run_scheduler(cr, uid, automatic=proc.automatic, use_new_cursor=cr.dbname,\
context=context)
@@ -61,7 +61,7 @@ class procurement_compute(osv.osv_memory):
threaded_calculation.start()
return {}
procurement_compute()
procurement_compute_all()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -6,7 +6,7 @@
<record id="view_compute_schedulers_wizard" model="ir.ui.view">
<field name="name">Compute Schedulers</field>
<field name="model">mrp.procurement.compute.all</field>
<field name="model">procurement.order.compute.all</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Scheduler Parameters">
@@ -23,8 +23,8 @@
</record>
<act_window name="Compute Schedulers"
res_model="mrp.procurement.compute.all"
src_model="mrp.procurement"
res_model="procurement.order.compute.all"
src_model="procurement.order"
view_mode="form"
target="new"
key2="client_action_multi"
+2 -1
View File
@@ -47,12 +47,13 @@ automatically created via sale orders.
""",
'author': 'Tiny',
'website': 'http://www.openerp.com',
'depends': ['project', 'mrp_procurement', 'sale', 'mrp_jit'],
'depends': ['project', 'procurement', 'sale', 'mrp_jit'],
'init_xml': [],
'update_xml': ['project_mrp_workflow.xml',
#'process/project_mrp_process.xml',
],
'demo_xml': [],
'test': ['test/project_task_procurement.yml'],
'installable': True,
'active': False,
'certificate': '0031976495453',
+4 -4
View File
@@ -22,9 +22,9 @@
from osv import fields, osv, orm
import tools
class mrp_procurement(osv.osv):
_name = "mrp.procurement"
_inherit = "mrp.procurement"
class procurement_order(osv.osv):
_name = "procurement.order"
_inherit = "procurement.order"
def action_produce_assign_service(self, cr, uid, ids, context={}):
for procurement in self.browse(cr, uid, ids):
@@ -91,7 +91,7 @@ class mrp_procurement(osv.osv):
'project_id': project_id,
},context=context)
return task_id
mrp_procurement()
procurement_order()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+3 -3
View File
@@ -26,7 +26,7 @@ class project_task(osv.osv):
_name = "project.task"
_inherit = "project.task"
_columns = {
'procurement_id': fields.many2one('mrp.procurement', 'Procurement', ondelete='set null')
'procurement_id': fields.many2one('procurement.order', 'Procurement', ondelete='set null')
}
def do_close(self, cr, uid, ids, *args):
@@ -35,7 +35,7 @@ class project_task(osv.osv):
for task in tasks:
if task.procurement_id:
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'mrp.procurement', task.procurement_id.id, 'subflow.done', cr)
wf_service.trg_validate(uid, 'procurement.order', task.procurement_id.id, 'subflow.done', cr)
return res
def do_cancel(self, cr, uid, ids, *args):
@@ -44,7 +44,7 @@ class project_task(osv.osv):
for task in tasks:
if task.procurement_id:
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'mrp.procurement', task.procurement_id.id, 'subflow.cancel', cr)
wf_service.trg_validate(uid, 'procurement.order', task.procurement_id.id, 'subflow.cancel', cr)
return True
project_task()
+3 -3
View File
@@ -1,9 +1,9 @@
<?xml version="1.0"?>
<openerp>
<data>
<record model="workflow.transition" id="mrp_procurement.trans_produce_service_make_done">
<field name="act_from" ref="mrp_procurement.act_produce_service"/>
<field name="act_to" ref="mrp_procurement.act_make_done"/>
<record model="workflow.transition" id="procurement.trans_produce_service_make_done">
<field name="act_from" ref="procurement.act_produce_service"/>
<field name="act_to" ref="procurement.act_make_done"/>
<field name="signal">subflow.done</field>
</record>
</data>
@@ -1,3 +1,3 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_mrp_procurement_project_user","mrp.procurement project_user","model_mrp_procurement","project.group_project_user",1,1,1,1
"access_mrp_procurement_project_manager","mrp.procurement project_manager","model_mrp_procurement","project.group_project_manager",1,1,1,1
"access_procurement_project_user","procurement.order project_user","model_procurement_order","project.group_project_user",1,1,1,1
"access_procurement_project_manager","procurement.order project_manager","model_procurement_order","project.group_project_manager",1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_mrp_procurement_project_user access_procurement_project_user mrp.procurement project_user procurement.order project_user model_mrp_procurement model_procurement_order project.group_project_user 1 1 1 1
3 access_mrp_procurement_project_manager access_procurement_project_manager mrp.procurement project_manager procurement.order project_manager model_mrp_procurement model_procurement_order project.group_project_manager 1 1 1 1
@@ -0,0 +1,75 @@
-
In order to test project_mrp module with OpenERP I want to create sale orders
with product type 'service' so when procurement runs one task is created.
-
I create record for a service type product.
-
!record {model: product.product, id: product_product_partnerstraining0}:
categ_id: product.product_category_7
cost_method: standard
mes_type: fixed
name: Partners Training
procure_method: make_to_order
supply_method: produce
type: service
uom_id: product.uom_day
uom_po_id: product.uom_day
warranty: 0.0
-
I create a sale order for product Partners Training which has type 'Service'.
-
!record {model: sale.order, id: sale_order_so0}:
date_order: '2010-05-21'
invoice_quantity: order
name: SO006
order_policy: manual
partner_id: base.res_partner_asus
partner_invoice_id: base.res_partner_address_tang
partner_order_id: base.res_partner_address_tang
partner_shipping_id: base.res_partner_address_tang
order_line:
- state: draft
delay: 7.0
name: Partners Training
price_unit: 1.0
product_id: product_product_partnerstraining0
product_uom: product.uom_day
product_uom_qty: 5.0
th_weight: 0.0
type: make_to_order
picking_policy: direct
pricelist_id: product.list0
shop_id: sale.shop
user_id: base.user_demo
-
I confirm this sale order.
-
!workflow {model: sale.order, action: order_confirm, ref: sale_order_so0}
-
I check the procurements.
-
!python {model: procurement.order}: |
from tools.translate import _
orderline_obj = self.pool.get('sale.order.line')
line_ids = orderline_obj.search(cr, uid, [('order_id','=', ref('sale_order_so0'))])
orders = orderline_obj.browse(cr, uid, line_ids)
proc_ids = map(lambda x: x.procurement_id.id, orders)
assert proc_ids, _('No Procurements!')
-
The scheduler runs.
-
!function {model: procurement.order, name: run_scheduler}:
- model: procurement.order
search: "[('state','=','confirmed')]"
-
Now I check the tasks.
-
I see that one task is created for my sale order.
-
!python {model: project.task}: |
from tools.translate import _
order_obj = self.pool.get('sale.order')
order = order_obj.browse(cr, uid, ref('sale_order_so0'))
task_id = self.search(cr, uid, [('project_id.name','=', order.name)])
assert task_id, _('No Task is created!')
+1 -1
View File
@@ -31,7 +31,7 @@
""",
'author': 'Tiny',
'website': 'http://www.openerp.com',
'depends': ['base', 'account', 'stock', 'process', 'mrp_procurement'],
'depends': ['base', 'account', 'stock', 'process', 'procurement'],
'init_xml': [],
'update_xml': [
+3 -3
View File
@@ -698,8 +698,8 @@ class purchase_order_line(osv.osv):
return True
purchase_order_line()
class mrp_procurement(osv.osv):
_inherit = 'mrp.procurement'
class procurement_order(osv.osv):
_inherit = 'procurement.order'
_columns = {
'purchase_id': fields.many2one('purchase.order', 'Latest Requisition'),
}
@@ -779,7 +779,7 @@ class mrp_procurement(osv.osv):
res[procurement.id] = purchase_id
self.write(cr, uid, [procurement.id], {'state': 'running', 'purchase_id': purchase_id})
return res
mrp_procurement()
procurement_order()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+3 -3
View File
@@ -353,9 +353,9 @@
-->
<record id="view_procurement_form_inherit" model="ir.ui.view">
<field name="name">mrp.procurement.form.inherit</field>
<field name="model">mrp.procurement</field>
<field name="inherit_id" ref="mrp_procurement.mrp_procurement_form_view"/>
<field name="name">procurement.order.form.inherit</field>
<field name="model">procurement.order</field>
<field name="inherit_id" ref="procurement.procurement_form_view"/>
<field name="type">form</field>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page/field[@name='close_move']" position="before">
+4 -4
View File
@@ -180,7 +180,7 @@
<!-- Procurement -->
<record id="act_buy" model="workflow.activity">
<field name="wkf_id" ref="mrp_procurement.wkf_procurement"/>
<field name="wkf_id" ref="procurement.wkf_procurement"/>
<field name="name">buy</field>
<field name="kind">subflow</field>
<field name="subflow_id" search="[('osv','=','purchase.order')]"/>
@@ -188,20 +188,20 @@
</record>
<record id="trans_confirm_mto_buy" model="workflow.transition">
<field name="act_from" ref="mrp_procurement.act_confirm_mto"/>
<field name="act_from" ref="procurement.act_confirm_mto"/>
<field name="act_to" ref="act_buy"/>
<field name="condition">check_buy()</field>
</record>
<record id="trans_buy_make_done" model="workflow.transition">
<field name="act_from" ref="act_buy"/>
<field name="act_to" ref="mrp_procurement.act_make_done"/>
<field name="act_to" ref="procurement.act_make_done"/>
<field name="signal">subflow.delivery_done</field>
</record>
<record id="trans_buy_cancel" model="workflow.transition">
<field name="act_from" ref="act_buy"/>
<field name="act_to" ref="mrp_procurement.act_cancel"/>
<field name="act_to" ref="procurement.act_cancel"/>
<field name="signal">subflow.cancel</field>
</record>
@@ -136,11 +136,11 @@ class product_product(osv.osv):
product_product()
class mrp_procurement(osv.osv):
_inherit = 'mrp.procurement'
class procurement_order(osv.osv):
_inherit = 'procurement.order'
def make_po(self, cr, uid, ids, context={}):
sequence_obj=self.pool.get('ir.sequence')
res = super(mrp_procurement, self).make_po(cr, uid, ids, context)
res = super(procurement_order, self).make_po(cr, uid, ids, context)
for proc_id,po_id in res.items():
procurement = self.browse(cr, uid, proc_id)
if procurement.product_id.purchase_requisition:
@@ -157,4 +157,4 @@ class mrp_procurement(osv.osv):
'purchase_ids': [(6,0,[po_id])]
})
return res
mrp_procurement()
procurement_order()
@@ -59,8 +59,8 @@
-
I launch he scheduler to compute all procurements, and specify all requisitions orders.
-
!python {model: mrp.procurement.compute.all}: |
proc_obj = self.pool.get('mrp.procurement')
!python {model: procurement.order.compute.all}: |
proc_obj = self.pool.get('procurement.order')
proc_obj._procure_confirm(cr,uid)
-
On the purchase tender, I create a new purchase order for the supplier 'DistriPC' by clicking on
@@ -52,8 +52,8 @@
-
I launch he scheduler to compute all procurements, and planify all requisitions orders.
-
!python {model: mrp.procurement.compute.all}: |
proc_obj = self.pool.get('mrp.procurement')
!python {model: procurement.order.compute.all}: |
proc_obj = self.pool.get('procurement.order')
proc_obj._procure_confirm(cr,uid)
-
I should find a purchase requisition with the origin 'TEST/TENDER/0002', that includes a request for
-1
View File
@@ -26,7 +26,6 @@
import sale
import stock
import product
#import mrp
import wizard
import report
import company
+1 -1
View File
@@ -42,7 +42,7 @@
""",
'author': 'Tiny',
'website': 'http://www.openerp.com',
'depends': ['product', 'stock', 'mrp_procurement', 'process'],
'depends': ['product', 'stock', 'procurement', 'process'],
'init_xml': [],
'update_xml': [
'wizard/sale_make_invoice_advance.xml',
+5 -5
View File
@@ -35,7 +35,7 @@
<field eval="&quot;&quot;&quot;Sale Order Requisition&quot;&quot;&quot;" name="name"/>
<field eval="&quot;&quot;&quot;Drives procurement orders for every sale order line.&quot;&quot;&quot;" name="note"/>
<field name="subflow_id" ref="process_process_salesprocess0"/>
<field name="process_id" ref="mrp_procurement.process_process_procurementprocess0"/>
<field name="process_id" ref="procurement.process_process_procurementprocess0"/>
<field eval="&quot;&quot;&quot;object.state in ('draft', 'waiting_date', 'manual', 'progress', 'shipping_except', 'invoice_except', 'done', 'cancel')&quot;&quot;&quot;" name="model_states"/>
<field eval="1" name="flow_start"/>
</record>
@@ -63,12 +63,12 @@
</record>
<record id="process_node_saleprocurement0" model="process.node">
<field name="menu_id" ref="mrp_procurement.menu_mrp_procurement_action"/>
<field name="model_id" ref="mrp_procurement.model_mrp_procurement"/>
<field name="menu_id" ref="procurement.menu_mrp_procurement_action"/>
<field name="model_id" ref="procurement.model_procurement_order"/>
<field eval="&quot;&quot;&quot;subflow&quot;&quot;&quot;" name="kind"/>
<field eval="&quot;&quot;&quot;Procurement Order&quot;&quot;&quot;" name="name"/>
<field eval="&quot;&quot;&quot;One Procurement order for each sale order line and for each of the components.&quot;&quot;&quot;" name="note"/>
<field name="subflow_id" ref="mrp_procurement.process_process_procurementprocess0"/>
<field name="subflow_id" ref="procurement.process_process_procurementprocess0"/>
<field name="process_id" ref="process_process_salesprocess0"/>
<field eval="&quot;&quot;&quot;object.state=='confirmed'&quot;&quot;&quot;" name="model_states"/>
<field eval="1" name="flow_start"/>
@@ -202,7 +202,7 @@
<field eval="[(6,0,[])]" name="transition_ids"/>
<field eval="&quot;&quot;&quot;Procurement of sold material&quot;&quot;&quot;" name="name"/>
<field eval="&quot;&quot;&quot;For every sale order line, a procurement order is created to supply the sold product.&quot;&quot;&quot;" name="note"/>
<field model="process.node" name="target_node_id" ref="mrp_procurement.process_node_procureproducts0"/>
<field model="process.node" name="target_node_id" ref="procurement.process_node_procureproducts0"/>
<field model="process.node" name="source_node_id" ref="process_node_saleorderprocurement0"/>
</record>
+8 -8
View File
@@ -112,7 +112,7 @@ class sale_order(osv.osv):
LEFT JOIN
stock_picking p on (p.id=m.picking_id)
LEFT JOIN
mrp_procurement mp on (mp.move_id=m.id)
procurement_order mp on (mp.move_id=m.id)
WHERE
p.sale_id = ANY(%s) GROUP BY mp.state, p.sale_id''',(ids,))
for oid, nbr, mp_state in cr.fetchall():
@@ -658,7 +658,7 @@ class sale_order(osv.osv):
'note': line.notes,
'company_id': order.company_id.id,
})
proc_id = self.pool.get('mrp.procurement').create(cr, uid, {
proc_id = self.pool.get('procurement.order').create(cr, uid, {
'name': order.name,
'origin': order.name,
'date_planned': date_planned,
@@ -676,10 +676,10 @@ class sale_order(osv.osv):
'company_id': order.company_id.id,
})
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'mrp.procurement', proc_id, 'button_confirm', cr)
wf_service.trg_validate(uid, 'procurement.order', proc_id, 'button_confirm', cr)
self.pool.get('sale.order.line').write(cr, uid, [line.id], {'procurement_id': proc_id})
elif line.product_id and line.product_id.product_tmpl_id.type == 'service':
proc_id = self.pool.get('mrp.procurement').create(cr, uid, {
proc_id = self.pool.get('procurement.order').create(cr, uid, {
'name': line.name,
'origin': order.name,
'date_planned': date_planned,
@@ -693,7 +693,7 @@ class sale_order(osv.osv):
})
self.pool.get('sale.order.line').write(cr, uid, [line.id], {'procurement_id': proc_id})
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'mrp.procurement', proc_id, 'button_confirm', cr)
wf_service.trg_validate(uid, 'procurement.order', proc_id, 'button_confirm', cr)
else:
#
# No procurement because no product in the sale.order.line.
@@ -807,7 +807,7 @@ class sale_order_line(osv.osv):
'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], change_default=True),
'invoice_lines': fields.many2many('account.invoice.line', 'sale_order_line_invoice_rel', 'order_line_id', 'invoice_id', 'Invoice Lines', readonly=True),
'invoiced': fields.boolean('Invoiced', readonly=True),
'procurement_id': fields.many2one('mrp.procurement', 'Procurement'),
'procurement_id': fields.many2one('procurement.order', 'Procurement'),
'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Sale Price'), readonly=True, states={'draft':[('readonly',False)]}),
'price_subtotal': fields.function(_amount_line, method=True, string='Subtotal', digits_compute= dp.get_precision('Sale Price')),
'tax_id': fields.many2many('account.tax', 'sale_order_tax', 'order_line_id', 'tax_id', 'Taxes', readonly=True, states={'draft':[('readonly',False)]}),
@@ -856,7 +856,7 @@ class sale_order_line(osv.osv):
return line.product_uos_qty or 0.0
return line.product_uom_qty
else:
return self.pool.get('mrp.procurement').quantity_get(cr, uid,
return self.pool.get('procurement.order').quantity_get(cr, uid,
line.procurement_id.id, context=context)
def _get_line_uom(line):
@@ -865,7 +865,7 @@ class sale_order_line(osv.osv):
return line.product_uos.id
return line.product_uom.id
else:
return self.pool.get('mrp.procurement').uom_get(cr, uid,
return self.pool.get('procurement.order').uom_get(cr, uid,
line.procurement_id.id, context=context)
create_ids = []
+1 -1
View File
@@ -206,7 +206,7 @@
<workflow action="order_confirm" model="sale.order" ref="order5"/>
<!-- Run all schedulers -->
<function model="mrp.procurement" name="run_scheduler"/>
<function model="procurement.order" name="run_scheduler"/>
<!-- sale advance demo.. -->
+1 -1
View File
@@ -112,7 +112,7 @@
</assert>
<!-- Run all schedulers -->
<function model="mrp.procurement" name="run_scheduler"/>
<function model="procurement.order" name="run_scheduler"/>
<assert id="test_order_1" model="sale.order" string="the sale order is now done">
<test expr="state">done</test>
+2 -2
View File
@@ -218,7 +218,7 @@
<record id="trans_ship_ship_end" model="workflow.transition">
<field name="act_from" ref="act_ship"/>
<field name="act_to" ref="act_ship_end"/>
<field name="trigger_model">mrp.procurement</field>
<field name="trigger_model">procurement.order</field>
<field name="trigger_expr_id">procurement_lines_get()</field>
<field name="condition">test_state('finished')</field>
</record>
@@ -226,7 +226,7 @@
<field name="act_from" ref="act_ship"/>
<field name="act_to" ref="act_ship_except"/>
<!--
<field name="trigger_model">mrp.procurement</field>
<field name="trigger_model">procurement.order</field>
<field name="trigger_expr_id">procurement_lines_get()</field>
-->
<field name="condition">test_state('canceled')</field>
+1 -1
View File
@@ -11,7 +11,7 @@
"access_account_analytic_account_salesman","account_analytic_account salesman","analytic.model_account_analytic_account","group_sale_user",1,1,1,1
"access_stock_picking_salesman","stock_picking salesman","stock.model_stock_picking","group_sale_user",1,1,1,1
"access_stock_move_salesman","stock_move salesman","stock.model_stock_move","group_sale_user",1,1,1,0
"access_mrp_procurement_salesman","mrp.procurement salesman","mrp_procurement.model_mrp_procurement","group_sale_user",1,1,1,1
"access_procurement_salesman","procurement.order salesman","procurement.model_procurement_order","group_sale_user",1,1,1,1
"access_sale_order_stock_worker","sale.order stock worker","model_sale_order","stock.group_stock_user",1,1,0,0
"access_sale_order_line_stock_worker","sale.order.line stock worker","model_sale_order_line","stock.group_stock_user",1,1,0,0
"access_sale_order_manager","sale.order.manager","model_sale_order","group_sale_manager",1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
11 access_account_analytic_account_salesman account_analytic_account salesman analytic.model_account_analytic_account group_sale_user 1 1 1 1
12 access_stock_picking_salesman stock_picking salesman stock.model_stock_picking group_sale_user 1 1 1 1
13 access_stock_move_salesman stock_move salesman stock.model_stock_move group_sale_user 1 1 1 0
14 access_mrp_procurement_salesman access_procurement_salesman mrp.procurement salesman procurement.order salesman mrp_procurement.model_mrp_procurement procurement.model_procurement_order group_sale_user 1 1 1 1
15 access_sale_order_stock_worker sale.order stock worker model_sale_order stock.group_stock_user 1 1 0 0
16 access_sale_order_line_stock_worker sale.order.line stock worker model_sale_order_line stock.group_stock_user 1 1 0 0
17 access_sale_order_manager sale.order.manager model_sale_order group_sale_manager 1 1 1 1
+24
View File
@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import sale_mrp
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+44
View File
@@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': 'Sales and MRP Management',
'version': '1.0',
'category': 'Generic Modules/Sales & MRP',
'description': """
This module provides facility to the user to install mrp and sale modules
at a time. It is basically used when we want to keep track of production
orders generated from sale orders.
""",
'author': 'Tiny',
'website': 'http://www.openerp.com',
'depends': ['mrp', 'sale'],
'init_xml': [],
'update_xml': [
'sale_mrp_view.xml',
],
'demo_xml': [],
'installable': True,
'active': False,
'certificate': '',
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -23,10 +23,14 @@
from osv import osv, fields
class mrp_production(osv.osv):
_inherit = 'mrp.production'
def _ref_calc(self, cr, uid, ids, field_names=None, arg=False, context={}):
""" Finds reference of sale order for production order.
@param field_names: Names of fields.
@param arg: User defined arguments
@return: Dictionary of values.
"""
if not field_names:
field_names=[]
res = {}
@@ -65,4 +69,11 @@ class mrp_production(osv.osv):
res[production['id']] = move.sale_line_id and move.sale_line_id.order_id.client_order_ref or False
return res
mrp_production()
_columns = {
'sale_name': fields.function(_ref_calc, method=True, multi='sale_name', type='char', string='Sale Name', help='Indicate the name of sale order.'),
'sale_ref': fields.function(_ref_calc, method=True, multi='sale_ref', type='char', string='Sale Reference', help='Indicate the Customer Reference from sale order.'),
}
mrp_production()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_mrp_production_form" model="ir.ui.view">
<field name="name">mrp.production.form</field>
<field name="model">mrp.production</field>
<field name="inherit_id" ref="mrp.mrp_production_form_view"/>
<field name="type">form</field>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page/field[@name='move_prod_id']" position="after">
<field name="sale_name" groups="base.group_extended"/>
<field name="sale_ref" groups="base.group_extended"/>
</xpath>
</field>
</record>
</data>
</openerp>
+285 -69
View File
@@ -78,6 +78,9 @@ class stock_location(osv.osv):
return res
def _complete_name(self, cr, uid, ids, name, args, context):
""" Forms complete name of location from parent location to child location.
@return: Dictionary of values
"""
def _get_one_full_name(location, level=4):
if location.location_id:
parent_path = _get_one_full_name(location.location_id, level-1) + "/"
@@ -90,6 +93,9 @@ class stock_location(osv.osv):
return res
def _product_qty_available(self, cr, uid, ids, field_names, arg, context={}):
""" Finds real and virtual quantity for product available at particular location.
@return: Dictionary of values
"""
res = {}
for id in ids:
res[id] = {}.fromkeys(field_names, 0.0)
@@ -106,6 +112,10 @@ class stock_location(osv.osv):
return res
def product_detail(self, cr, uid, id, field, context={}):
""" Finds detail of product like price type, currency and then calculates its price.
@param field: Field name
@return: Calculated price
"""
res = {}
res[id] = {}
final_value = 0.0
@@ -117,21 +127,25 @@ class stock_location(osv.osv):
if result:
# Choose the right filed standard_price to read
# Take the user company
price_type_id=self.pool.get('res.users').browse(cr,uid,uid).company_id.property_valuation_price_type.id
pricetype=self.pool.get('product.price.type').browse(cr,uid,price_type_id)
price_type_id = self.pool.get('res.users').browse(cr,uid,uid).company_id.property_valuation_price_type.id
pricetype = self.pool.get('product.price.type').browse(cr, uid, price_type_id)
for r in result:
c = (context or {}).copy()
c['location'] = id
product = self.pool.get('product.product').read(cr, uid, r['product_id'], [field_to_read], context=c)
# Compute the amount_unit in right currency
context['currency_id']=self.pool.get('res.users').browse(cr,uid,uid).company_id.currency_id.id
amount_unit=self.pool.get('product.product').browse(cr,uid,r['product_id']).price_get(pricetype.field, context)[r['product_id']]
context['currency_id'] = self.pool.get('res.users').browse(cr,uid,uid).company_id.currency_id.id
amount_unit = self.pool.get('product.product').browse(cr,uid,r['product_id']).price_get(pricetype.field, context)[r['product_id']]
final_value += (product[field_to_read] * amount_unit)
return final_value
def _product_value(self, cr, uid, ids, field_names, arg, context={}):
""" Calculates real and virtual stock value of a product.
@param field_names: Name of field
@return: Dictionary of values
"""
result = {}
for id in ids:
result[id] = {}.fromkeys(field_names, 0.0)
@@ -199,6 +213,12 @@ class stock_location(osv.osv):
}
def chained_location_get(self, cr, uid, location, partner=None, product=None, context={}):
""" Finds chained location
@param location: Location id
@param partner: Partner id
@param product: Product id
@return: List of values
"""
result = None
if location.chained_location_type == 'customer':
if partner:
@@ -210,6 +230,11 @@ class stock_location(osv.osv):
return result
def picking_type_get(self, cr, uid, from_location, to_location, context={}):
""" Gets type of picking.
@param from_location: Source location
@param to_location: Destination location
@return: Location type
"""
result = 'internal'
if (from_location.usage=='internal') and (to_location and to_location.usage in ('customer', 'supplier')):
result = 'delivery'
@@ -224,13 +249,18 @@ class stock_location(osv.osv):
def _product_get_report(self, cr, uid, ids, product_ids=False,
context=None, recursive=False):
""" Finds the product quantity and price for particular location.
@param product_ids: Ids of product
@param recursive: True or False
@return: Dictionary of values
"""
if context is None:
context = {}
product_obj = self.pool.get('product.product')
# Take the user company and pricetype
price_type_id=self.pool.get('res.users').browse(cr,uid,uid).company_id.property_valuation_price_type.id
pricetype=self.pool.get('product.price.type').browse(cr,uid,price_type_id)
context['currency_id']=self.pool.get('res.users').browse(cr,uid,uid).company_id.currency_id.id
price_type_id = self.pool.get('res.users').browse(cr, uid, uid).company_id.property_valuation_price_type.id
pricetype = self.pool.get('product.price.type').browse(cr, uid, price_type_id)
context['currency_id'] = self.pool.get('res.users').browse(cr, uid, uid).company_id.currency_id.id
if not product_ids:
product_ids = product_obj.search(cr, uid, [])
@@ -265,7 +295,7 @@ class stock_location(osv.osv):
# Compute based on pricetype
# Choose the right filed standard_price to read
amount_unit=product.price_get(pricetype.field, context)[product.id]
amount_unit = product.price_get(pricetype.field, context)[product.id]
price = qty[product_id] * amount_unit
# price = qty[product_id] * product.standard_price
@@ -283,7 +313,14 @@ class stock_location(osv.osv):
result['total_price'] = total_price
return result
def _product_get_multi_location(self, cr, uid, ids, product_ids=False, context={}, states=['done'], what=('in', 'out')):
def _product_get_multi_location(self, cr, uid, ids, product_ids=False, context={},
states=['done'], what=('in', 'out')):
"""
@param product_ids: Ids of product
@param states: List of states
@param what: Tuple of
@return:
"""
product_obj = self.pool.get('product.product')
context.update({
'states': states,
@@ -293,6 +330,11 @@ class stock_location(osv.osv):
return product_obj.get_product_available(cr, uid, product_ids, context=context)
def _product_get(self, cr, uid, id, product_ids=False, context={}, states=['done']):
"""
@param product_ids:
@param states:
@return:
"""
ids = id and [id] or []
return self._product_get_multi_location(cr, uid, ids, product_ids, context, states)
@@ -313,6 +355,11 @@ class stock_location(osv.osv):
# [ (tracking_id, product_qty, location_id) ]
#
def _product_reserve(self, cr, uid, ids, product_id, product_qty, context={}):
"""
@param product_id: Id of product
@param product_qty: Quantity of product
@return: List of Values or False
"""
result = []
amount = 0.0
for id in self.search(cr, uid, [('location_id', 'child_of', ids)]):
@@ -352,6 +399,10 @@ class stock_tracking(osv.osv):
_description = "Stock Tracking Lots"
def get_create_tracking_lot(self, cr, uid, ids, tracking_lot):
"""
@param tracking_lot: Name of tracking lot
@return:
"""
tracking_lot_list = self.search(cr, uid, [('name', '=', tracking_lot)],
limit=1)
if tracking_lot_list:
@@ -382,6 +433,7 @@ class stock_tracking(osv.osv):
'move_ids': fields.one2many('stock.move', 'tracking_id', 'Moves Tracked'),
'date': fields.datetime('Created Date', required=True),
}
_defaults = {
'active': lambda *a: 1,
'name': make_sscc,
@@ -417,6 +469,12 @@ class stock_picking(osv.osv):
_description = "Picking List"
def _set_maximum_date(self, cr, uid, ids, name, value, arg, context):
""" Calculates planned date if it is greater than 'value'.
@param name: Name of field
@param value: Value of field
@param arg: User defined argument
@return: True or False
"""
if not value:
return False
if isinstance(ids, (int, long)):
@@ -433,6 +491,12 @@ class stock_picking(osv.osv):
return True
def _set_minimum_date(self, cr, uid, ids, name, value, arg, context):
""" Calculates planned date if it is less than 'value'.
@param name: Name of field
@param value: Value of field
@param arg: User defined argument
@return: True or False
"""
if not value:
return False
if isinstance(ids, (int, long)):
@@ -448,6 +512,9 @@ class stock_picking(osv.osv):
return True
def get_min_max_date(self, cr, uid, ids, field_name, arg, context={}):
""" Finds minimum and maximum dates for picking.
@return: Dictionary of values
"""
res = {}
for id in ids:
res[id] = {'min_date': False, 'max_date': False}
@@ -470,7 +537,8 @@ class stock_picking(osv.osv):
def create(self, cr, user, vals, context=None):
if ('name' not in vals) or (vals.get('name')=='/'):
vals['name'] = self.pool.get('ir.sequence').get(cr, user, 'stock.picking')
seq_obj_name = 'stock.picking.' + vals['type']
vals['name'] = self.pool.get('ir.sequence').get(cr, user, seq_obj_name)
type_list = {
'out':_('Packing List'),
'in':_('Reception'),
@@ -539,8 +607,11 @@ class stock_picking(osv.osv):
if default is None:
default = {}
default = default.copy()
if not default.get('name',False):
default['name'] = self.pool.get('ir.sequence').get(cr, uid, 'stock.picking')
picking_obj = self.browse(cr, uid, [id], context)[0]
if ('name' not in default) or (picking_obj.name=='/'):
seq_obj_name = 'stock.picking.' + picking_obj.type
default['name'] = self.pool.get('ir.sequence').get(cr, uid, seq_obj_name)
return super(stock_picking, self).copy(cr, uid, id, default, context)
def onchange_partner_in(self, cr, uid, context, partner_id=None):
@@ -550,6 +621,9 @@ class stock_picking(osv.osv):
return moves
def action_confirm(self, cr, uid, ids, context={}):
""" Confirms picking.
@return: True
"""
self.write(cr, uid, ids, {'state': 'confirmed'})
todo = []
for picking in self.browse(cr, uid, ids, context=context):
@@ -573,6 +647,9 @@ class stock_picking(osv.osv):
# return True
def action_assign(self, cr, uid, ids, *args):
""" Changes state of picking to available if all moves are confirmed.
@return: True
"""
for pick in self.browse(cr, uid, ids):
move_ids = [x.id for x in pick.move_lines if x.state == 'confirmed']
if not move_ids:
@@ -581,6 +658,9 @@ class stock_picking(osv.osv):
return True
def force_assign(self, cr, uid, ids, *args):
""" Changes state of picking to available if moves are confirmed or waiting.
@return: True
"""
wf_service = netsvc.LocalService("workflow")
for pick in self.browse(cr, uid, ids):
move_ids = [x.id for x in pick.move_lines if x.state in ['confirmed','waiting']]
@@ -590,6 +670,9 @@ class stock_picking(osv.osv):
return True
def draft_force_assign(self, cr, uid, ids, *args):
""" Confirms picking directly from draft state.
@return: True
"""
wf_service = netsvc.LocalService("workflow")
for pick in self.browse(cr, uid, ids):
wf_service.trg_validate(uid, 'stock.picking', pick.id,
@@ -600,6 +683,9 @@ class stock_picking(osv.osv):
return True
def draft_validate(self, cr, uid, ids, *args):
""" Validates picking directly from draft state.
@return: True
"""
wf_service = netsvc.LocalService("workflow")
self.draft_force_assign(cr, uid, ids)
for pick in self.browse(cr, uid, ids):
@@ -612,6 +698,9 @@ class stock_picking(osv.osv):
return True
def cancel_assign(self, cr, uid, ids, *args):
""" Cancels picking and moves.
@return: True
"""
wf_service = netsvc.LocalService("workflow")
for pick in self.browse(cr, uid, ids):
move_ids = [x.id for x in pick.move_lines]
@@ -620,6 +709,9 @@ class stock_picking(osv.osv):
return True
def action_assign_wkf(self, cr, uid, ids, context=None):
""" Changes picking state to assigned.
@return: True
"""
for pick in self.browse(cr, uid, ids, context=context):
type_list = {
'out':'Packing List',
@@ -633,6 +725,9 @@ class stock_picking(osv.osv):
return True
def test_finnished(self, cr, uid, ids):
""" Tests whether the move is in done or cancel state or not.
@return: True or False
"""
move_ids = self.pool.get('stock.move').search(cr, uid, [('picking_id', 'in', ids)])
for move in self.pool.get('stock.move').browse(cr, uid, move_ids):
if move.state not in ('done', 'cancel'):
@@ -643,18 +738,24 @@ class stock_picking(osv.osv):
return True
def test_assigned(self, cr, uid, ids):
""" Tests whether the move is in assigned state or not.
@return: True or False
"""
ok = True
for pick in self.browse(cr, uid, ids):
mt = pick.move_type
for move in pick.move_lines:
if (move.state in ('confirmed', 'draft')) and (mt=='one'):
if (move.state in ('confirmed', 'draft')) and (mt == 'one'):
return False
if (mt=='direct') and (move.state=='assigned') and (move.product_qty):
if (mt == 'direct') and (move.state == 'assigned') and (move.product_qty):
return True
ok = ok and (move.state in ('cancel', 'done', 'assigned'))
return ok
def action_cancel(self, cr, uid, ids, context={}):
""" Changes picking state to cancel.
@return: True
"""
for pick in self.browse(cr, uid, ids):
ids2 = [move.id for move in pick.move_lines]
self.pool.get('stock.move').action_cancel(cr, uid, ids2, context)
@@ -665,10 +766,16 @@ class stock_picking(osv.osv):
# TODO: change and create a move if not parents
#
def action_done(self, cr, uid, ids, context=None):
""" Changes picking state to done.
@return: True
"""
self.write(cr, uid, ids, {'state': 'done', 'date_done': time.strftime('%Y-%m-%d %H:%M:%S')})
return True
def action_move(self, cr, uid, ids, context={}):
""" Changes move state to assigned.
@return: True
"""
for pick in self.browse(cr, uid, ids):
todo = []
for move in pick.move_lines:
@@ -684,13 +791,17 @@ class stock_picking(osv.osv):
return False
def _get_payment_term(self, cr, uid, picking):
'''Return {'contact': address, 'invoice': address} for invoice'''
""" Gets payment term from partner.
@return: Payment term
"""
partner_obj = self.pool.get('res.partner')
partner = picking.address_id.partner_id
return partner.property_payment_term and partner.property_payment_term.id or False
def _get_address_invoice(self, cr, uid, picking):
'''Return {'contact': address, 'invoice': address} for invoice'''
""" Gets invoice address of a partner
@return {'contact': address, 'invoice': address} for invoice
"""
partner_obj = self.pool.get('res.partner')
partner = picking.address_id.partner_id
@@ -698,11 +809,17 @@ class stock_picking(osv.osv):
['contact', 'invoice'])
def _get_comment_invoice(self, cr, uid, picking):
'''Return comment string for invoice'''
"""
@return: comment string for invoice
"""
return picking.note or ''
def _get_price_unit_invoice(self, cr, uid, move_line, type, context=None):
'''Return the price unit for the move line'''
""" Gets price unit for invoice
@param move_line: Stock move lines
@param type: Type of invoice
@return: The price unit for the move line
"""
if context is None:
context = {}
@@ -722,7 +839,11 @@ class stock_picking(osv.osv):
return 0.0
def _get_taxes_invoice(self, cr, uid, move_line, type):
'''Return taxes ids for the move line'''
""" Gets taxes on invoice
@param move_line: Stock move lines
@param type: Type of invoice
@return: Taxes Ids for the move line
"""
if type in ('in_invoice', 'in_refund'):
taxes = move_line.product_id.supplier_taxes_id
else:
@@ -751,7 +872,12 @@ class stock_picking(osv.osv):
def action_invoice_create(self, cr, uid, ids, journal_id=False,
group=False, type='out_invoice', context=None):
'''Return ids of created invoices for the pickings'''
""" Creates invoice based on the invoice state selected for picking.
@param journal_id: Id of journal
@param group: Whether to create a group invoice or not
@param type: Type invoice to be created
@return: Ids of created invoices for the pickings
"""
if context is None:
context = {}
@@ -881,6 +1007,9 @@ class stock_picking(osv.osv):
return res
def test_cancel(self, cr, uid, ids, context={}):
""" Test whether the move lines are canceled or not.
@return: True or False
"""
for pick in self.browse(cr, uid, ids, context=context):
if not pick.move_lines:
return False
@@ -910,11 +1039,14 @@ class stock_picking(osv.osv):
return super(stock_picking, self).unlink(cr, uid, ids, context=context)
def do_partial(self, cr, uid, ids, partial_datas, context={}):
"""
@ partial_datas : dict. contain details of partial picking
like partner_id, address_id, delivery_date, delivery moves with product_id, product_qty, uom
""" Makes partial picking and moves done.
@param partial_datas : Dictionary containing details of partial picking
like partner_id, address_id, delivery_date,
delivery moves with product_id, product_qty, uom
@return: Dictionary of values
"""
res = {}
move_obj = self.pool.get('stock.move')
delivery_obj = self.pool.get('stock.delivery')
product_obj = self.pool.get('product.product')
@@ -1076,6 +1208,9 @@ class stock_production_lot(osv.osv):
_description = 'Production lot'
def _get_stock(self, cr, uid, ids, field_name, arg, context={}):
""" Gets stock of products for locations
@return: Dictionary of values
"""
if 'location_id' not in context:
locations = self.pool.get('stock.location').search(cr, uid, [('usage', '=', 'internal')], context=context)
else:
@@ -1097,6 +1232,9 @@ class stock_production_lot(osv.osv):
return res
def _stock_search(self, cr, uid, obj, name, args, context):
""" Searches Ids of products
@return: Ids of locations
"""
locations = self.pool.get('stock.location').search(cr, uid, [('usage', '=', 'internal')])
cr.execute('''select
prodlot_id,
@@ -1120,6 +1258,7 @@ class stock_production_lot(osv.osv):
'revisions': fields.one2many('stock.production.lot.revision', 'lot_id', 'Revisions'),
'company_id': fields.many2one('res.company','Company',select=1),
}
_defaults = {
'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'name': lambda x, y, z, c: x.pool.get('ir.sequence').get(y, z, 'stock.lot.serial'),
@@ -1134,6 +1273,7 @@ stock_production_lot()
class stock_production_lot_revision(osv.osv):
_name = 'stock.production.lot.revision'
_description = 'Production lot revisions'
_columns = {
'name': fields.char('Revision Name', size=64, required=True),
'description': fields.text('Description'),
@@ -1153,10 +1293,11 @@ stock_production_lot_revision()
class stock_delivery(osv.osv):
""" Tracability of partialdeliveries """
""" Traceability of partial deliveries """
_name = "stock.delivery"
_description = "Delivery"
_columns = {
'name': fields.char('Name', size=60, required=True),
'date': fields.datetime('Date', required=True),
@@ -1191,6 +1332,9 @@ class stock_move(osv.osv):
return res
def _check_tracking(self, cr, uid, ids):
""" Checks if production lot is assigned to stock move or not.
@return: True or False
"""
for move in self.browse(cr, uid, ids):
if not move.prodlot_id and \
(move.state == 'done' and \
@@ -1204,6 +1348,9 @@ class stock_move(osv.osv):
return True
def _check_product_lot(self, cr, uid, ids):
""" Checks whether move is done or not and production lot is assigned to that move.
@return: True or False
"""
for move in self.browse(cr, uid, ids):
if move.prodlot_id and move.state == 'done' and (move.prodlot_id.product_id.id != move.product_id.id):
return False
@@ -1263,6 +1410,9 @@ class stock_move(osv.osv):
['prodlot_id'])]
def _default_location_destination(self, cr, uid, context={}):
""" Gets default address of partner for destination location
@return: Address id or False
"""
if context.get('move_line', []):
if context['move_line'][0]:
if isinstance(context['move_line'][0], (tuple, list)):
@@ -1275,6 +1425,9 @@ class stock_move(osv.osv):
return False
def _default_location_source(self, cr, uid, context={}):
""" Gets default address of partner for source location
@return: Address id or False
"""
if context.get('move_line', []):
try:
return context['move_line'][0][2]['location_id']
@@ -1325,7 +1478,15 @@ class stock_move(osv.osv):
cursor.commit()
return res
def onchange_lot_id(self, cr, uid, ids, prodlot_id=False, product_qty=False, loc_id=False, product_id=False, context=None):
def onchange_lot_id(self, cr, uid, ids, prodlot_id=False, product_qty=False,
loc_id=False, product_id=False, context=None):
""" On change of production lot gives a warning message.
@param prodlot_id: Changed production lot id
@param product_qty: Quantity of product
@param loc_id: Location id
@param product_id: Product id
@return: Warning message
"""
if not prodlot_id or not loc_id:
return {}
ctx = context and context.copy() or {}
@@ -1340,7 +1501,15 @@ class stock_move(osv.osv):
}
return {'warning': warning}
def onchange_quantity(self, cr, uid, ids, product_id, product_qty, product_uom, product_uos):
def onchange_quantity(self, cr, uid, ids, product_id, product_qty,
product_uom, product_uos):
""" On change of product quantity finds UoM and UoS quantities
@param product_id: Product id
@param product_qty: Changed Quantity of product
@param product_uom: Unit of measure of product
@param product_uos: Unit of sale of product
@return: Dictionary of values
"""
result = {
'product_uos_qty': 0.00
}
@@ -1358,7 +1527,15 @@ class stock_move(osv.osv):
return {'value': result}
def onchange_product_id(self, cr, uid, ids, prod_id=False, loc_id=False, loc_dest_id=False, address_id=False):
def onchange_product_id(self, cr, uid, ids, prod_id=False, loc_id=False,
loc_dest_id=False, address_id=False):
""" On change of product id, if finds UoM, UoS, quantity and UoS quantity.
@param prod_id: Changed Product id
@param loc_id: Source location id
@param loc_id: Destination location id
@param address_id: Address id of partner
@return: Dictionary of values
"""
if not prod_id:
return {}
lang = False
@@ -1385,6 +1562,10 @@ class stock_move(osv.osv):
return {'value': result}
def _chain_compute(self, cr, uid, moves, context={}):
""" Finds whether the location has chained location type or not.
@param moves: Stock moves
@return: Dictionary containing destination location with chained location type.
"""
result = {}
for m in moves:
dest = self.pool.get('stock.location').chained_location_get(
@@ -1407,6 +1588,9 @@ class stock_move(osv.osv):
return result
def action_confirm(self, cr, uid, ids, context={}):
""" Confirms stock move.
@return: List of ids.
"""
# ids = map(lambda m: m.id, moves)
moves = self.browse(cr, uid, ids)
self.write(cr, uid, ids, {'state': 'confirmed'})
@@ -1454,6 +1638,9 @@ class stock_move(osv.osv):
return []
def action_assign(self, cr, uid, ids, *args):
""" Changes state to confirmed or waiting.
@return: List of values
"""
todo = []
for move in self.browse(cr, uid, ids):
if move.state in ('confirmed', 'waiting'):
@@ -1462,10 +1649,16 @@ class stock_move(osv.osv):
return res
def force_assign(self, cr, uid, ids, context={}):
""" Changes the state to assigned.
@return: True
"""
self.write(cr, uid, ids, {'state': 'assigned'})
return True
def cancel_assign(self, cr, uid, ids, context={}):
""" Changes the state to confirmed.
@return: True
"""
self.write(cr, uid, ids, {'state': 'confirmed'})
return True
@@ -1473,6 +1666,9 @@ class stock_move(osv.osv):
# Duplicate stock.move
#
def check_assign(self, cr, uid, ids, context={}):
""" Checks the product type and accordingly writes the state.
@return: No. of moves done
"""
done = []
count = 0
pickings = {}
@@ -1514,6 +1710,9 @@ class stock_move(osv.osv):
# Cancel move => cancel others move and pickings
#
def action_cancel(self, cr, uid, ids, context={}):
""" Cancels the moves and if all moves are cancelled it cancels the picking.
@return: True
"""
if not len(ids):
return True
pickings = {}
@@ -1539,6 +1738,9 @@ class stock_move(osv.osv):
return True
def action_done(self, cr, uid, ids, context={}):
""" Makes the move done and if all moves are done, it will finish the picking.
@return:
"""
track_flag = False
picking_ids = []
product_uom_obj = self.pool.get('product.uom')
@@ -1666,7 +1868,7 @@ class stock_move(osv.osv):
for id in ids:
wf_service.trg_trigger(uid, 'stock.move', id, cr)
return True
def unlink(self, cr, uid, ids, context=None):
if context is None:
context = {}
@@ -1678,6 +1880,9 @@ class stock_move(osv.osv):
cr, uid, ids, context=context)
def _create_lot(self, cr, uid, ids, product_id, prefix=False):
""" Creates production lot
@return: Production lot id
"""
prodlot_obj = self.pool.get('stock.production.lot')
ir_sequence_obj = self.pool.get('ir.sequence')
sequence = ir_sequence_obj.get(cr, uid, 'stock.lot.serial')
@@ -1693,18 +1898,15 @@ class stock_move(osv.osv):
def action_scrap(self, cr, uid, ids, quantity, location_id, context=None):
'''
Move the scrap/damaged product into scrap location
@ param cr: the database cursor
@ param uid: the user id
@ param ids: ids of stock move object to be scraped
@ param quantity : specify scrap qty
@ param location_id : specify scrap location
@ param context: context arguments
@ return: Scraped lines
'''
""" Move the scrap/damaged product into scrap location
@param cr: the database cursor
@param uid: the user id
@param ids: ids of stock move object to be scraped
@param quantity : specify scrap qty
@param location_id : specify scrap location
@param context: context arguments
@return: Scraped lines
"""
if quantity <= 0:
raise osv.except_osv(_('Warning!'), _('Please provide Proper Quantity !'))
res = []
@@ -1725,19 +1927,16 @@ class stock_move(osv.osv):
return res
def action_split(self, cr, uid, ids, quantity, split_by_qty=1, prefix=False, with_lot=True, context=None):
'''
Split Stock Move lines into production lot which specified split by quantity.
@ param cr: the database cursor
@ param uid: the user id
@ param ids: ids of stock move object to be splited
@ param split_by_qty : specify split by qty
@ param prefix : specify prefix of production lot
@ param with_lot : if true, prodcution lot will assign for split line otherwise not.
@ param context: context arguments
@ return: splited move lines
'''
""" Split Stock Move lines into production lot which specified split by quantity.
@param cr: the database cursor
@param uid: the user id
@param ids: ids of stock move object to be splited
@param split_by_qty : specify split by qty
@param prefix : specify prefix of production lot
@param with_lot : if true, prodcution lot will assign for split line otherwise not.
@param context: context arguments
@return: Splited move lines
"""
if quantity <= 0:
raise osv.except_osv(_('Warning!'), _('Please provide Proper Quantity !'))
@@ -1788,18 +1987,15 @@ class stock_move(osv.osv):
return res
def action_consume(self, cr, uid, ids, quantity, location_id=False, context=None):
'''
Consumed product with specific quatity from specific source location
@ param cr: the database cursor
@ param uid: the user id
@ param ids: ids of stock move object to be consumed
@ param quantity : specify consume quantity
@ param location_id : specify source location
@ param context: context arguments
@ return: Consumed lines
'''
""" Consumed product with specific quatity from specific source location
@param cr: the database cursor
@param uid: the user id
@param ids: ids of stock move object to be consumed
@param quantity : specify consume quantity
@param location_id : specify source location
@param context: context arguments
@return: Consumed lines
"""
if context is None:
context = {}
@@ -1859,9 +2055,10 @@ class stock_move(osv.osv):
return res
def do_partial(self, cr, uid, ids, partial_datas, context={}):
"""
@ partial_datas : dict. contain details of partial picking
like partner_id, address_id, delivery_date, delivery moves with product_id, product_qty, uom
""" Makes partial pickings and moves done.
@param partial_datas: Dictionary containing details of partial picking
like partner_id, address_id, delivery_date, delivery
moves with product_id, product_qty, uom
"""
res = {}
picking_obj = self.pool.get('stock.picking')
@@ -2015,10 +2212,17 @@ class stock_inventory(osv.osv):
def _inventory_line_hook(self, cr, uid, inventory_line, move_vals):
'''Creates a stock move from an inventory line'''
""" Creates a stock move from an inventory line
@param inventory_line:
@param move_vals:
@return:
"""
return self.pool.get('stock.move').create(cr, uid, move_vals)
def action_done(self, cr, uid, ids, context=None):
""" Finishes the inventory and writes its finished date
@return: True
"""
for inv in self.browse(cr, uid, ids):
move_ids = []
move_line = []
@@ -2065,12 +2269,18 @@ class stock_inventory(osv.osv):
return True
def action_cancel(self, cr, uid, ids, context={}):
""" Cancels the stock move and change inventory state to draft.
@return: True
"""
for inv in self.browse(cr, uid, ids):
self.pool.get('stock.move').action_cancel(cr, uid, [x.id for x in inv.move_ids], context)
self.write(cr, uid, [inv.id], {'state': 'draft'})
return True
def action_cancel_inventary(self, cr, uid, ids, context={}):
""" Cancels both stock move and inventory
@return: True
"""
for inv in self.browse(cr,uid,ids):
self.pool.get('stock.move').action_cancel(cr, uid, [x.id for x in inv.move_ids], context)
self.write(cr, uid, [inv.id], {'state':'cancel'})
@@ -2094,6 +2304,12 @@ class stock_inventory_line(osv.osv):
}
def on_change_product_id(self, cr, uid, ids, location_id, product, uom=False):
""" Changes UoM and name if product_id changes.
@param location_id: Location id
@param product: Changed product_id
@param uom: UoM product
@return: Dictionary of changed values
"""
if not product:
return {}
if not uom:
@@ -34,17 +34,13 @@ class change_standard_price(osv.osv_memory):
}
def default_get(self, cr, uid, fields, context):
"""
To get default values for the object.
""" To get default values for the object.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for which we want default values
@param context: A standard dictionary
@return: A dictionary which of fields with values.
"""
product_pool = self.pool.get('product.product')
product_obj = product_pool.browse(cr, uid, context.get('active_id', False))
@@ -68,6 +64,16 @@ class change_standard_price(osv.osv_memory):
return res
def onchange_price(self, cr, uid, ids, new_price, context = {}):
""" Sets stock input and output account according to the difference
of old price and new price.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: List of IDs selected
@param new_price: Changed price
@param context: A standard dictionary
@return: Dictionary of values
"""
product_obj = self.pool.get('product.product').browse(cr, uid, context.get('active_id', False))
price = product_obj.standard_price
diff = price - new_price
@@ -77,18 +83,14 @@ class change_standard_price(osv.osv_memory):
return {'value' : {'enable_stock_in_out_acc':False}}
def change_price(self, cr, uid, ids, context):
"""
Changes the Standard Price of Product.
And creates an account move accordingly.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: List of IDs selected
@param context: A standard dictionary
@return:
""" Changes the Standard Price of Product.
And creates an account move accordingly.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: List of IDs selected
@param context: A standard dictionary
@return:
"""
rec_id = context and context.get('active_id', False)
assert rec_id, _('Active ID is not set in Context')
+9 -13
View File
@@ -34,21 +34,17 @@ class stock_fill_inventory(osv.osv_memory):
_description = "Fill Inventory"
_columns = {
'location_id': fields.many2one('stock.location', 'Location', required=True),
'recursive': fields.boolean("Include all childs for the location"),
}
'recursive': fields.boolean("Include all children for the location"),
}
def fill_inventory(self, cr, uid, ids, context):
"""
To fill stock inventory according to products available in the selected locations..
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param context: A standard dictionary
@return:
""" To fill stock inventory according to products available in the selected locations.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param context: A standard dictionary
@return:
"""
inventory_line_obj = self.pool.get('stock.inventory.line')
location_obj = self.pool.get('stock.location')
@@ -35,17 +35,13 @@ class stock_inventory_line_split(osv.osv_memory):
def default_get(self, cr, uid, fields, context):
"""
To check the availability of production lot.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for which we want default values
@param context: A standard dictionary
@return: A dictionary which of fields with values.
""" To check the availability of production lot.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for which we want default values
@param context: A standard dictionary
@return: A dictionary which of fields with values.
"""
record_id = context and context.get('active_id',False)
res = super(stock_inventory_line_split, self).default_get(cr, uid, fields, context=context)
@@ -55,18 +51,14 @@ class stock_inventory_line_split(osv.osv_memory):
return res
def split(self, cr, uid, ids, line_ids, context=None):
"""
To split stock inventory lines according to production lot
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param line_ids: the ID or list of IDs of inventory lines we want to split
@param context: A standard dictionary
@return:
""" To split stock inventory lines according to production lot.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param line_ids: the ID or list of IDs of inventory lines we want to split
@param context: A standard dictionary
@return:
"""
prodlot_obj = self.pool.get('stock.production.lot')
ir_sequence_obj = self.pool.get('ir.sequence')
+7 -14
View File
@@ -31,22 +31,15 @@ import wizard
class stock_inventory_merge(osv.osv_memory):
_name = "stock.inventory.merge"
_description = "Merge Inventory"
_columns = {
}
def do_merge(self, cr, uid, ids, context):
"""
To merge selected Inventories.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: List of IDs selected
@param context: A standard dictionary
@return:
""" To merge selected Inventories.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: List of IDs selected
@param context: A standard dictionary
@return:
"""
invent_obj = self.pool.get('stock.inventory')
invent_line_obj = self.pool.get('stock.inventory.line')
@@ -32,22 +32,19 @@ import wizard
class inventory_set_stock_zero(osv.osv_memory):
_name = "stock.inventory.set.stock.zero"
_description = "Set Stock to 0"
_columns = {
'location_id': fields.many2one('stock.location', 'Location', required=True),
}
}
def do_merge(self, cr, uid, ids, context):
"""
To set stock to Zero
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param context: A standard dictionary
@return:
""" To set stock to Zero
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param context: A standard dictionary
@return:
"""
invent_obj = pooler.get_pool(cr.dbname).get('stock.inventory')
invent_line_obj = pooler.get_pool(cr.dbname).get('stock.inventory.line')
+16 -24
View File
@@ -39,20 +39,16 @@ class stock_invoice_onshipping(osv.osv_memory):
('out_refund', 'Customer Refund'),
('in_refund', 'Supplier Refund')] , 'Type', required=True),
'invoice_date': fields.date('Invoiced date'),
}
}
def _get_type(self, cr, uid, context=None):
"""
To get invoice type
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param context: A standard dictionary
@return: invoice type
""" To get invoice type.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: The ID or list of IDs if we want more than one
@param context: A standard dictionary
@return: Invoice type
"""
if context is None:
context = {}
@@ -80,20 +76,16 @@ class stock_invoice_onshipping(osv.osv_memory):
_defaults = {
'type': _get_type,
}
}
def create_invoice(self, cr, uid, ids, context):
"""
To create invoice
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param context: A standard dictionary
@return: invoice ids
""" To create invoice
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param context: A standard dictionary
@return: Invoice ids
"""
result = []
picking_obj = self.pool.get('stock.picking')
@@ -30,16 +30,13 @@ class stock_location_product(osv.osv_memory):
}
def action_open_window(self, cr, uid, ids, context):
"""
To open location wise product information specific to given duration
""" To open location wise product information specific to given duration
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param ids: An ID or list of IDs if we want more than one
@param context: A standard dictionary
@return: invoice type
@return: Invoice type
"""
mod_obj = self.pool.get('ir.model.data')
for location_obj in self.read(cr, uid, ids, ['from_date', 'to_date']):
+61 -91
View File
@@ -29,24 +29,20 @@ class stock_move_track(osv.osv_memory):
_columns = {
'tracking_prefix': fields.char('Tracking prefix', size=64),
'quantity': fields.float("Quantity per lot")
}
}
_defaults = {
'quantity': lambda *x: 1
}
}
def track_lines(self, cr, uid, ids, context={}):
"""
To track stock moves lines
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param context: A standard dictionary
@return:
""" To track stock moves lines
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: An ID or list of IDs if we want more than one
@param context: A standard dictionary
@return:
"""
datas = self.read(cr, uid, ids)[0]
move_obj = self.pool.get('stock.move')
@@ -67,17 +63,13 @@ class stock_move_consume(osv.osv_memory):
}
def default_get(self, cr, uid, fields, context=None):
"""
Get default values
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for default value
@param context: A standard dictionary
@return: default values of fields
""" Get default values
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for default value
@param context: A standard dictionary
@return: default values of fields
"""
res = super(stock_move_consume, self).default_get(cr, uid, fields, context=context)
move = self.pool.get('stock.move').browse(cr, uid, context['active_id'], context=context)
@@ -93,17 +85,13 @@ class stock_move_consume(osv.osv_memory):
return res
def do_move_consume(self, cr, uid, ids, context={}):
"""
To move consumed products
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param context: A standard dictionary
@return:
""" To move consumed products
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param context: A standard dictionary
@return:
"""
move_obj = self.pool.get('stock.move')
move_ids = context['active_ids']
@@ -126,17 +114,13 @@ class stock_move_scrap(osv.osv_memory):
}
def default_get(self, cr, uid, fields, context=None):
"""
Get default values
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for default value
@param context: A standard dictionary
@return: default values of fields
""" Get default values
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for default value
@param context: A standard dictionary
@return: default values of fields
"""
res = super(stock_move_consume, self).default_get(cr, uid, fields, context=context)
move = self.pool.get('stock.move').browse(cr, uid, context['active_id'], context=context)
@@ -158,17 +142,13 @@ class stock_move_scrap(osv.osv_memory):
return res
def move_scrap(self, cr, uid, ids, context={}):
"""
To move scraped products
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param context: A standard dictionary
@return:
""" To move scraped products
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param context: A standard dictionary
@return:
"""
move_obj = self.pool.get('stock.move')
move_ids = context['active_ids']
@@ -186,17 +166,13 @@ class split_in_production_lot(osv.osv_memory):
_description = "Split in Production lots"
def default_get(self, cr, uid, fields, context=None):
"""
Get default values
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for default value
@param context: A standard dictionary
@return: default values of fields
""" Get default values
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for default value
@param context: A standard dictionary
@return: Default values of fields
"""
res = super(split_in_production_lot, self).default_get(cr, uid, fields, context=context)
@@ -209,35 +185,28 @@ class split_in_production_lot(osv.osv_memory):
'product_id': fields.many2one('product.product', 'Product', required=True, select=True),
'line_ids': fields.one2many('stock.move.split.lines', 'lot_id', 'Lots Number')
}
def split_lot(self, cr, uid, ids, context=None):
"""
To split a lot
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param context: A standard dictionary
@return:
""" To split a lot
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: An ID or list of IDs if we want more than one
@param context: A standard dictionary
@return:
"""
self.split(cr, uid, ids, context.get('active_ids'), context=context)
return {}
def split(self, cr, uid, ids, move_ids, context=None):
"""
To split stock moves into production lot
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param move_ids: the ID or list of IDs of stock move we want to split
@param context: A standard dictionary
@return:
""" To split stock moves into production lot
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: the ID or list of IDs if we want more than one
@param move_ids: the ID or list of IDs of stock move we want to split
@param context: A standard dictionary
@return:
"""
prodlot_obj = self.pool.get('stock.production.lot')
ir_sequence_obj = self.pool.get('ir.sequence')
@@ -306,6 +275,7 @@ class stock_move_split_lines(osv.osv_memory):
'lot_id': fields.many2one('stock.move.split', 'Lot'),
'action': fields.selection([('split','Split'),('keepinone','Keep in one lot')],'Action'),
}
_defaults = {
'quantity': lambda *x: 1,
'action' : lambda *x: 'split',
+21 -16
View File
@@ -30,10 +30,9 @@ class stock_partial_move(osv.osv_memory):
_name = "stock.partial.move"
_description = "Partial Move"
_columns = {
'date': fields.datetime('Date', required=True),
'partner_id': fields.many2one('res.partner',string="Partner", required=True),
'address_id': fields.many2one('res.partner.address', 'Delivery Address', help="Address where goods are to be delivered", required=True),
'date': fields.datetime('Date', required=True),
'partner_id': fields.many2one('res.partner',string="Partner", required=True),
'address_id': fields.many2one('res.partner.address', 'Delivery Address', help="Address where goods are to be delivered", required=True),
}
def view_init(self, cr, uid, fields_list, context=None):
@@ -140,17 +139,13 @@ class stock_partial_move(osv.osv_memory):
return result
def default_get(self, cr, uid, fields, context=None):
"""
To get default values for the object.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for which we want default values
@param context: A standard dictionary
@return: A dictionary which of fields with values.
""" To get default values for the object.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for which we want default values
@param context: A standard dictionary
@return: A dictionary which of fields with values.
"""
res = super(stock_partial_move, self).default_get(cr, uid, fields, context=context)
@@ -185,7 +180,16 @@ class stock_partial_move(osv.osv_memory):
res['move%s_product_currency'%(m.id)] = currency
return res
def do_partial(self, cr, uid, ids, context):
def do_partial(self, cr, uid, ids, context):
""" Makes partial moves and pickings done.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for which we want default values
@param context: A standard dictionary
@return: A dictionary which of fields with values.
"""
rec_id = context and context.get('active_id', False)
tracking_lot = context.get('tracking_lot', False)
if tracking_lot:
@@ -218,5 +222,6 @@ class stock_partial_move(osv.osv_memory):
return {}
stock_partial_move()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+19 -16
View File
@@ -29,10 +29,9 @@ class stock_partial_picking(osv.osv_memory):
_name = "stock.partial.picking"
_description = "Partial Picking"
_columns = {
'date': fields.datetime('Date', required=True),
'partner_id': fields.many2one('res.partner',string="Partner", required=True),
'address_id': fields.many2one('res.partner.address', 'Delivery Address', help="Address where goods are to be delivered", required=True),
'date': fields.datetime('Date', required=True),
'partner_id': fields.many2one('res.partner',string="Partner", required=True),
'address_id': fields.many2one('res.partner.address', 'Delivery Address', help="Address where goods are to be delivered", required=True),
}
def view_init(self, cr, uid, fields_list, context=None):
@@ -141,17 +140,13 @@ class stock_partial_picking(osv.osv_memory):
return result
def default_get(self, cr, uid, fields, context=None):
"""
To get default values for the object.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for which we want default values
@param context: A standard dictionary
@return: A dictionary which of fields with values.
""" To get default values for the object.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for which we want default values
@param context: A standard dictionary
@return: A dictionary which of fields with values.
"""
res = super(stock_partial_picking, self).default_get(cr, uid, fields, context=context)
@@ -191,7 +186,15 @@ class stock_partial_picking(osv.osv_memory):
res['move%s_product_currency'%(m.id)] = currency
return res
def do_partial(self, cr, uid, ids, context):
def do_partial(self, cr, uid, ids, context):
""" Makes partial moves and pickings done.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param fields: List of fields for which we want default values
@param context: A standard dictionary
@return: A dictionary which of fields with values.
"""
pick_obj = self.pool.get('stock.picking')
picking_ids = context.get('active_ids', False)
partial = self.browse(cr, uid, ids[0], context)
+9 -12
View File
@@ -38,20 +38,17 @@ class stock_replacement(osv.osv_memory):
return {}
def replace_composant(self, cr, uid, ids, context = {}):
"""
to open a new wizard that acknowledge, a replacement task
@return: it returns the replacement acknowledgement form
""" To open a new wizard that acknowledge, a replacement task
@return: It returns the replacement acknowledgement form
"""
return {
'name': False,
'view_type': 'form',
'view_mode': 'form',
'res_model': 'stock.replacement.result',
'type': 'ir.actions.act_window',
'target':'new',
}
'name': False,
'view_type': 'form',
'view_mode': 'form',
'res_model': 'stock.replacement.result',
'type': 'ir.actions.act_window',
'target':'new',
}
stock_replacement()
+4 -8
View File
@@ -26,8 +26,7 @@ class stock_split_move_line(osv.osv_memory):
_description = "Split Moves"
def default_get(self, cr, uid, fields, context):
"""
To get default values for the object.
""" To get default values for the object.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@@ -44,8 +43,7 @@ class stock_split_move_line(osv.osv_memory):
return res
def view_init(self, cr, uid, fields_list, context=None):
"""
Creates view dynamically and adding fields at runtime.
""" Creates view dynamically and adding fields at runtime.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@@ -67,8 +65,7 @@ class stock_split_move_line(osv.osv_memory):
def fields_view_get(self, cr, uid, view_id=None, view_type='form',
context=None, toolbar=False, submenu=False):
"""
Changes the view dynamically
""" Changes the view dynamically
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@@ -94,8 +91,7 @@ class stock_split_move_line(osv.osv_memory):
return res
def split_lines(self, cr, uid, ids, context):
"""
Splits moves in quantity given in the wizard.
""" Splits moves in quantity given in the wizard.
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
+8 -11
View File
@@ -34,18 +34,15 @@ class action_traceability(osv.osv_memory):
_description = "Action traceability "
def action_traceability(self, cr, uid, ids, context={}):
"""
It traces the information of a product
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: List of IDs selected
@param context: A standard dictionary
@return: A dictionary of values
""" It traces the information of a product
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param ids: List of IDs selected
@param context: A standard dictionary
@return: A dictionary of values
"""
type1 = context['type'] or 'move_history_ids'
field = context['field'] or 'tracking_id'
obj = self.pool.get('stock.move')
+22 -16
View File
@@ -31,25 +31,25 @@ class stock_ups(osv.osv_memory):
_description = "Stock ups"
def ups_save(self, cr, uid, ids, context = {}):
return {
'name': False,
'view_type': 'form',
'view_mode': 'form',
'res_model': 'stock.ups.final',
'type': 'ir.actions.act_window',
'target':'new',
}
'name': False,
'view_type': 'form',
'view_mode': 'form',
'res_model': 'stock.ups.final',
'type': 'ir.actions.act_window',
'target':'new',
}
def ups_upload(self, cr, uid, ids, context = {}):
return {
'name': False,
'view_type': 'form',
'view_mode': 'form',
'res_model': 'stock.ups.upload',
'type': 'ir.actions.act_window',
'target':'new',
}
'name': False,
'view_type': 'form',
'view_mode': 'form',
'res_model': 'stock.ups.upload',
'type': 'ir.actions.act_window',
'target':'new',
}
_columns = {
'weight': fields.float('Lot weight', required=True),
}
@@ -64,6 +64,9 @@ class stock_ups_final(osv.osv_memory):
_description = "Stock ups final"
def create_xmlfile(self, cr, uid, ids, context = {}):
""" Creates xml report file.
@return: xml file
"""
report = netsvc._group['report']['report.stock.move.lot.ups_xml']
data['report_type'] = 'raw'
return {'xmlfile' : report.create(uid, context['active_id'], ids, {})}
@@ -79,6 +82,9 @@ class stock_ups_upload(osv.osv_memory):
_description = "Stock ups upload"
def upload_xmlfile(self, cr, uid, ids, context = {}):
""" Uploads xml report file.
@return:
"""
report = netsvc._group['report']['report.stock.move.lot.ups_xml']
data['report_type'] = 'raw'
#FIXME: this seems unfinished
+2 -2
View File
@@ -899,7 +899,7 @@ class stock_planning(osv.osv):
raise osv.except_osv(_('Error !'), _('Incoming Left must be greater than 0 !'))
uom_qty, uom, uos_qty, uos = self._qty_to_standard(cr, uid, obj, context)
user = self.pool.get('res.users').browse(cr, uid, uid, context)
proc_id = self.pool.get('mrp.procurement').create(cr, uid, {
proc_id = self.pool.get('procurement.order').create(cr, uid, {
'company_id' : obj.company_id.id,
'name': _('Manual planning for ') + obj.period_id.name,
'origin': _('MPS(') + str(user.login) +') '+ obj.period_id.name,
@@ -926,7 +926,7 @@ class stock_planning(osv.osv):
}, context=context)
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'mrp.procurement', proc_id, 'button_confirm', cr)
wf_service.trg_validate(uid, 'procurement.order', proc_id, 'button_confirm', cr)
self.calculate_planning(cr, uid, ids, context)
prev_text = obj.history or ""
self.write(cr, uid, ids, {