mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
[ADD] new module 'stock_demand_estimate'
This commit is contained in:
committed by
Lois Rilo
parent
fe20ebe435
commit
0f9f956132
76
stock_demand_estimate/README.rst
Normal file
76
stock_demand_estimate/README.rst
Normal file
@@ -0,0 +1,76 @@
|
||||
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
|
||||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||
:alt: License: AGPL-3
|
||||
|
||||
=====================
|
||||
Stock Demand Estimate
|
||||
=====================
|
||||
|
||||
This module allows to create demand estimates for a given product and
|
||||
location, on configurable time periods.
|
||||
|
||||
The module does not provide in itself any specific usage of the estimates.
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
This module relies on the OCA module '2D matrix for x2many fields', and can
|
||||
be downloaded from:
|
||||
* Github: https://github.com/OCA/web/tree/8.0/web_widget_x2many_2d_matrix
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Go to 'Warehouse / Configuration / Demand Estimate Periods' and define your
|
||||
estimating periods (monthly or weekly).
|
||||
|
||||
|
||||
Go to 'Warehouse / Demand Planning / Create Demand Estimates' to create or
|
||||
update your demand estimates.
|
||||
|
||||
Go to 'Warehouse / Demand Planning / Demand Estimates' to review the
|
||||
estimates created.
|
||||
|
||||
|
||||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
|
||||
:alt: Try me on Runbot
|
||||
:target: https://runbot.odoo-community.org/runbot/153/8.0
|
||||
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `GitHub Issues
|
||||
<https://github.com/OCA/stock-logistics-warehouse/issues>`_. In case of trouble, please
|
||||
check there if your issue has already been reported. If you spotted it first,
|
||||
help us smashing it by providing a detailed and welcomed feedback.
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Images
|
||||
------
|
||||
|
||||
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
* Jordi Ballester Alomar <jordi.ballester@eficent.com>
|
||||
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
|
||||
.. image:: https://odoo-community.org/logo.png
|
||||
:alt: Odoo Community Association
|
||||
:target: https://odoo-community.org
|
||||
|
||||
This module is maintained by the OCA.
|
||||
|
||||
OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||
mission is to support the collaborative development of Odoo features and
|
||||
promote its widespread use.
|
||||
|
||||
To contribute to this module, please visit https://odoo-community.org.
|
||||
7
stock_demand_estimate/__init__.py
Normal file
7
stock_demand_estimate/__init__.py
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016 Eficent Business and IT Consulting Services S.L.
|
||||
# (http://www.eficent.com)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import models
|
||||
from . import wizards
|
||||
25
stock_demand_estimate/__openerp__.py
Normal file
25
stock_demand_estimate/__openerp__.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016 Eficent Business and IT Consulting Services S.L.
|
||||
# (http://www.eficent.com)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
{
|
||||
"name": "Stock Demand Estimate",
|
||||
"summary": "Allows to create demand estimates.",
|
||||
"version": "8.0.1.0.0",
|
||||
"author": "Eficent Business and IT Consulting Services S.L,"
|
||||
"Odoo Community Association (OCA)",
|
||||
"website": "https://www.odoo-community.org",
|
||||
"category": "Warehouse Management",
|
||||
"depends": ["stock",
|
||||
"web_widget_x2many_2d_matrix"
|
||||
],
|
||||
"data": ["security/ir.model.access.csv",
|
||||
"security/stock_security.xml",
|
||||
"views/stock_demand_estimate_period_view.xml",
|
||||
"views/stock_demand_estimate_view.xml",
|
||||
"wizards/stock_demand_estimate_wizard_view.xml",
|
||||
],
|
||||
"license": "AGPL-3",
|
||||
'installable': True,
|
||||
'application': True,
|
||||
}
|
||||
7
stock_demand_estimate/models/__init__.py
Normal file
7
stock_demand_estimate/models/__init__.py
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016 Eficent Business and IT Consulting Services S.L.
|
||||
# (http://www.eficent.com)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import stock_demand_estimate_period
|
||||
from . import stock_demand_estimate
|
||||
82
stock_demand_estimate/models/stock_demand_estimate.py
Normal file
82
stock_demand_estimate/models/stock_demand_estimate.py
Normal file
@@ -0,0 +1,82 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Eficent Business and IT Consulting Services S.L.
|
||||
# (http://www.eficent.com)
|
||||
# © 2016 Aleph Objects, Inc. (https://www.alephobjects.com/)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from openerp import api, fields, models, _
|
||||
import openerp.addons.decimal_precision as dp
|
||||
from openerp.exceptions import Warning as UserError
|
||||
|
||||
|
||||
class StockDemandEstimate(models.Model):
|
||||
_name = 'stock.demand.estimate'
|
||||
_description = 'Stock Demand Estimate Line'
|
||||
|
||||
@api.multi
|
||||
@api.depends('product_id', 'product_uom', 'product_uom_qty')
|
||||
def _compute_product_qty(self):
|
||||
for rec in self:
|
||||
if rec.product_uom:
|
||||
rec.product_qty = rec.product_uom._compute_qty(
|
||||
rec.product_id.uom_id.id, rec.product_uom_qty,
|
||||
rec.product_uom.id)
|
||||
|
||||
def _set_product_qty(self):
|
||||
raise UserError(_('The requested operation cannot be '
|
||||
'processed because of a programming error '
|
||||
'setting the `product_qty` field instead '
|
||||
'of the `product_uom_qty`.'))
|
||||
|
||||
@api.multi
|
||||
def _compute_daily_qty(self):
|
||||
for rec in self:
|
||||
rec.daily_qty = rec.product_qty / rec.period_id.days
|
||||
|
||||
period_id = fields.Many2one(
|
||||
comodel_name="stock.demand.estimate.period",
|
||||
string="Estimating Period",
|
||||
required=True)
|
||||
product_id = fields.Many2one(comodel_name="product.product",
|
||||
string="Product", required=True)
|
||||
product_uom = fields.Many2one(comodel_name="product.uom",
|
||||
string="Unit of measure")
|
||||
location_id = fields.Many2one(comodel_name="stock.location",
|
||||
string="Location", required=True)
|
||||
product_uom_qty = fields.Float(
|
||||
string="Quantity",
|
||||
digits_compute=dp.get_precision('Product Unit of Measure'))
|
||||
product_qty = fields.Float('Real Quantity', compute='_compute_product_qty',
|
||||
inverse='_set_product_qty', digits=0,
|
||||
store=True,
|
||||
help='Quantity in the default UoM of the '
|
||||
'product', readonly=True)
|
||||
daily_qty = fields.Float(string='Quantity / Day',
|
||||
compute='_compute_daily_qty')
|
||||
company_id = fields.Many2one(
|
||||
comodel_name='res.company', string='Company', required=True,
|
||||
default=lambda self: self.env['res.company']._company_default_get(
|
||||
'stock.demand.estimate'))
|
||||
|
||||
@api.multi
|
||||
def name_get(self):
|
||||
res = []
|
||||
for rec in self:
|
||||
name = "%s - %s - %s" % (rec.period_id.name, rec.product_id.name,
|
||||
rec.location_id.name)
|
||||
res.append((rec.id, name))
|
||||
return res
|
||||
|
||||
@api.model
|
||||
def get_quantity_by_date_range(self, date_from, date_to):
|
||||
# Check if the dates overlap with the period
|
||||
period_date_from = fields.Date.from_string(self.period_id.date_from)
|
||||
period_date_to = fields.Date.from_string(self.period_id.date_to)
|
||||
|
||||
if date_from <= period_date_to and period_date_from <= date_to:
|
||||
overlap_date_from = max(period_date_from, date_from)
|
||||
overlap_date_to = min(period_date_to, date_to)
|
||||
days = (abs(overlap_date_to-overlap_date_from)).days + 1
|
||||
return days * self.daily_qty
|
||||
return 0.0
|
||||
|
||||
49
stock_demand_estimate/models/stock_demand_estimate_period.py
Normal file
49
stock_demand_estimate/models/stock_demand_estimate_period.py
Normal file
@@ -0,0 +1,49 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Eficent Business and IT Consulting Services S.L.
|
||||
# (http://www.eficent.com)
|
||||
# © 2016 Aleph Objects, Inc. (https://www.alephobjects.com/)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from openerp import api, fields, models, _
|
||||
from openerp.exceptions import Warning as UserError
|
||||
|
||||
|
||||
class StockDemandEstimatePeriod(models.Model):
|
||||
_name = 'stock.demand.estimate.period'
|
||||
_description = 'Stock Demand Estimate Period'
|
||||
_order = 'date_from'
|
||||
|
||||
@api.multi
|
||||
@api.depends('date_from', 'date_to')
|
||||
def _compute_days(self):
|
||||
for rec in self:
|
||||
if rec.date_from and rec.date_to:
|
||||
rec.days = (fields.Date.from_string(rec.date_to) -
|
||||
fields.Date.from_string(rec.date_from)).days + 1
|
||||
|
||||
name = fields.Char(string="Name", required=True)
|
||||
date_from = fields.Date(string="Date From", required=True)
|
||||
date_to = fields.Date(string="Date To", required=True)
|
||||
days = fields.Float(string="Days between dates",
|
||||
compute='_compute_days', store=True, readonly=True)
|
||||
|
||||
estimate_ids = fields.One2many(
|
||||
comodel_name="stock.demand.estimate",
|
||||
inverse_name="period_id")
|
||||
|
||||
company_id = fields.Many2one(
|
||||
comodel_name='res.company', string='Company', required=True,
|
||||
default=lambda self: self.env['res.company']._company_default_get(
|
||||
'stock.demand.estimate.period'))
|
||||
|
||||
@api.multi
|
||||
@api.constrains('name', 'date_from', 'date_to')
|
||||
def _check_period(self):
|
||||
for period in self:
|
||||
self.env.cr.execute('SELECT id, date_from, date_to \
|
||||
FROM stock_demand_estimate_period \
|
||||
WHERE (date_from <= %s and %s <= date_to) \
|
||||
AND id <> %s', (period.date_to, period.date_from, period.id))
|
||||
res = self.env.cr.fetchall()
|
||||
if res:
|
||||
raise UserError(_('Two periods cannot overlap.'))
|
||||
5
stock_demand_estimate/security/ir.model.access.csv
Normal file
5
stock_demand_estimate/security/ir.model.access.csv
Normal file
@@ -0,0 +1,5 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_stock_demand_estimate,stock.orderpoint.demand.estimate,model_stock_demand_estimate,stock.group_stock_user,1,0,0,0
|
||||
access_stock_demand_estimate_system,stock.orderpoint.demand.estimate system,model_stock_demand_estimate,stock.group_stock_manager,1,1,1,1
|
||||
access_stock_demand_estimate_period,stock.orderpoint.demand.estimate.period,model_stock_demand_estimate_period,stock.group_stock_user,1,0,0,0
|
||||
access_stock_demand_estimate_period_system,stock.orderpoint.demand.estimate.period system,model_stock_demand_estimate_period,stock.group_stock_manager,1,1,1,1
|
||||
|
22
stock_demand_estimate/security/stock_security.xml
Normal file
22
stock_demand_estimate/security/stock_security.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
|
||||
<data noupdate="1">
|
||||
|
||||
<record model="ir.rule" id="stock_demand_estimate_comp_rule">
|
||||
<field name="name">Stock demand estimate multi-company</field>
|
||||
<field name="model_id" ref="model_stock_demand_estimate"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.rule" id="stock_demand_estimate_period_comp_rule">
|
||||
<field name="name">Stock demand estimate multi-company</field>
|
||||
<field name="model_id"
|
||||
ref="model_stock_demand_estimate_period"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
BIN
stock_demand_estimate/static/description/icon.png
Normal file
BIN
stock_demand_estimate/static/description/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.2 KiB |
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record model="ir.ui.view"
|
||||
id="view_stock_demand_estimate_period_tree">
|
||||
<field name="name">stock.demand.estimate.period.tree</field>
|
||||
<field name="model">stock.demand.estimate.period</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Stock Demand Estimate Period" editable="top">
|
||||
<field name="name"/>
|
||||
<field name="date_from"/>
|
||||
<field name="date_to"/>
|
||||
<field name="days"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_stock_demand_estimate_period_search"
|
||||
model="ir.ui.view">
|
||||
<field name="name">stock.demand.estimate.period.search</field>
|
||||
<field name="model">stock.demand.estimate.period</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Stock Demand Estimates">
|
||||
<field name="name"/>
|
||||
<field name="date_from"/>
|
||||
<field name="date_to"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window"
|
||||
id="stock_demand_estimate_period_form_action">
|
||||
<field name="name">Stock Demand Estimate Periods</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">stock.demand.estimate.period</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="search_view_id"
|
||||
ref="view_stock_demand_estimate_period_search"/>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
id="menu_stock_demand_estimate_period"
|
||||
parent="stock.menu_stock_config_settings"
|
||||
action="stock_demand_estimate_period_form_action"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
55
stock_demand_estimate/views/stock_demand_estimate_view.xml
Normal file
55
stock_demand_estimate/views/stock_demand_estimate_view.xml
Normal file
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record model="ir.ui.view"
|
||||
id="view_stock_demand_estimate_tree">
|
||||
<field name="name">stock.demand.estimate.tree</field>
|
||||
<field name="model">stock.demand.estimate</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Stock Demand Estimate" editable="top">
|
||||
<field name="period_id"/>
|
||||
<field name="product_id"/>
|
||||
<field name="location_id"/>
|
||||
<field name="product_uom_qty"/>
|
||||
<field name="product_uom"/>
|
||||
<field name="product_qty"/>
|
||||
<field name="daily_qty"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_stock_demand_estimate_search"
|
||||
model="ir.ui.view">
|
||||
<field name="name">stock.demand.estimate.search</field>
|
||||
<field name="model">stock.demand.estimate</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Stock Demand Estimates">
|
||||
<field name="period_id"/>
|
||||
<field name="product_id"/>
|
||||
<field name="location_id"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window"
|
||||
id="stock_demand_estimate_form_action">
|
||||
<field name="name">Stock Demand Estimates</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">stock.demand.estimate</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="search_view_id"
|
||||
ref="view_stock_demand_estimate_search"/>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_stock_demand_planning" name="Demand Planning"
|
||||
parent="stock.menu_stock_root" sequence="10"/>
|
||||
|
||||
<menuitem
|
||||
id="menu_stock_demand_estimate"
|
||||
parent="menu_stock_demand_planning"
|
||||
action="stock_demand_estimate_form_action"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
6
stock_demand_estimate/wizards/__init__.py
Normal file
6
stock_demand_estimate/wizards/__init__.py
Normal file
@@ -0,0 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016 Eficent Business and IT Consulting Services S.L.
|
||||
# (http://www.eficent.com)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import stock_demand_estimate_wizard
|
||||
189
stock_demand_estimate/wizards/stock_demand_estimate_wizard.py
Normal file
189
stock_demand_estimate/wizards/stock_demand_estimate_wizard.py
Normal file
@@ -0,0 +1,189 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Eficent Business and IT Consulting Services S.L.
|
||||
# (http://www.eficent.com)
|
||||
# © 2016 Aleph Objects, Inc. (https://www.alephobjects.com/)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from openerp import api, fields, models, _
|
||||
import openerp.addons.decimal_precision as dp
|
||||
from openerp.exceptions import Warning as UserError
|
||||
|
||||
_PERIOD_SELECTION = [
|
||||
('monthly', 'Monthly'),
|
||||
('weekly', 'Weekly')
|
||||
]
|
||||
|
||||
|
||||
class StockDemandEstimateSheet(models.TransientModel):
|
||||
_name = 'stock.demand.estimate.sheet'
|
||||
_description = 'Stock Demand Estimate Sheet'
|
||||
|
||||
def _default_date_from(self):
|
||||
return self.env.context.get('date_from', False)
|
||||
|
||||
def _default_date_to(self):
|
||||
return self.env.context.get('date_to', False)
|
||||
|
||||
def _default_location_id(self):
|
||||
location_id = self.env.context.get('location_id', False)
|
||||
if location_id:
|
||||
return self.env['stock.location'].browse(location_id)
|
||||
else:
|
||||
return False
|
||||
|
||||
def _default_estimate_ids(self):
|
||||
date_from = self.env.context.get('date_from', False)
|
||||
date_to = self.env.context.get('date_to', False)
|
||||
location_id = self.env.context.get('location_id', False)
|
||||
product_ids = self.env.context.get('product_ids', False)
|
||||
domain = [('date_from', '>=', date_from),
|
||||
('date_to', '<=', date_to)]
|
||||
periods = self.env['stock.demand.estimate.period'].search(
|
||||
domain)
|
||||
products = self.env['product.product'].browse(product_ids)
|
||||
|
||||
lines = []
|
||||
for product in products:
|
||||
name_y = ''
|
||||
if product.default_code:
|
||||
name_y += '[%s] ' % product.default_code
|
||||
name_y += product.name
|
||||
name_y += ' - %s' % product.uom_id.name
|
||||
for period in periods:
|
||||
estimates = self.env['stock.demand.estimate'].search(
|
||||
[('product_id', '=', product.id),
|
||||
('period_id', '=', period.id),
|
||||
('location_id', '=', location_id)])
|
||||
if estimates:
|
||||
lines.append((0, 0, {
|
||||
'value_x': period.name,
|
||||
'value_y': name_y,
|
||||
'period_id': period.id,
|
||||
'product_id': product.id,
|
||||
'product_uom': estimates[0].product_uom.id,
|
||||
'location_id': location_id,
|
||||
'estimate_id': estimates[0].id,
|
||||
'product_uom_qty': estimates[0].product_uom_qty
|
||||
}))
|
||||
else:
|
||||
lines.append((0, 0, {
|
||||
'value_x': period.name,
|
||||
'value_y': name_y,
|
||||
'period_id': period.id,
|
||||
'product_id': product.id,
|
||||
'product_uom': product.uom_id.id,
|
||||
'location_id': location_id,
|
||||
'product_uom_qty': 0.0
|
||||
}))
|
||||
return lines
|
||||
|
||||
date_from = fields.Date(string="Date From", readonly=True,
|
||||
default=_default_date_from)
|
||||
date_to = fields.Date(string="Date From", readonly=True,
|
||||
default=_default_date_to)
|
||||
location_id = fields.Many2one(comodel_name="stock.location",
|
||||
string="Location", readonly=True,
|
||||
default=_default_location_id)
|
||||
line_ids = fields.Many2many(
|
||||
string="Estimates",
|
||||
comodel_name='stock.demand.estimate.sheet.line',
|
||||
rel='stock_demand_estimate_line_rel',
|
||||
default=_default_estimate_ids)
|
||||
|
||||
@api.model
|
||||
def _prepare_estimate_data(self, line):
|
||||
return {
|
||||
'period_id': line.period_id.id,
|
||||
'product_id': line.product_id.id,
|
||||
'location_id': line.location_id.id,
|
||||
'product_uom_qty': line.product_uom_qty,
|
||||
'product_uom': line.product_id.uom_id.id,
|
||||
}
|
||||
|
||||
@api.multi
|
||||
def button_validate(self):
|
||||
res = []
|
||||
for line in self.line_ids:
|
||||
if line.estimate_id:
|
||||
line.estimate_id.product_uom_qty = line.product_uom_qty
|
||||
res.append(line.estimate_id.id)
|
||||
else:
|
||||
data = self._prepare_estimate_data(line)
|
||||
estimate = self.env['stock.demand.estimate'].create(
|
||||
data)
|
||||
res.append(estimate.id)
|
||||
res = {
|
||||
'domain': [('id', 'in', res)],
|
||||
'name': _('Stock Demand Estimates'),
|
||||
'src_model': 'stock.demand.estimate.wizard',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree',
|
||||
'res_model': 'stock.demand.estimate',
|
||||
'type': 'ir.actions.act_window'
|
||||
}
|
||||
return res
|
||||
|
||||
|
||||
class StockDemandEstimateSheetLine(models.TransientModel):
|
||||
_name = 'stock.demand.estimate.sheet.line'
|
||||
_description = 'Stock Demand Estimate Sheet Line'
|
||||
|
||||
estimate_id = fields.Many2one(comodel_name='stock.demand.estimate')
|
||||
period_id = fields.Many2one(
|
||||
comodel_name='stock.demand.estimate.period',
|
||||
string='Period')
|
||||
location_id = fields.Many2one(comodel_name='stock.location',
|
||||
string="Stock Location")
|
||||
product_id = fields.Many2one(comodel_name='product.product',
|
||||
string='Product')
|
||||
value_x = fields.Char(string='Period')
|
||||
value_y = fields.Char(string='Product')
|
||||
product_uom_qty = fields.Float(
|
||||
string="Quantity", digits_compute=dp.get_precision('Product UoM'))
|
||||
|
||||
|
||||
class DemandEstimateWizard(models.TransientModel):
|
||||
_name = 'stock.demand.estimate.wizard'
|
||||
_description = 'Stock Demand Estimate Wizard'
|
||||
|
||||
date_from = fields.Date(string="Date From", required=True)
|
||||
date_to = fields.Date(string="Date To", required=True)
|
||||
location_id = fields.Many2one(comodel_name="stock.location",
|
||||
string="Location", required=True)
|
||||
product_ids = fields.Many2many(
|
||||
comodel_name="product.product",
|
||||
string="Products")
|
||||
|
||||
@api.multi
|
||||
def _prepare_demand_estimate_sheet(self):
|
||||
self.ensure_one()
|
||||
return {
|
||||
'date_from': self.date_from,
|
||||
'date_to': self.date_to,
|
||||
'location_id': self.location_id.id,
|
||||
}
|
||||
|
||||
@api.multi
|
||||
def create_sheet(self):
|
||||
self.ensure_one()
|
||||
if not self.product_ids:
|
||||
raise UserError(_('You must select at lease one product.'))
|
||||
|
||||
context = {
|
||||
'date_from': self.date_from,
|
||||
'date_to': self.date_to,
|
||||
'location_id': self.location_id.id,
|
||||
'product_ids': self.product_ids.ids
|
||||
}
|
||||
res = {
|
||||
'context': context,
|
||||
'name': _('Estimate Sheet'),
|
||||
'src_model': 'stock.demand.estimate.wizard',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'res_model': 'stock.demand.estimate.sheet',
|
||||
'type': 'ir.actions.act_window'
|
||||
}
|
||||
|
||||
return res
|
||||
@@ -0,0 +1,85 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record model="ir.ui.view"
|
||||
id="view_stock_demand_estimate_sheet_form">
|
||||
<field name="name">stock.demand.estimate.sheet.form</field>
|
||||
<field name="model">stock.demand.estimate.sheet</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Stock Demand Estimate Sheet">
|
||||
<group>
|
||||
<group name="dates">
|
||||
<label for="date_from" string="Timesheet Period"/>
|
||||
<div><field name="date_from" class="oe_inline"/> to <field name="date_to" class="oe_inline"/></div>
|
||||
</group>
|
||||
<div/>
|
||||
<group name="attributes">
|
||||
<field name="location_id"/>
|
||||
</group>
|
||||
</group>
|
||||
<div/>
|
||||
<group string="Estimated quantity">
|
||||
<field name="line_ids" nolabel="1"
|
||||
widget="x2many_2d_matrix"
|
||||
field_x_axis="value_x"
|
||||
field_y_axis="value_y"
|
||||
field_value="product_uom_qty"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="button_validate"
|
||||
type="object"
|
||||
string="Validate"
|
||||
class="oe_highlight"/>
|
||||
<button class="oe_link"
|
||||
special="cancel"
|
||||
string="Cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view"
|
||||
id="view_demand_estimate_wizard_form">
|
||||
<field name="name">stock.demand.estimate.wizard.form</field>
|
||||
<field name="model">stock.demand.estimate.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Stock Demand Estimate Wizard">
|
||||
<group>
|
||||
<group name="dates">
|
||||
<label for="date_from" string="Period"/>
|
||||
<div><field name="date_from" class="oe_inline"/> to <field name="date_to" class="oe_inline"/></div>
|
||||
</group>
|
||||
<div/>
|
||||
<group name="attributes">
|
||||
<field name="location_id"/>
|
||||
</group>
|
||||
</group>
|
||||
<div/>
|
||||
<group name="products" string="Products">
|
||||
<field name="product_ids" nolabel="1"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="create_sheet" string="Prepare"
|
||||
type="object" class="oe_highlight" /> or
|
||||
<button string="Cancel" class="oe_link" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<act_window name="Create Stock Demand Estimates"
|
||||
res_model="stock.demand.estimate.wizard"
|
||||
src_model="stock.demand.estimate.sheet"
|
||||
view_mode="form"
|
||||
target="new"
|
||||
key2="client_action_multi"
|
||||
id="action_stock_demand_estimate_wizard"/>
|
||||
|
||||
<menuitem
|
||||
id="menu_stock_demand_estimate_wizard"
|
||||
parent="menu_stock_demand_planning"
|
||||
action="action_stock_demand_estimate_wizard"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
Reference in New Issue
Block a user