[MERGE] stock_planning: a few bugfixes, better help/tooltips, cleanup, most of it courtesy of Grzegorz Grzelak (OpenGLOBE.pl)
Also removed some dead code, fixed views, and changed deprecated dependency on HR module to CRM module. The latter was only used to select a department, i.e. a group of users. Using sales teams from CRM is more suited, as the goal is to make Sales Forecast. bzr revid: odo@openerp.com-20110916203230-pm5qtmbmw6x5lfg2
This commit is contained in:
@@ -20,94 +20,129 @@
|
||||
##############################################################################
|
||||
|
||||
{
|
||||
"name":"Master Procurement Schedule",
|
||||
"version":"1.1",
|
||||
"author":["OpenERP SA", "Grzegorz Grzelak (Cirrus)"],
|
||||
"category":"Warehouse",
|
||||
"images":["images/master_procurement_schedule.jpeg","images/sales_forecast.jpeg","images/stock_planning_line.jpeg","images/stock_sales_period.jpeg"],
|
||||
"depends":["hr","stock","sale"],
|
||||
"name": "Master Procurement Schedule",
|
||||
"version": "1.2",
|
||||
"author": "OpenERP SA and Grzegorz Grzelak (OpenGLOBE)",
|
||||
"category": "Warehouse",
|
||||
"images": ["images/master_procurement_schedule.jpeg","images/sales_forecast.jpeg","images/stock_planning_line.jpeg","images/stock_sales_period.jpeg"],
|
||||
"depends": ["crm", "stock","sale"],
|
||||
"complexity": "expert",
|
||||
"description": """
|
||||
Purpose of MPS is to allow create a manual procurement apart of MRP scheduler (which works automatically on minimum stock rules).
|
||||
=================================================================================================================================
|
||||
MPS allows to create a manual procurement plan apart of the normal MRP scheduling, which works automatically based on minimum stock rules
|
||||
=========================================================================================================================================
|
||||
|
||||
This module is based on original OpenERP SA module stock_planning version 1.0 of the same name Master Procurement Schedule.
|
||||
Terms used in the module:
|
||||
- Stock and Sales Period - is the time (between Start Date and End Date) for which you plan Stock and Sales Forecast and make Procurement Planning.
|
||||
- Stock and Sales Forecast - is the quantity of products you plan to sell in the Period.
|
||||
- Stock Planning - is the quantity of products you plan to purchase or produce for the Period.
|
||||
Quick Glossary
|
||||
--------------
|
||||
- Stock Period - the time boundaries (between Start Date and End Date) for your Sales and Stock forecasts and planning
|
||||
- Sales Forecast - the quantity of products you plan to sell during the related Stock Period.
|
||||
- Stock Planning - the quantity of products you plan to purchase or produce for the related Stock Period.
|
||||
|
||||
Because we have another module sale_forecast which uses terms "Sales Forecast" and "Planning" as amount values we will use terms "Stock and Sales Forecast" and "Stock Planning" to emphasize that we use quantity values.
|
||||
To avoid confusion with the terms used by the ``sale_forecast`` module, ("Sales Forecast" and "Planning" are amounts) we use terms "Stock and Sales Forecast" and "Stock Planning" to emphasize that we use quantity values.
|
||||
|
||||
Activity with this module is divided to three steps:
|
||||
- Creating Periods. Mandatory step.
|
||||
- Creating Sale Forecasts and entering quantities to them. Optional step but useful for further planning.
|
||||
- Creating Planning lines, entering quantities to them and making Procurement. Making procurement is the final step for the Period.
|
||||
Where to begin
|
||||
--------------
|
||||
Using this module is done in three steps:
|
||||
|
||||
Periods
|
||||
-------
|
||||
You have two menu items for Periods in "Sales Management - Configuration". There are:
|
||||
- "Create Sales Periods" - Which automates creating daily, weekly or monthly periods.
|
||||
- "Stock and sales Periods" - Which allows to create any type of periods, change the dates and change the State of period.
|
||||
* Create Stock Periods via the Warehouse>Configuration>Stock Periods menu (Mandatory step)
|
||||
* Create Sale Forecasts fill them with forecast quantities, via the Sales>Sales Forecast menu. (Optional step but useful for further planning)
|
||||
* Create the actual MPS plan, check the balance and trigger the procurements as required. The actual procurement is the final step for the Stock Period.
|
||||
|
||||
Creating periods is the first step you have to do to use modules features. You can create custom periods using "New" button in "Stock and Sales Periods" form or view but it is recommended to use automating tool.
|
||||
Stock Period configuration
|
||||
--------------------------
|
||||
You have two menu items for Periods in "Warehouse > Configuration > Stock Periods". There are:
|
||||
|
||||
Remarks:
|
||||
- These periods (officially Stock and Sales Periods) are separated of Financial or other periods in the system.
|
||||
- Periods are not assigned to companies (when you use multicompany feature at all). Module suppose that you use the same periods across companies. If you wish to use different periods for different companies define them as you wish (they can overlap). Later on in this text will be indications how to use such periods.
|
||||
- When periods are created automatically their start and finish dates are with start hour 00:00:00 and end hour 23:59:00. when you create daily periods they will have start date 31.01.2010 00:00:00 and end date 31.01.2010 23:59:00. It works only in automatic creation of periods. When you create periods manually you have to take care about hours because you can have incorrect values form sales or stock.
|
||||
- If you use overlapping periods for the same product, warehouse and company results can be unpredictable.
|
||||
- If current date doesn't belong to any period or you have holes between periods results can be unpredictable.
|
||||
* "Create Stock Periods" - can automatically creating daily, weekly or monthly periods.
|
||||
* "Stock Periods" - allows to create any type of periods, change the dates and change the state of period.
|
||||
|
||||
Sales Forecasts
|
||||
---------------
|
||||
You have few menus for Sales forecast in "Sales Management - Sales Forecasts".
|
||||
- "Create Sales Forecasts for Sales Periods" - which automates creating forecasts lines according to some parameters.
|
||||
- "Sales Forecasts" - few menus for working with forecasts lists and forms.
|
||||
|
||||
Menu "Create Sales Forecasts for Sales Periods" creates Forecasts for products from selected Category, for selected Period and for selected Warehouse. It is an option "Copy Last Forecast" to copy forecast and other settings of period before this one to created one.
|
||||
|
||||
Remarks:
|
||||
- This tool doesn't create lines, if relevant lines (for the same Product, Period, Warehouse and validated or created by you) already exists. If you wish to create another forecast, if relevant lines exists you have to do it manually using menus described bellow.
|
||||
- When created lines are validated by someone else you can use this tool to create another lines for the same Period, Product and Warehouse.
|
||||
- When you choose "Copy Last Forecast" created line takes quantity and some settings from your (validated by you or created by you if not validated yet) forecast which is for last period before period of created forecast. If there are few your forecasts for period before this one (it is possible) system takes one of them (no rule which of them).
|
||||
|
||||
|
||||
Menus "Sales Forecasts"
|
||||
On "Sales Forecast" form mainly you have to enter a forecast quantity in "Product Quantity". Further calculation can work for draft forecasts. But validation can save your data against any accidental changes. You can click "Validate" button but it is not mandatory.
|
||||
|
||||
Instead of forecast quantity you can enter amount of forecast sales in field "Product Amount". System will count quantity from amount according to Sale price of the Product.
|
||||
|
||||
All values on the form are expressed in unit of measure selected on form. You can select one of unit of measure from default category or from second category. When you change unit of measure the quanities will be recalculated according to new UoM: editable values (blue fields) immediately, non edited fields after clicking of "Calculate Planning" button.
|
||||
|
||||
To find proper value for Sale Forecast you can use "Sales History" table for this product. You have to enter parameters to the top and left of this table and system will count sale quantities according to these parameters. So you can select your department (at the top) then (to the left): last period, period before last and period year ago.
|
||||
Creating periods is the first step. You can create custom periods using the "New" button in "Stock Periods", but it is recommended to use the automatic assistant "Create Stock Periods".
|
||||
|
||||
Remarks:
|
||||
|
||||
- These periods (Stock Periods) are completely distinct from Financial or other periods in the system.
|
||||
- Periods are not assigned to companies (when you use multicompany). Module suppose that you use the same periods across companies. If you wish to use different periods for different companies define them as you wish (they can overlap). Later on in this text will be indications how to use such periods.
|
||||
- When periods are created automatically their start and finish dates are with start hour 00:00:00 and end hour 23:59:00. When you create daily periods they will have start date 31.01.2010 00:00:00 and end date 31.01.2010 23:59:00. It works only in automatic creation of periods. When you create periods manually you have to take care about hours because you can have incorrect values form sales or stock.
|
||||
- If you use overlapping periods for the same product, warehouse and company results can be unpredictable.
|
||||
- If current date doesn't belong to any period or you have holes between periods results can be unpredictable.
|
||||
|
||||
Procurement Planning
|
||||
--------------------
|
||||
Menu for Planning you can find in "Warehouse - Stock Planning".
|
||||
- "Create Stock Planning Lines" - allows you to automate creating planning lines according to some parameters.
|
||||
- "Master Procurement Scheduler" - is the most important menu of the module which allows to create procurement.
|
||||
Sales Forecasts configuration
|
||||
-----------------------------
|
||||
You have few menus for Sales forecast in "Sales > Sales Forecasts":
|
||||
|
||||
As Sales forecast is phase of planning sales. The Procurement Planning (Planning) is the phase of scheduling Purchasing or Producing. You can create Procurement Planning quickly using tool from menu "Create Stock Planning Lines", then you can review created planning and make procurement using menu "Master Procurement Schedule".
|
||||
- "Create Sales Forecasts" - can automatically create forecast lines according to your needs
|
||||
- "Sales Forecasts" - for managing the Sales forecasts
|
||||
|
||||
Menu "Create Stock Planning Lines" allows you to create quickly Planning lines for products from selected Category, for selected Period, and for selected Warehouse. When you check option "All Products with Forecast" system creates lines for all products having forecast for selected Period and Warehouse. Selected Category will be ignored in this case.
|
||||
Menu "Create Sales Forecasts" creates Forecasts for products from selected Category, for selected Period and for selected Warehouse.
|
||||
It is also possible to copy the previous forecast.
|
||||
|
||||
Under menu "Master Procurement Scheduler" you can generally change the values "Planned Out" and "Planned In" to observe the field "Stock Simulation" and decide if this value would be accurate for end of the Period.
|
||||
"Planned Out" can be based on "Warehouse Forecast" which is the sum of all forecasts for Period and Warehouse. But your planning can be based on any other information you have. It is not necessary to have any forecast.
|
||||
"Planned In" quantity is used to calculate field "Incoming Left" which is the quantity to be procured to make stock as indicated in "Stock Simulation" at the end of Period. You can compare "Stock Simulation" quantity to minimum stock rules visible on the form. But you can plan different quantity than in Minimum Stock Rules. Calculation is made for whole Warehouse by default. But if you want to see values for Stock location of calculated warehouse you can use check box "Stock Location Only".
|
||||
Remarks:
|
||||
|
||||
If after few tries you decide that you found correct quantities for "Planned Out" and "Planned In" and you are satisfied with end of period stock calculated in "Stock Simulation" you can click "Procure Incoming Left" button to procure quantity of field "Incoming Left" into the Warehouse. System creates appropriate Procurement Order. You can decide if procurement will be made to Stock or Input location of calculated Warehouse.
|
||||
- This tool doesn't duplicate lines if you already have an entry for the same Product, Period, Warehouse, created or validated by the same user. If you wish to create another forecast, if relevant lines exists you have to do it manually as described below.
|
||||
- When created lines are validated by someone else you can use this tool to create another line for the same Period, Product and Warehouse.
|
||||
- When you choose "Copy Last Forecast", created line take quantity and other settings from your (validated by you or created by you if not validated yet) forecast which is for last period before period of created forecast.
|
||||
|
||||
If you don't want to Produce or Buy the product but just pick calculated quantity from another warehouse you can click "Supply from Another Warehouse" (instead of "Procure Incoming Left"). System creates pick list with move from selected source Warehouse to calculated Warehouse (as destination). You can also decide if this pick should be done from Stock or Output location of source warehouse. Destination location (Stock or Input) of destination warehouse will be used as set for "Procure Incoming Left".
|
||||
On "Sales Forecast" form mainly you have to enter a forecast quantity in "Product Quantity".
|
||||
Further calculation can work for draft forecasts. But validation can save your data against any accidental changes.
|
||||
You can click "Validate" button but it is not mandatory.
|
||||
|
||||
To see proper quantities in fields "Confirmed In", "Confirmed Out", "Confirmed In Before", "Planned Out Before" and "Stock Simulation" you have to click button "Calculate Planning".
|
||||
Instead of forecast quantity you may enter the amount of forecast sales via the "Product Amount" field.
|
||||
The system will count quantity from amount according to Sale price of the Product.
|
||||
|
||||
All values on the form are expressed in unit of measure selected on form. You can select one of unit of measure from default category or from second category. When you change unit of measure the quanities will be recalculated according to new UoM: editable values (blue fields) immediately, non edited fields after clicking of "Calculate Planning" button.
|
||||
All values on the form are expressed in unit of measure selected on form.
|
||||
You can select a unit of measure from the default category or from secondary category.
|
||||
When you change unit of measure the forecast product quantity will be re-computed according to new UoM.
|
||||
|
||||
How Stock Simulation field is calculated:
|
||||
Generally Stock Simulation shows the stock for end of the calculated period according to some planned or confirmed stock moves. Calculation always starts with quantity of real stock of beginning of current period. Then calculation adds or subtracts quantities of calculated period or periods before calculated.
|
||||
To work out your Sale Forecast you can use the "Sales History" of the product.
|
||||
You have to enter parameters to the top and left of this table and system will count sale quantities according to these parameters.
|
||||
So you can get results for a given sales team or period.
|
||||
|
||||
|
||||
MPS or Procurement Planning
|
||||
---------------------------
|
||||
An MPS planning consists in Stock Planning lines, used to analyze and possibly drive the procurement of
|
||||
products for each relevant Stock Period and Warehouse.
|
||||
The menu is located in "Warehouse > Schedulers > Master Procurement Schedule":
|
||||
|
||||
- "Create Stock Planning Lines" - a wizard to help automatically create many planning lines
|
||||
- "Master Procurement Schedule" - management of your planning lines
|
||||
|
||||
Similarly to the way Sales forecast serves to define your sales planning, the MPS lets you plan your procurements (Purchase/Manufacturing).
|
||||
You can quickly populate the MPS with the "Create Stock Planning Lines" wizard, and then proceed to review them via the "Master Procurement Schedule" menu.
|
||||
|
||||
The "Create Stock Planning Lines" wizard lets you to quickly create all MPS lines for a given Product Category, and a given Period and Warehouse.
|
||||
When you enable the "All Products with Forecast" option of the wizard, the system creates lines for all products having sales forecast for selected
|
||||
Period and Warehouse (the selected Category will be ignored in this case).
|
||||
|
||||
Under menu "Master Procurement Schedule" you will usually change the "Planned Out" and "Planned In" quantities and observe the resulting "Stock Simulation" value
|
||||
to decide if you need to procure more products for the given Period.
|
||||
"Planned Out" will be initially based on "Warehouse Forecast" which is the sum of all outgoing stock moves already planned for the Period and Warehouse.
|
||||
Of course you can alter this value to provide your own quantities. It is not necessary to have any forecast.
|
||||
"Planned In" quantity is used to calculate field "Incoming Left" which is the quantity to be procured to reach the "Stock Simulation" at the end of Period.
|
||||
You can compare "Stock Simulation" quantity to minimum stock rules visible on the form.
|
||||
And you can plan different quantity than in Minimum Stock Rules. Calculations are done for whole Warehouse by default,
|
||||
if you want to see values for Stock location of calculated warehouse you can check "Stock Location Only".
|
||||
|
||||
When you are satisfied with the "Planned Out", "Planned In" and end of period "Stock Simulation",
|
||||
you can click on "Procure Incoming Left" to create a procurement for the "Incoming Left" quantity.
|
||||
You can decide if procurement will go to the to Stock or Input location of the Warehouse.
|
||||
|
||||
If you don't want to Produce or Buy the product but just transfer the calculated quantity from another warehouse
|
||||
you can click "Supply from Another Warehouse" (instead of "Procure Incoming Left") and the system will
|
||||
create the appropriate picking list (stock moves).
|
||||
You can choose to take the goods from the Stock or the Output location of the source warehouse.
|
||||
Destination location (Stock or Input) in the destination warehouse will be taken as for the procurement case.
|
||||
|
||||
To see update the quantities of "Confirmed In", "Confirmed Out", "Confirmed In Before", "Planned Out Before"
|
||||
and "Stock Simulation" you can press "Calculate Planning".
|
||||
|
||||
All values on the form are expressed in unit of measure selected on form.
|
||||
You can select one of unit of measure from default category or from secondary category.
|
||||
When you change unit of measure the editable quantities will be re-computed according to new UoM. The others will be updated after pressing "Calculate Planning".
|
||||
|
||||
Computation of Stock Simulation quantities
|
||||
------------------------------------------
|
||||
The Stock Simulation value is the estimated stock quantity at the end of the period.
|
||||
The calculation always starts with the real stock on hand at the beginning of the current period, then
|
||||
adds or subtracts the computed quantities.
|
||||
When you are in the same period (current period is the same as calculated) Stock Simulation is calculated as follows:
|
||||
|
||||
Stock Simulation =
|
||||
@@ -124,9 +159,12 @@ Stock Simulation =
|
||||
- Planned Out of calculated Period
|
||||
+ Planned In of calculated Period .
|
||||
|
||||
As you see calculated Period is taken the same way like in case above. But calculation of current Period are made a little bit different. First you should note that system takes for current Period only Confirmed In moves. It means that you have to make planning and procurement for current Period before this calculation (for Period next to current).
|
||||
As you see the calculated Period is taken the same way as in previous case, but the calculation in the current
|
||||
Period is a little bit different. First you should note that system takes for only Confirmed moves for the
|
||||
current period. This means that you should complete the planning and procurement of the current Period before
|
||||
going to the next one.
|
||||
|
||||
When you calculate Period ahead:
|
||||
When you plan for future Periods:
|
||||
|
||||
Stock Simulation =
|
||||
Stock of beginning of current Period
|
||||
@@ -135,15 +173,22 @@ Stock Simulation =
|
||||
- Planned Out of calculated Period
|
||||
+ Planned In of calculated Period.
|
||||
|
||||
Periods before calculated means periods starting from current till period before calculated.
|
||||
Here "Periods before calculated" designates all periods starting with the current until the period before the one being calculated.
|
||||
|
||||
Remarks:
|
||||
- Remember to make planning for all periods before calculated because omitting these quantities and procurements can cause wrong suggestions for procurements few periods ahead.
|
||||
- If you made planning few periods ahead and you find that real Confirmed Out is bigger than Planned Out in some periods before you can repeat Planning and make another procurement. You should do it in the same planning line. If you create another planning line the suggestions can be wrong.
|
||||
- When you wish to work with different periods for some part of products define two kinds of periods (fe. Weekly and Monthly) and use them for different products. Example: If you use always Weekly periods for Products A, and Monthly periods for Products B your all calculations will work correctly. You can also use different kind of periods for the same products from different warehouse or companies. But you cannot use overlapping periods for the same product, warehouse and company because results can be unpredictable. The same apply to Forecasts lines.
|
||||
|
||||
- Remember to make the proceed with the planning of each period in chronological order, otherwise the numbers will not reflect the
|
||||
reality
|
||||
- If you planned for future periods and find that real Confirmed Out is larger than Planned Out in some periods before,
|
||||
you can repeat Planning and make another procurement. You should do it in the same planning line.
|
||||
If you create another planning line the suggestions can be wrong.
|
||||
- When you wish to work with different periods for some products, define two kinds of periods (e.g. Weekly and Monthly) and use
|
||||
them for different products. Example: If you use always Weekly periods for Product A, and Monthly periods for Product B
|
||||
all calculations will work correctly. You can also use different kind of periods for the same product from different warehouse
|
||||
or companies. But you cannot use overlapping periods for the same product, warehouse and company because results
|
||||
can be unpredictable. The same applies to Forecasts lines.
|
||||
""",
|
||||
"demo_xml":[],
|
||||
"update_xml": [
|
||||
"data": [
|
||||
"security/ir.model.access.csv",
|
||||
"stock_planning_view.xml",
|
||||
"wizard/stock_planning_create_periods_view.xml",
|
||||
|
||||
@@ -26,6 +26,10 @@ from dateutil.relativedelta import relativedelta
|
||||
from osv import osv, fields
|
||||
import netsvc
|
||||
from tools.translate import _
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger('mps')
|
||||
|
||||
|
||||
def rounding(fl, round_value):
|
||||
if not round_value:
|
||||
@@ -37,6 +41,7 @@ def rounding(fl, round_value):
|
||||
class stock_period(osv.osv):
|
||||
_name = "stock.period"
|
||||
_description = "stock period"
|
||||
_order = "date_start"
|
||||
_columns = {
|
||||
'name': fields.char('Period Name', size=64, required=True),
|
||||
'date_start': fields.datetime('Start Date', required=True),
|
||||
@@ -75,16 +80,16 @@ class stock_sale_forecast(osv.osv):
|
||||
help = 'Shows which period this forecast concerns.'),
|
||||
'product_id': fields.many2one('product.product', 'Product', readonly=True, required=True, states={'draft':[('readonly',False)]}, \
|
||||
help = 'Shows which product this forecast concerns.'),
|
||||
'product_qty': fields.float('Product Quantity', required=True, readonly=True, states={'draft':[('readonly',False)]}, \
|
||||
help= 'Forecasted quantity.'),
|
||||
'product_qty': fields.float('Forecast Quantity', required=True, readonly=True, states={'draft':[('readonly',False)]}, \
|
||||
help= 'Forecast Product quantity.'),
|
||||
'product_amt': fields.float('Product Amount', readonly=True, states={'draft':[('readonly',False)]}, \
|
||||
help='Forecast value which will be converted to Product Quantity according to prices.'),
|
||||
'product_uom_categ': fields.many2one('product.uom.categ', 'Product UoM Category'), # Invisible field for product_uom domain
|
||||
'product_uom': fields.many2one('product.uom', 'Product UoM', required=True, readonly=True, states={'draft':[('readonly',False)]}, \
|
||||
help = "Unit of Measure used to show the quanities of stock calculation." \
|
||||
help = "Unit of Measure used to show the quantities of stock calculation." \
|
||||
"You can use units form default category or from second category (UoS category)."),
|
||||
'product_uos_categ' : fields.many2one('product.uom.categ', 'Product UoS Category'), # Invisible field for product_uos domain
|
||||
# Field used in onchange_uom to check what uom was before change and recalculate quantities acording to old uom (active_uom) and new uom.
|
||||
# Field used in onchange_uom to check what uom was before change and recalculate quantities according to old uom (active_uom) and new uom.
|
||||
'active_uom': fields.many2one('product.uom', string = "Active UoM"),
|
||||
'state': fields.selection([('draft','Draft'),('validated','Validated')],'State',readonly=True),
|
||||
'analyzed_period1_id': fields.many2one('stock.period', 'Period1', readonly=True, states={'draft':[('readonly',False)]},),
|
||||
@@ -93,7 +98,7 @@ class stock_sale_forecast(osv.osv):
|
||||
'analyzed_period4_id': fields.many2one('stock.period', 'Period4', readonly=True, states={'draft':[('readonly',False)]},),
|
||||
'analyzed_period5_id': fields.many2one('stock.period' , 'Period5', readonly=True, states={'draft':[('readonly',False)]},),
|
||||
'analyzed_user_id': fields.many2one('res.users', 'This User', required=False, readonly=True, states={'draft':[('readonly',False)]},),
|
||||
'analyzed_dept_id': fields.many2one('hr.department', 'This Department', required=False, \
|
||||
'analyzed_team_id': fields.many2one('crm.case.section', 'Sales Team', required=False, \
|
||||
readonly=True, states={'draft':[('readonly',False)]},),
|
||||
'analyzed_warehouse_id': fields.many2one('stock.warehouse' , 'This Warehouse', required=False, \
|
||||
readonly=True, states={'draft':[('readonly',False)]}),
|
||||
@@ -114,7 +119,7 @@ class stock_sale_forecast(osv.osv):
|
||||
'analyzed_period3_per_warehouse': fields.float('This Warehouse Period3', readonly=True),
|
||||
'analyzed_period4_per_warehouse': fields.float('This Warehouse Period4', readonly=True),
|
||||
'analyzed_period5_per_warehouse': fields.float('This Warehouse Period5', readonly=True),
|
||||
'analyzed_period1_per_company': fields.float('This Copmany Period1', readonly=True),
|
||||
'analyzed_period1_per_company': fields.float('This Company Period1', readonly=True),
|
||||
'analyzed_period2_per_company': fields.float('This Company Period2', readonly=True),
|
||||
'analyzed_period3_per_company': fields.float('This Company Period3', readonly=True),
|
||||
'analyzed_period4_per_company': fields.float('This Company Period4', readonly=True),
|
||||
@@ -147,7 +152,7 @@ class stock_sale_forecast(osv.osv):
|
||||
return result
|
||||
result['warehouse_id'] = False
|
||||
result['analyzed_user_id'] = False
|
||||
result['analyzed_dept_id'] = False
|
||||
result['analyzed_team_id'] = False
|
||||
result['analyzed_warehouse_id'] = False
|
||||
return {'value': result}
|
||||
|
||||
@@ -196,7 +201,7 @@ class stock_sale_forecast(osv.osv):
|
||||
uom = uom_obj.browse(cr, uid, uom_id, context=context)
|
||||
coef = uom.factor
|
||||
if uom.category_id.id <> product.uom_id.category_id.id:
|
||||
coef = coef / product.uos_coeff
|
||||
coef = coef * product.uos_coeff
|
||||
return product.uom_id.factor / coef
|
||||
|
||||
def _from_default_uom_factor(self, cr, uid, product_id, uom_id, context=None):
|
||||
@@ -206,7 +211,7 @@ class stock_sale_forecast(osv.osv):
|
||||
uom = uom_obj.browse(cr, uid, uom_id, context=context)
|
||||
res = uom.factor
|
||||
if uom.category_id.id <> product.uom_id.category_id.id:
|
||||
res = res / product.uos_coeff
|
||||
res = res * product.uos_coeff
|
||||
return res / product.uom_id.factor, uom.rounding
|
||||
|
||||
def _sales_per_users(self, cr, uid, so, so_line, company, users):
|
||||
@@ -237,35 +242,24 @@ class stock_sale_forecast(osv.osv):
|
||||
so_line_obj = self.pool.get('sale.order.line')
|
||||
so_line_product_ids = so_line_obj.search(cr, uid, [('product_id','=', obj.product_id.id)], context = context)
|
||||
if so_line_product_ids:
|
||||
so_line_product_set = ','.join(map(str,so_line_product_ids))
|
||||
shops = users = None
|
||||
if obj.analyzed_warehouse_id:
|
||||
shops = self.pool.get('sale.shop').search(cr, uid,[('warehouse_id','=', obj.analyzed_warehouse_id.id)], context = context)
|
||||
shops_set = ','.join(map(str,shops))
|
||||
else:
|
||||
shops = False
|
||||
if obj.analyzed_dept_id:
|
||||
dept_obj = self.pool.get('hr.department')
|
||||
dept_id = obj.analyzed_dept_id.id and [obj.analyzed_dept_id.id] or []
|
||||
dept_ids = dept_obj.search(cr,uid,[('parent_id','child_of',dept_id)])
|
||||
cr.execute("SELECT user_id FROM resource_resource rsc, hr_employee emp WHERE (emp.resource_id = rsc.id and emp.department_id IN %s)" ,(tuple(dept_ids),))
|
||||
dept_users = [x for x, in cr.fetchall()]
|
||||
dept_users_set = map(str,dept_users)
|
||||
else:
|
||||
dept_users = False
|
||||
factor, round_value = self._from_default_uom_factor(cr, uid, obj.product_id.id, obj.product_uom.id, context=context)
|
||||
if obj.analyzed_team_id:
|
||||
users = [u.id for u in obj.analyzed_team_id.member_ids]
|
||||
factor, _ = self._from_default_uom_factor(cr, uid, obj.product_id.id, obj.product_uom.id, context=context)
|
||||
for i, period in enumerate(periods):
|
||||
if period:
|
||||
so_period_ids = so_obj.search(cr, uid, [('date_order','>=',period.date_start),('date_order','<=',period.date_stop) ], context = context)
|
||||
if so_period_ids:
|
||||
if obj.analyzed_user_id:
|
||||
user_set = str(obj.analyzed_user_id.id)
|
||||
sales[i][0] = self._sales_per_users(cr, uid, so_period_ids, so_line_product_ids, obj.company_id.id, user_set)
|
||||
sales[i][0] = self._sales_per_users(cr, uid, so_period_ids, so_line_product_ids, obj.company_id.id, [obj.analyzed_user_id.id])
|
||||
sales[i][0] *= factor
|
||||
if dept_users:
|
||||
sales[i][1] = self._sales_per_users(cr, uid, so_period_ids, so_line_product_ids, obj.company_id.id, dept_users_set)
|
||||
if users:
|
||||
sales[i][1] = self._sales_per_users(cr, uid, so_period_ids, so_line_product_ids, obj.company_id.id, users)
|
||||
sales[i][1] *= factor
|
||||
if shops:
|
||||
sales[i][2] = self._sales_per_warehouse(cr, uid, so_period_ids, so_line_product_ids, obj.company_id.id, shops_set)
|
||||
sales[i][2] = self._sales_per_warehouse(cr, uid, so_period_ids, so_line_product_ids, obj.company_id.id, shops)
|
||||
sales[i][2] *= factor
|
||||
if obj.analyze_company:
|
||||
sales[i][3] = self._sales_per_company(cr, uid, so_period_ids, so_line_product_ids, obj.company_id.id, )
|
||||
@@ -343,13 +337,20 @@ class stock_planning(osv.osv):
|
||||
GROUP BY planning.product_uom", \
|
||||
(date_start, date_stop, val.product_id.id, val.company_id.id,))
|
||||
planning_qtys = cr.fetchall()
|
||||
res = self._to_planning_uom(cr, uid, val, planning_qtys, context)
|
||||
res = self._to_default_uom(cr, uid, val, planning_qtys, context)
|
||||
return res
|
||||
|
||||
def _to_planning_uom(self, cr, uid, val, qtys, context=None):
|
||||
def _to_default_uom(self, cr, uid, val, qtys, context=None):
|
||||
res_qty = 0
|
||||
if qtys:
|
||||
for qty, prod_uom in qtys:
|
||||
coef = self._to_default_uom_factor(cr, uid, val.product_id.id, prod_uom, context=context)
|
||||
res_qty += qty * coef
|
||||
return res_qty
|
||||
|
||||
def _to_form_uom(self, cr, uid, val, qtys, context=None):
|
||||
res_qty = 0
|
||||
if qtys:
|
||||
uom_obj = self.pool.get('product.uom')
|
||||
for qty, prod_uom in qtys:
|
||||
coef = self._to_default_uom_factor(cr, uid, val.product_id.id, prod_uom, context=context)
|
||||
res_coef, round_value = self._from_default_uom_factor(cr, uid, val.product_id.id, val.product_uom.id, context=context)
|
||||
@@ -369,7 +370,7 @@ class stock_planning(osv.osv):
|
||||
'GROUP BY product_uom', \
|
||||
(val.product_id.id,val.period_id.id, val.company_id.id))
|
||||
company_qtys = cr.fetchall()
|
||||
res[val.id]['company_forecast'] = self._to_planning_uom(cr, uid, val, company_qtys, context)
|
||||
res[val.id]['company_forecast'] = self._to_form_uom(cr, uid, val, company_qtys, context)
|
||||
|
||||
cr.execute('SELECT sum(product_qty), product_uom \
|
||||
FROM stock_sale_forecast \
|
||||
@@ -377,8 +378,8 @@ class stock_planning(osv.osv):
|
||||
'GROUP BY product_uom', \
|
||||
(val.product_id.id,val.period_id.id, val.warehouse_id.id))
|
||||
warehouse_qtys = cr.fetchall()
|
||||
res[val.id]['warehouse_forecast'] = self._to_planning_uom(cr, uid, val, warehouse_qtys, context)
|
||||
res[val.id]['warehouse_forecast'] = rounding(res[val.id]['warehouse_forecast'], val.product_id.uom_id.rounding)
|
||||
res[val.id]['warehouse_forecast'] = self._to_form_uom(cr, uid, val, warehouse_qtys, context)
|
||||
# res[val.id]['warehouse_forecast'] = rounding(res[val.id]['warehouse_forecast'], val.product_id.uom_id.rounding)
|
||||
return res
|
||||
|
||||
def _get_stock_start(self, cr, uid, val, date, context=None):
|
||||
@@ -419,7 +420,7 @@ class stock_planning(osv.osv):
|
||||
res_coef, round_value = self._from_default_uom_factor(cr, uid, val.product_id.id, val.product_uom.id, context=context)
|
||||
coef = coef * res_coef
|
||||
res[val.id]['minimum_op'] = rounding(ret[0]*coef, round_value)
|
||||
res[val.id]['maximum_op'] = ret[1]*coef
|
||||
res[val.id]['maximum_op'] = rounding(ret[1]*coef, round_value)
|
||||
return res
|
||||
|
||||
def onchange_company(self, cr, uid, ids, company_id=False):
|
||||
@@ -451,11 +452,11 @@ class stock_planning(osv.osv):
|
||||
'warehouse_id': fields.many2one('stock.warehouse','Warehouse', required=True),
|
||||
'product_id': fields.many2one('product.product' , 'Product', required=True, help = 'Product which this planning is created for.'),
|
||||
'product_uom_categ' : fields.many2one('product.uom.categ', 'Product UoM Category'), # Invisible field for product_uom domain
|
||||
'product_uom': fields.many2one('product.uom', 'UoM', required=True, help = "Unit of Measure used to show the quanities of stock calculation." \
|
||||
"You can use units form default category or from second category (UoS category)."),
|
||||
'product_uom': fields.many2one('product.uom', 'UoM', required=True, help = "Unit of Measure used to show the quantities of stock calculation." \
|
||||
"You can use units from default category or from second category (UoS category)."),
|
||||
'product_uos_categ': fields.many2one('product.uom.categ', 'Product UoM Category'), # Invisible field for product_uos domain
|
||||
# Field used in onchange_uom to check what uom was before change to recalculate quantities acording to old uom (active_uom) and new uom.
|
||||
'active_uom': fields.many2one('product.uom', string = "Active UoM"),
|
||||
# Field used in onchange_uom to check what uom was before change to recalculate quantities according to old uom (active_uom) and new uom.
|
||||
'active_uom': fields.many2one('product.uom', string = "Active UoM"), # It works only in Forecast
|
||||
'planned_outgoing': fields.float('Planned Out', required=True, \
|
||||
help = 'Enter planned outgoing quantity from selected Warehouse during the selected Period of selected Product. '\
|
||||
'To plan this value look at Confirmed Out or Sales Forecasts. This value should be equal or greater than Confirmed Out.'),
|
||||
@@ -475,16 +476,16 @@ class stock_planning(osv.osv):
|
||||
help = 'Quantity left to Planned incoming quantity. This is calculated difference between Planned In and Confirmed In. ' \
|
||||
'For current period Already In is also calculated. This value is used to create procurement for lacking quantity.'),
|
||||
'outgoing_left': fields.float('Expected Out', readonly=True, \
|
||||
help = 'Quantity expected to go out in selected period. As a difference between Planned Out and Confirmed Out. ' \
|
||||
help = 'Quantity expected to go out in selected period besides Confirmed Out. As a difference between Planned Out and Confirmed Out. ' \
|
||||
'For current period Already Out is also calculated'),
|
||||
'to_procure': fields.float(string='Planned In', required=True, \
|
||||
help = 'Enter quantity which (by your plan) should come in. Change this value and observe Stock simulation. ' \
|
||||
'This value should be equal or greater than Confirmed In.'),
|
||||
'line_time': fields.function(_get_past_future,type='char', string='Past/Future'),
|
||||
'line_time': fields.function(_get_past_future, type='char', string='Past/Future'),
|
||||
'minimum_op': fields.function(_get_op, type='float', string = 'Minimum Rule', multi= 'minimum', \
|
||||
help = 'Minimum quantity set in Minimum Stock Rules for this Warhouse'),
|
||||
help = 'Minimum quantity set in Minimum Stock Rules for this Warehouse'),
|
||||
'maximum_op': fields.function(_get_op, type='float', string = 'Maximum Rule', multi= 'maximum', \
|
||||
help = 'Maximum quantity set in Minimum Stock Rules for this Warhouse'),
|
||||
help = 'Maximum quantity set in Minimum Stock Rules for this Warehouse'),
|
||||
'outgoing_before': fields.float('Planned Out Before', readonly=True, \
|
||||
help= 'Planned Out in periods before calculated. '\
|
||||
'Between start date of current period and one day before start of calculated period.'),
|
||||
@@ -499,18 +500,18 @@ class stock_planning(osv.osv):
|
||||
help= 'Quantity which is already picked up to this warehouse in current period.'),
|
||||
'stock_only': fields.boolean("Stock Location Only", help = "Check to calculate stock location of selected warehouse only. " \
|
||||
"If not selected calculation is made for input, stock and output location of warehouse."),
|
||||
"procure_to_stock": fields.boolean("Procure To Stock Location", help = "Chect to make procurement to stock location of selected warehouse. " \
|
||||
"procure_to_stock": fields.boolean("Procure To Stock Location", help = "Check to make procurement to stock location of selected warehouse. " \
|
||||
"If not selected procurement will be made into input location of warehouse."),
|
||||
"confirmed_forecasts_only": fields.boolean("Validated Forecasts", help = "Check to take validated forecasts only. " \
|
||||
"If not checked system takes validated and draft forecasts."),
|
||||
'supply_warehouse_id': fields.many2one('stock.warehouse','Source Warehouse', help = "Warehouse used as source in supply pick move created by 'Supply from Another Warhouse'."),
|
||||
'supply_warehouse_id': fields.many2one('stock.warehouse','Source Warehouse', help = "Warehouse used as source in supply pick move created by 'Supply from Another Warehouse'."),
|
||||
"stock_supply_location": fields.boolean("Stock Supply Location", help = "Check to supply from Stock location of Supply Warehouse. " \
|
||||
"If not checked supply will be made from Output location of Supply Warehouse. Used in 'Supply from Another Warhouse' with Supply Warehouse."),
|
||||
"If not checked supply will be made from Output location of Supply Warehouse. Used in 'Supply from Another Warehouse' with Supply Warehouse."),
|
||||
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'state': lambda *args: 'draft' ,
|
||||
'state': 'draft' ,
|
||||
'to_procure': 0.0,
|
||||
'planned_outgoing': 0.0,
|
||||
'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.planning', context=c),
|
||||
@@ -525,7 +526,7 @@ class stock_planning(osv.osv):
|
||||
uom = uom_obj.browse(cr, uid, uom_id, context=context)
|
||||
coef = uom.factor
|
||||
if uom.category_id.id != product.uom_id.category_id.id:
|
||||
coef = coef / product.uos_coeff
|
||||
coef = coef * product.uos_coeff
|
||||
return product.uom_id.factor / coef
|
||||
|
||||
|
||||
@@ -536,19 +537,22 @@ class stock_planning(osv.osv):
|
||||
uom = uom_obj.browse(cr, uid, uom_id, context=context)
|
||||
res = uom.factor
|
||||
if uom.category_id.id != product.uom_id.category_id.id:
|
||||
res = res / product.uos_coeff
|
||||
res = res * product.uos_coeff
|
||||
return res / product.uom_id.factor, uom.rounding
|
||||
|
||||
def calculate_planning(self, cr, uid, ids, context, *args):
|
||||
one_minute = relativedelta(minutes=1)
|
||||
current_date_beginning_c = datetime.today()
|
||||
current_date_end_c = current_date_beginning_c + relativedelta(days=1, minutes=-1) # to get hour 23:59:00
|
||||
one_second = relativedelta(seconds=1)
|
||||
today = datetime.today()
|
||||
current_date_beginning_c = datetime(today.year, today.month, today.day)
|
||||
current_date_end_c = current_date_beginning_c + relativedelta(days=1, seconds=-1) # to get hour 23:59:59
|
||||
current_date_beginning = current_date_beginning_c.strftime('%Y-%m-%d %H:%M:%S')
|
||||
current_date_end = current_date_end_c.strftime('%Y-%m-%d %H:%M:%S')
|
||||
_logger.debug("Calculate Planning: current date beg: %s and end: %s", current_date_beginning, current_date_end)
|
||||
for val in self.browse(cr, uid, ids, context=context):
|
||||
day = datetime.strptime(val.period_id.date_start, '%Y-%m-%d %H:%M:%S')
|
||||
dbefore = datetime(day.year, day.month, day.day) - one_minute
|
||||
dbefore = datetime(day.year, day.month, day.day) - one_second
|
||||
day_before_calculated_period = dbefore.strftime('%Y-%m-%d %H:%M:%S') # one day before start of calculated period
|
||||
_logger.debug("Day before calculated period: %s ", day_before_calculated_period)
|
||||
cr.execute("SELECT date_start \
|
||||
FROM stock_period AS period \
|
||||
LEFT JOIN stock_planning AS planning \
|
||||
@@ -558,10 +562,10 @@ class stock_planning(osv.osv):
|
||||
date = cr.fetchone()
|
||||
start_date_current_period = date and date[0] or False
|
||||
start_date_current_period = start_date_current_period or current_date_beginning
|
||||
|
||||
day = datetime.strptime(start_date_current_period, '%Y-%m-%d %H:%M:%S')
|
||||
dbefore = datetime(day.year, day.month, day.day) - one_minute
|
||||
dbefore = datetime(day.year, day.month, day.day) - one_second
|
||||
date_for_start = dbefore.strftime('%Y-%m-%d %H:%M:%S') # one day before current period
|
||||
_logger.debug("Date for start: %s", date_for_start)
|
||||
already_out = self._get_in_out(cr, uid, val, start_date_current_period, current_date_end, direction='out', done=True, context=context),
|
||||
already_in = self._get_in_out(cr, uid, val, start_date_current_period, current_date_end, direction='in', done=True, context=context),
|
||||
outgoing = self._get_in_out(cr, uid, val, val.period_id.date_start, val.period_id.date_stop, direction='out', done=False, context=context),
|
||||
@@ -623,7 +627,7 @@ class stock_planning(osv.osv):
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
|
||||
proc_id = self.pool.get('procurement.order').create(cr, uid, {
|
||||
'company_id' : obj.company_id.id,
|
||||
'name': _('Manual planning for %s') %(obj.period_id.name),
|
||||
'name': _('MPS planning for %s') %(obj.period_id.name),
|
||||
'origin': _('MPS(%s) %s') %(user.login, obj.period_id.name),
|
||||
'date_planned': obj.period_id.date_start,
|
||||
'product_id': obj.product_id.id,
|
||||
@@ -633,7 +637,7 @@ class stock_planning(osv.osv):
|
||||
'product_uos': uos,
|
||||
'location_id': obj.procure_to_stock and obj.warehouse_id.lot_stock_id.id or obj.warehouse_id.lot_input_id.id,
|
||||
'procure_method': 'make_to_order',
|
||||
'note' : _(' Procurement created in MPS by user: %s Creation Date: %s \
|
||||
'note' : _(' Procurement created by MPS for user: %s Creation Date: %s \
|
||||
\n For period: %s \
|
||||
\n according to state: \
|
||||
\n Warehouse Forecast: %s \
|
||||
@@ -653,7 +657,7 @@ class stock_planning(osv.osv):
|
||||
self.calculate_planning(cr, uid, ids, context)
|
||||
prev_text = obj.history or ""
|
||||
self.write(cr, uid, ids, {
|
||||
'history': _('%s Requisition (%s, %s) %s %s \n') % (prev_text, user.login, time.strftime('%Y.%m.%d %H:%M'),
|
||||
'history': _('%s Procurement (%s, %s) %s %s \n') % (prev_text, user.login, time.strftime('%Y.%m.%d %H:%M'),
|
||||
obj.incoming_left, obj.product_uom.name)
|
||||
})
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<openerp>
|
||||
<data>
|
||||
<menuitem id="menu_stock_period_main"
|
||||
name="Stock and Sales Periods"
|
||||
parent="base.menu_base_config" sequence="20"/>
|
||||
name="Stock Periods"
|
||||
parent="stock.menu_stock_configuration" sequence="20"/>
|
||||
|
||||
<!-- Periods tree and form section -->
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<field name="model">stock.period</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Stock and Sales Periods">
|
||||
<form string="Stock Periods">
|
||||
<field name="name" colspan="2"/>
|
||||
<newline/>
|
||||
<field name="date_start"/>
|
||||
@@ -46,7 +46,7 @@
|
||||
<field name="model">stock.period</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Stock and Sales Period">
|
||||
<search string="Stock Periods">
|
||||
<filter string="Current" domain="[('state','in',['draft','open'])]" icon="terp-check" help="Current Periods"/>
|
||||
<filter string="Closed" domain="[('state','=','close')]" icon="gtk-stop" help="Closed Periods"/>
|
||||
<separator orientation="vertical"/>
|
||||
@@ -58,11 +58,13 @@
|
||||
</record>
|
||||
|
||||
<record id="action_stock_period_form" model="ir.actions.act_window">
|
||||
<field name="name">Stock and Sales Periods</field>
|
||||
<field name="name">Stock Periods</field>
|
||||
<field name="res_model">stock.period</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="search_view_id" ref="view_stock_period_search"/>
|
||||
<field name="help">Stock periods are used for stock planning. Stock periods are independent of account periods. You can use wizard for creating periods and review them here.</field>
|
||||
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
@@ -112,7 +114,7 @@
|
||||
<label string = ""/>
|
||||
<label string = "Periods :"/>
|
||||
<field name="analyzed_user_id" nolabel = "1" domain = "[('company_id','=',company_id)] "/>
|
||||
<field name="analyzed_dept_id" nolabel = "1" domain = "[('company_id','=',company_id)] " />
|
||||
<field name="analyzed_team_id" nolabel = "1" />
|
||||
<field name="analyzed_warehouse_id" nolabel = "1" domain = "[('company_id','=',company_id)] " />
|
||||
<group colspan = "1" col = "2">
|
||||
<field name = "analyze_company"/>
|
||||
@@ -215,7 +217,7 @@
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,graph</field>
|
||||
<field name="context">{"search_default_create_uid":uid}</field>
|
||||
<field name="search_view_id" ref="view_stock_sale_forecast_filter"/>
|
||||
<field name="help">This quantity sales forecast is an indication for Stock Planner to make procurement manually or to complement automatic procurement. You can use manual procurement with this forecast when some periods are exceptional for usual minimum stock rules.</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_stock_sale_forecast_all"
|
||||
@@ -225,7 +227,7 @@
|
||||
|
||||
<!-- Planning section -->
|
||||
|
||||
<menuitem id="menu_stock_planning_main" name="Stock Planning" parent="stock.menu_stock_root" sequence="2"/>
|
||||
<menuitem id="menu_stock_planning_manual" name="Master Procurement Schedule" parent="procurement.menu_stock_sched" sequence="10"/>
|
||||
|
||||
<record id="view_stock_planning_form" model="ir.ui.view">
|
||||
<field name="name">stock.planning.form</field>
|
||||
@@ -247,6 +249,7 @@
|
||||
<field name="product_uom"
|
||||
domain = "[('category_id','in',[product_uom_categ,product_uos_categ])]"
|
||||
on_change = "onchange_uom(product_uom, product_id, active_uom, planned_outgoing, to_procure)"/>
|
||||
<field name="active_uom" invisible = "True" />
|
||||
<separator colspan ="2" string = "Forecasts"/>
|
||||
<field name="warehouse_forecast"/>
|
||||
<field name="company_forecast"/>
|
||||
@@ -283,7 +286,7 @@
|
||||
<field name="stock_supply_location"/>
|
||||
</group>
|
||||
</group>
|
||||
<separator colspan ="4" string = "Requisition history"/>
|
||||
<separator colspan ="4" string = "Procurement history"/>
|
||||
<field name = "history" colspan = "2" nolabel = "1"/>
|
||||
</form>
|
||||
</field>
|
||||
@@ -338,12 +341,14 @@
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="search_view_id" ref="view_stock_planning_filter"/>
|
||||
<field name="help">The Master Procurement Schedule can be the main driver for warehouse replenishment, or can complement the automatic MRP scheduling (minimum stock rules, etc.).
|
||||
Each MPS line gives you a pre-computed overview of the incoming and outgoing quantities of a given product for a given Stock Period in a given Warehouse, based on the current and future stock levels,
|
||||
as well as the planned stock moves. The forecast quantities can be altered manually, and when satisfied with resulting (simulated) Stock quantity, you can trigger the procurement of what is missing to reach your desired quantities</field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
id="menu_stock_planning"
|
||||
parent="menu_stock_planning_main"
|
||||
parent="menu_stock_planning_manual"
|
||||
action="action_view_stock_planning_form"/>
|
||||
|
||||
</data>
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
!python {model: stock.sale.forecast}: |
|
||||
forecast_ids = self.search(cr, uid, [('product_id','=',ref('product.product_product_pc1'))])
|
||||
write_dict = {'product_qty': 30.0,
|
||||
'analyzed_dept_id': ref("hr.dep_sales"),
|
||||
'analyzed_section_id': ref("crm.section_sales_department"),
|
||||
'analyzed_period1_id': ref("stock_period_03"),
|
||||
'analyzed_user_id': ref("base.user_root"),
|
||||
'analyzed_warehouse_id': ref("stock.warehouse0")}
|
||||
|
||||
@@ -52,8 +52,6 @@ class stock_period_createlines(osv.osv_memory):
|
||||
}
|
||||
|
||||
def create_stock_periods(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
interval = context.get('interval',0)
|
||||
name = context.get('name','Daily')
|
||||
period_obj = self.pool.get('stock.period')
|
||||
@@ -106,7 +104,7 @@ class stock_period_createlines(osv.osv_memory):
|
||||
return {
|
||||
'domain': "[('id','in', ["+','.join(map(str, lines))+"])]",
|
||||
'view_type': 'form',
|
||||
"view_mode": 'tree, form',
|
||||
"view_mode": 'tree,form',
|
||||
'res_model': 'stock.period',
|
||||
'type': 'ir.actions.act_window',
|
||||
}
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
<field name="model">stock.period.createlines</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Stock and Sales Periods">
|
||||
<separator colspan="4" string="Create periods for Stock and Sales Planning"/>
|
||||
<form string="Stock Periods">
|
||||
<field name="date_start"/>
|
||||
<field name="date_stop"/>
|
||||
<separator colspan="4" string=""/>
|
||||
@@ -24,16 +23,17 @@
|
||||
</record>
|
||||
|
||||
<record id="action_stock_period_createlines_form" model="ir.actions.act_window">
|
||||
<field name="name">Stock and Sales Planning Periods</field>
|
||||
<field name="name">Stock Periods</field>
|
||||
<field name="res_model">stock.period.createlines</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="view_stock_period_createlines_form"/>
|
||||
<field name="help">This wizard helps with the creation of stock planning periods. These periods are independent of financial periods. If you need periods other than day-, week- or month-based, you may also add then manually.</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_stock_period_creatlines"
|
||||
name="Create Stock and Sales Periods"
|
||||
name="Create Stock Periods"
|
||||
parent="menu_stock_period_main"
|
||||
action="action_stock_period_createlines_form"
|
||||
sequence = "5"/>
|
||||
|
||||
@@ -127,16 +127,13 @@ class stock_planning_createlines(osv.osv_memory):
|
||||
'stock_supply_location': stock_supply_location,
|
||||
|
||||
}))
|
||||
result = mod_obj._get_id(cr, uid, 'stock_planning', 'view_stock_planning_filter')
|
||||
id = mod_obj.read(cr, uid, result, ['res_id'], context=context)
|
||||
|
||||
return {
|
||||
'domain': "[('id','in', ["+','.join(map(str, planning_lines))+"])]",
|
||||
'view_type': 'form',
|
||||
"view_mode": 'tree, form',
|
||||
"view_mode": 'tree,form',
|
||||
'res_model': 'stock.planning',
|
||||
'type': 'ir.actions.act_window',
|
||||
'search_view_id': id['res_id'],
|
||||
}
|
||||
|
||||
stock_planning_createlines()
|
||||
|
||||
@@ -1,24 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!-- Create Planning section -->
|
||||
|
||||
<record id="view_stock_planning_createlines_form" model="ir.ui.view">
|
||||
<field name="name">stock.planning.createlines.form</field>
|
||||
<field name="model">stock.planning.createlines</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Create Stock Planning Lines">
|
||||
<separator colspan ="4" string="Creates planning lines for selected period and warehouse."/>
|
||||
<field name="period_id" widget="selection"/>
|
||||
<field name="company_id" widget= "selection" on_change="onchange_company(company_id)" groups="base.group_multi_company"/>
|
||||
<field name="warehouse_id" domain = "[('company_id','=',company_id)] "/>
|
||||
<field name="forecasted_products"/>
|
||||
<field name="product_categ_id" attrs="{'required':[('forecasted_products','=',0)]}" widget="selection"/>
|
||||
<field name="company_id" widget= "selection" on_change="onchange_company(company_id)" groups="base.group_multi_company"/>
|
||||
<newline/>
|
||||
<label colspan ="4" string="Note: Doesn't duplicate existing lines created by you."/>
|
||||
<separator colspan="4"/>
|
||||
<group colspan="4">
|
||||
<button icon="gtk-cancel" special="cancel" string="Close"/>
|
||||
<button icon="gtk-ok" name="create_planning" string="Create" type="object"/>
|
||||
@@ -30,15 +24,17 @@
|
||||
<record id="action_stock_planning_createlines_form" model="ir.actions.act_window">
|
||||
<field name="name">Create Stock Planning Lines</field>
|
||||
<field name="res_model">stock.planning.createlines</field>
|
||||
<field name="src_model">stock.planning</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="view_stock_planning_createlines_form"/>
|
||||
<field name="help">This wizard helps create MPS planning lines for a given selected period and warehouse, so you don't have to create them one by one. The wizard doesn't duplicate lines if they already exist for this selection.</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
id="menu_stock_planning_createlines"
|
||||
parent="menu_stock_planning_main"
|
||||
parent="menu_stock_planning_manual"
|
||||
action="action_stock_planning_createlines_form" sequence = "5"/>
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -96,16 +96,13 @@ class stock_sale_forecast_createlines(osv.osv_memory):
|
||||
'product_uom_categ': p.uom_id.category_id.id,
|
||||
'product_uos_categ': prod_uos_categ,
|
||||
}))
|
||||
result = mod_obj._get_id(cr, uid, 'stock_planning', 'view_stock_sale_forecast_filter')
|
||||
id = mod_obj.read(cr, uid, result, ['res_id'], context=context)
|
||||
|
||||
return {
|
||||
'domain': "[('id','in', ["+','.join(map(str, forecast_lines))+"])]",
|
||||
'view_type': 'form',
|
||||
"view_mode": 'tree, form',
|
||||
"view_mode": 'tree,form',
|
||||
'res_model': 'stock.sale.forecast',
|
||||
'type': 'ir.actions.act_window',
|
||||
'search_view_id': id['res_id'],
|
||||
}
|
||||
|
||||
stock_sale_forecast_createlines()
|
||||
|
||||
@@ -3,22 +3,17 @@
|
||||
<data>
|
||||
|
||||
<!-- Create Forecast section -->
|
||||
|
||||
<record id="view_stock_sale_forecast_createlines_form" model="ir.ui.view">
|
||||
<field name="name">stock.sale.forecast.createlines</field>
|
||||
<field name="model">stock.sale.forecast.createlines</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Create Forecasts Lines">
|
||||
<separator colspan ="4" string="Creates forecast lines for selected warehouse and period."/>
|
||||
<field name="period_id"/>
|
||||
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
||||
<field name="warehouse_id" domain = "[('company_id','=',company_id)] "/>
|
||||
<field name="copy_forecast"/>
|
||||
<field name="product_categ_id" widget="selection"/>
|
||||
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
||||
<newline/>
|
||||
<label colspan ="4" string="Note: Doesn't duplicate existing lines created by you."/>
|
||||
<separator colspan ="4" />
|
||||
<group colspan="4">
|
||||
<button icon="gtk-cancel" special="cancel" string="Close"/>
|
||||
<button icon="gtk-execute" name="create_forecast" string="Create" type="object" />
|
||||
@@ -34,12 +29,10 @@
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="view_stock_sale_forecast_createlines_form"/>
|
||||
<field name="target">new</field>
|
||||
<field name="help">This wizard helps create many forecast lines at once. After creating them you only have to fill in the forecast quantities. The wizard doesn't duplicate the line when another one exist for the same selection.</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_stock_sale_forecast_createlines" name="Create Sales Forecasts"
|
||||
parent="menu_stock_sale_forecast" action="action_stock_sale_forecast_createlines_form" sequence="5"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user