[IMP] stock,procurement : stat button procurement, ux improvements
This commit is contained in:
@@ -37,6 +37,7 @@ Procurements in exception should be checked manually and can be re-run.
|
||||
'wizard/schedulers_all_view.xml',
|
||||
'procurement_view.xml',
|
||||
'company_view.xml',
|
||||
'product_product_view.xml',
|
||||
],
|
||||
'demo': [],
|
||||
'test': ['test/procurement.yml'],
|
||||
|
||||
@@ -131,6 +131,31 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="procurement_order_action_exceptions" model="ir.actions.act_window">
|
||||
<field name="name">Procurement Exceptions</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">procurement.order</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="context">{'search_default_exceptions':1}</field>
|
||||
<field name="search_view_id" ref="view_procurement_filter"/>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a Procurement order in exception state, or remove the filter on the search bar to display all the procurements.
|
||||
</p>
|
||||
<p>
|
||||
<b>Procurement Orders</b> represent the need for a certain quantity of products, at a given time, in a given location.
|
||||
</p>
|
||||
<p>
|
||||
<b>Sales Orders</b> are one typical source of Procurement Orders (but these are distinct documents).
|
||||
<br/>Depending on the procurement parameters and the product configuration, the procurement engine will attempt to satisfy the need by reserving products from stock, ordering products from a supplier, or passing a manufacturing order, etc...
|
||||
</p>
|
||||
<p>
|
||||
A <b>Procurement Exception</b> occurs when the system cannot find a way to fulfill a procurement. Some exceptions will resolve themselves automatically, but others require manual intervention (those are identified by a specific error message in the chatter).
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="procurement_action" model="ir.actions.act_window">
|
||||
<field name="name">Procurement Orders</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
@@ -156,28 +181,55 @@
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="procurement_exceptions" model="ir.actions.act_window">
|
||||
<field name="name">Procurement Exceptions</field>
|
||||
|
||||
<record id="procurement_order_action_product_template_stat" model="ir.actions.act_window">
|
||||
<field name="name">Procurement Orders</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">procurement.order</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="context">{'search_default_exceptions':1}</field>
|
||||
<field name="search_view_id" ref="view_procurement_filter"/>
|
||||
<field name="context">{'search_default_current':1}</field>
|
||||
<field name="domain">[('product_id.product_tmpl_id.id', '=', active_id)]</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a Procurement Exception, or remove the filter on the search bar to display all the procurements.
|
||||
Click to create a procurement order.
|
||||
</p>
|
||||
<p>
|
||||
<b>Procurement Orders</b> represent the need for a certain quantity of products, at a given time, in a given location.
|
||||
A <b>procurement order</b> is used to record a need for a specific
|
||||
product at a specific location. Procurement orders are usually
|
||||
created automatically from <i>sales orders, pull logistic rules or
|
||||
minimum stock rules.</i>
|
||||
</p>
|
||||
<p>
|
||||
<b>Sales Orders</b> are one typical source of Procurement Orders (but these are distinct documents).
|
||||
<br/>Depending on the procurement parameters and the product configuration, the procurement engine will attempt to satisfy the need by reserving products from stock, ordering products from a supplier, or passing a manufacturing order, etc...
|
||||
When the procurement order is confirmed, it automatically
|
||||
creates the necessary operations to fullfil the need: purchase
|
||||
order proposition, manufacturing order, etc.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="procurement_order_action_product_product_stat" model="ir.actions.act_window">
|
||||
<field name="name">Procurement Orders</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">procurement.order</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="search_view_id" ref="view_procurement_filter"/>
|
||||
<field name="context">{'search_default_current':1, 'default_product_id': active_id}</field>
|
||||
<field name="domain">[('product_id.id', '=', active_id)]</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a procurement order.
|
||||
</p>
|
||||
<p>
|
||||
A <b>Procurement Exception</b> occurs when the system cannot find a way to fulfill a procurement. Some exceptions will resolve themselves automatically, but others require manual intervention (those are identified by a specific error message in the chatter).
|
||||
A <b>procurement order</b> is used to record a need for a specific
|
||||
product at a specific location. Procurement orders are usually
|
||||
created automatically from <i>sales orders, pull logistic rules or
|
||||
minimum stock rules.</i>
|
||||
</p>
|
||||
<p>
|
||||
When the procurement order is confirmed, it automatically
|
||||
creates the necessary operations to fullfil the need: purchase
|
||||
order proposition, manufacturing order, etc.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="product_template_view_form_procurement_button" model="ir.ui.view">
|
||||
<field name="name">product.template.procurement.stat.button</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="product.product_template_only_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='button_box']" position="inside">
|
||||
<button class="oe_stat_button" name="%(procurement.procurement_order_action_product_template_stat)d"
|
||||
icon="fa-truck" string="Procurements" type="action"
|
||||
groups="stock.group_adv_location"
|
||||
attrs="{'invisible':[('type', '=', 'service')]}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_product_view_form_procurement_button" model="ir.ui.view">
|
||||
<field name="name">product.product.procurement.stat.button</field>
|
||||
<field name="model">product.product</field>
|
||||
<field name="inherit_id" ref="product.product_normal_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='button_box']" position="inside">
|
||||
<button class="oe_stat_button" name="%(procurement.procurement_order_action_product_product_stat)d"
|
||||
icon="fa-truck" string="Procurements" type="action"
|
||||
groups="stock.group_adv_location"
|
||||
attrs="{'invisible':[('type', '=', 'service')]}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
+17
-2
@@ -201,6 +201,13 @@ class product_product(osv.osv):
|
||||
res[product.id] = str(product.qty_available) + _(" On Hand")
|
||||
return res
|
||||
|
||||
def _compute_nbr_reordering_rules(self, cr, uid, ids, field_names=None, arg=None, context=None):
|
||||
res = {}
|
||||
product_data = self.pool['stock.warehouse.orderpoint'].read_group(cr, uid, [('product_id', 'in', ids)], ['product_id'], ['product_id'], context=context)
|
||||
for data in product_data:
|
||||
res[data['product_id'][0]] = int(data['product_id_count'])
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'reception_count': fields.function(_stock_move_count, string="Receipt", type='integer', multi='pickings'),
|
||||
'delivery_count': fields.function(_stock_move_count, string="Delivery", type='integer', multi='pickings'),
|
||||
@@ -259,6 +266,7 @@ class product_product(osv.osv):
|
||||
'location_id': fields.dummy(string='Location', relation='stock.location', type='many2one'),
|
||||
'warehouse_id': fields.dummy(string='Warehouse', relation='stock.warehouse', type='many2one'),
|
||||
'orderpoint_ids': fields.one2many('stock.warehouse.orderpoint', 'product_id', 'Minimum Stock Rules'),
|
||||
'nbr_reordering_rules': fields.function(_compute_nbr_reordering_rules, string='Reordering Rules', type='integer'),
|
||||
}
|
||||
|
||||
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
|
||||
@@ -365,7 +373,13 @@ class product_template(osv.osv):
|
||||
res[product.id] = str(product.qty_available) + _(" On Hand")
|
||||
return res
|
||||
|
||||
|
||||
def _compute_nbr_reordering_rules(self, cr, uid, ids, field_names=None, arg=None, context=None):
|
||||
res = dict.fromkeys(ids, 0)
|
||||
product_data = self.pool['stock.warehouse.orderpoint'].read_group(cr, uid, [('product_id.product_tmpl_id', 'in', ids)], ['product_id'], ['product_id'], context=context)
|
||||
for data in product_data:
|
||||
product_tmpl_id = data['__domain'][1][2][0]
|
||||
res[product_tmpl_id] += data['product_id_count']
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'type': fields.selection([('product', 'Stockable Product'), ('consu', 'Consumable'), ('service', 'Service')], 'Product Type', required=True, help="Consumable: Will not imply stock management for this product. \nStockable product: Will imply stock management for this product."),
|
||||
@@ -409,6 +423,8 @@ class product_template(osv.osv):
|
||||
|
||||
'route_ids': fields.many2many('stock.location.route', 'stock_route_product', 'product_id', 'route_id', 'Routes', domain="[('product_selectable', '=', True)]",
|
||||
help="Depending on the modules installed, this will allow you to define the route of the product: whether it will be bought, manufactured, MTO/MTS,..."),
|
||||
'nbr_reordering_rules': fields.function(_compute_nbr_reordering_rules, string='Reordering Rules', type='integer'),
|
||||
'route_from_categ_ids': fields.related('categ_id', 'total_route_ids', type="many2many", relation="stock.location.route", string="Category Routes"),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
@@ -467,7 +483,6 @@ class product_template(osv.osv):
|
||||
result['context'] = "{}"
|
||||
return result
|
||||
|
||||
|
||||
def action_view_stock_moves(self, cr, uid, ids, context=None):
|
||||
products = self._get_products(cr, uid, ids, context=context)
|
||||
result = self._get_act_window_dict(cr, uid, 'stock.act_product_stock_move_open', context=context)
|
||||
|
||||
@@ -148,13 +148,12 @@
|
||||
<field name="product_manager" position="attributes">
|
||||
<attribute name="context">{'default_groups_ref': ['base.group_user', 'base.group_sale_manager', 'stock.group_stock_manager']}</attribute>
|
||||
</field>
|
||||
<page name="procurements" position="after">
|
||||
<page string="Supply Chain" groups="base.group_user" attrs="{'invisible': [('type', '=', 'service')]}">
|
||||
<group>
|
||||
<field name="route_ids" widget="many2many_checkboxes"/>
|
||||
</group>
|
||||
</page>
|
||||
</page>
|
||||
<group name="procurement" position="after" >
|
||||
<group string="Supply Chain Information" attrs="{'invisible': [('type', '=', 'service')]}" groups="base.group_user">
|
||||
<field name="route_ids" widget="many2many_checkboxes"/>
|
||||
<field name="route_from_categ_ids" widget="many2many_tags" readonly="1"/>
|
||||
</group>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -227,10 +226,12 @@
|
||||
type="action" attrs="{'invisible':[('type', '=', 'service')]}" groups="stock.group_locations">
|
||||
<field name="qty_available2" widget="statinfo"/>
|
||||
</button>
|
||||
<button class="oe_stat_button" string="Moves" name= "%(act_product_stock_move_open)d" type="action" attrs="{'invisible':[('type', '=', 'service')]}" groups="stock.group_stock_user" icon="fa-arrows-v"/>
|
||||
<button class="oe_stat_button" name= "%(act_product_stock_move_open)d" type="action" attrs="{'invisible':[('type', '=', 'service')]}" string="Moves" groups="stock.group_stock_user" icon="fa-arrows-v"/>
|
||||
<button class="oe_stat_button" name="%(product_open_orderpoint)d" type="action"
|
||||
attrs="{'invisible':[('type', '=', 'service')]}" icon="fa-refresh" string="Reordering Rules"/>
|
||||
<button class="oe_stat_button" name="action_view_routes" string="Routes" type="object" icon="fa-cogs" attrs="{'invisible':[('type', '=', 'service')]}" groups="stock.group_adv_location" />
|
||||
attrs="{'invisible':[('type', '=', 'service')]}" icon="fa-refresh">
|
||||
<field name="nbr_reordering_rules" widget="statinfo"/>
|
||||
</button>
|
||||
<button class="oe_stat_button" name="action_view_routes" type="object" icon="fa-cogs" attrs="{'invisible':[('type', '=', 'service')]}" groups="stock.group_adv_location" string="Routes"/>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
@@ -247,10 +248,12 @@
|
||||
type="object" attrs="{'invisible':[('type', '=', 'service')]}" groups="stock.group_locations">
|
||||
<field name="qty_available2" widget="statinfo"/>
|
||||
</button>
|
||||
<button class="oe_stat_button" string="Moves" name= "action_view_stock_moves" type="object" attrs="{'invisible':[('type', '=', 'service')]}" groups="stock.group_stock_user" icon="fa-arrows-v"/>
|
||||
<button class="oe_stat_button" name= "action_view_stock_moves" type="object" attrs="{'invisible':[('type', '=', 'service')]}" string="Moves" groups="stock.group_stock_user" icon="fa-arrows-v"/>
|
||||
<button class="oe_stat_button" name="action_view_orderpoints" type="object"
|
||||
attrs="{'invisible':[('type', 'in', ('service','consu'))]}" icon="fa-refresh" string="Reordering Rules"/>
|
||||
<button class="oe_stat_button" name="action_view_routes" string="Routes" type="object" icon="fa-cogs" attrs="{'invisible':[('type', '=', 'service')]}" groups="stock.group_adv_location"/>
|
||||
attrs="{'invisible':[('type', 'in', ('service','consu'))]}" icon="fa-refresh">
|
||||
<field name="nbr_reordering_rules" widget="statinfo"/>
|
||||
</button>
|
||||
<button class="oe_stat_button" name="action_view_routes" type="object" icon="fa-cogs" attrs="{'invisible':[('type', '=', 'service')]}" groups="stock.group_adv_location" string="Routes"/>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -486,7 +486,6 @@
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="action_location_form" model="ir.actions.act_window">
|
||||
<field name="name">Locations</field>
|
||||
@@ -1952,7 +1951,8 @@
|
||||
<menuitem id="menu_stock_sched" name="Schedulers" parent="stock.menu_stock_root" sequence="50" groups="base.group_no_one"/>
|
||||
<menuitem action="action_procurement_compute" id="menu_procurement_compute" parent="menu_stock_sched" groups="base.group_no_one" sequence="2"/>
|
||||
<menuitem action="procurement.action_compute_schedulers" id="menu_stock_proc_schedulers" parent="menu_stock_sched" sequence="1" groups="stock.group_stock_manager"/>
|
||||
<menuitem action="procurement.procurement_exceptions" id="menu_stock_procurement_action" parent="menu_stock_inventory_control" sequence="50" groups="stock.group_stock_manager"/>
|
||||
<menuitem action="procurement.procurement_order_action_exceptions" id="menu_stock_procurement_action" parent="menu_stock_inventory_control" sequence="50" groups="stock.group_stock_manager"/>
|
||||
<menuitem action="procurement.procurement_order_action_exceptions" id="menu_stock_procurement_action" parent="menu_stock_sched" sequence="50" groups="stock.group_stock_manager"/>
|
||||
<menuitem id="menu_stock_procurement" name="Automatic Procurements" parent="stock.menu_stock_config_settings" sequence="5"/>
|
||||
<menuitem id="menu_reordering_rules_config" action="action_orderpoint_form" name="Reordering Rules" parent="menu_stock_config_settings" sequence="3"/>
|
||||
<menuitem id="stock.menu_warehouse_report" name="Reports" sequence="99" parent="stock.menu_stock_root" groups="group_stock_manager"/>
|
||||
|
||||
Reference in New Issue
Block a user