replace demand estimate periods with date range

This commit is contained in:
Jordi Ballester
2017-05-30 16:50:47 +02:00
committed by Jordi Ballester Alomar
parent 403b8a956e
commit 2e44fb7f9f
13 changed files with 113 additions and 176 deletions

View File

@@ -1,2 +1,4 @@
stock-logistics-tracking stock-logistics-tracking
stock-logistics-barcode stock-logistics-barcode
server-tools
web

View File

@@ -14,9 +14,12 @@ The module does not provide in itself any specific usage of the estimates.
Installation Installation
============ ============
This module relies on the OCA module '2D matrix for x2many fields', and can This module relies on:
be downloaded from:
* Github: https://github.com/OCA/web/tree/8.0/web_widget_x2many_2d_matrix * The OCA module '2D matrix for x2many fields', and can be downloaded from
Github: https://github.com/OCA/web/tree/9.0/web_widget_x2many_2d_matrix
* The OCA module 'Date Range', and can be downloaded from
Github: https://github.com/OCA/server-tools/tree/9.0/date_range
Usage Usage

View File

@@ -11,11 +11,11 @@
"website": "https://www.odoo-community.org", "website": "https://www.odoo-community.org",
"category": "Warehouse Management", "category": "Warehouse Management",
"depends": ["stock", "depends": ["stock",
"web_widget_x2many_2d_matrix" "web_widget_x2many_2d_matrix",
"date_range"
], ],
"data": ["security/ir.model.access.csv", "data": ["security/ir.model.access.csv",
"security/stock_security.xml", "security/stock_security.xml",
"views/stock_demand_estimate_period_view.xml",
"views/stock_demand_estimate_view.xml", "views/stock_demand_estimate_view.xml",
"wizards/stock_demand_estimate_wizard_view.xml", "wizards/stock_demand_estimate_wizard_view.xml",
], ],

View File

@@ -3,5 +3,5 @@
# (http://www.eficent.com) # (http://www.eficent.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from . import stock_demand_estimate_period
from . import stock_demand_estimate from . import stock_demand_estimate
from . import date_range

View File

@@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# © 2016 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp import api, fields, models
from openerp.tools.translate import _
from openerp.exceptions import ValidationError
class DateRange(models.Model):
_inherit = "date.range"
@api.multi
@api.depends('date_start', 'date_end')
def _compute_days(self):
for rec in self:
if rec.date_start and rec.date_end:
rec.days = (fields.Date.from_string(rec.date_start) -
fields.Date.from_string(rec.date_end)).days + 1
days = fields.Float(string="Days between dates",
compute='_compute_days', store=True, readonly=True)

View File

@@ -31,10 +31,10 @@ class StockDemandEstimate(models.Model):
@api.multi @api.multi
def _compute_daily_qty(self): def _compute_daily_qty(self):
for rec in self: for rec in self:
rec.daily_qty = rec.product_qty / rec.period_id.days rec.daily_qty = rec.product_qty / rec.date_range_id.days
period_id = fields.Many2one( date_range_id = fields.Many2one(
comodel_name="stock.demand.estimate.period", comodel_name="date.range",
string="Estimating Period", string="Estimating Period",
required=True) required=True)
product_id = fields.Many2one(comodel_name="product.product", product_id = fields.Many2one(comodel_name="product.product",
@@ -62,21 +62,26 @@ class StockDemandEstimate(models.Model):
def name_get(self): def name_get(self):
res = [] res = []
for rec in self: for rec in self:
name = "%s - %s - %s" % (rec.period_id.name, rec.product_id.name, name = "%s - %s - %s" % (rec.date_range_id.name, rec.product_id.name,
rec.location_id.name) rec.location_id.name)
res.append((rec.id, name)) res.append((rec.id, name))
return res return res
@api.model @api.model
def get_quantity_by_date_range(self, date_from, date_to): def get_quantity_by_date_range(self, date_start, date_end):
# Check if the dates overlap with the period # Check if the dates overlap with the period
period_date_from = fields.Date.from_string(self.period_id.date_from) period_date_start = fields.Date.from_string(
period_date_to = fields.Date.from_string(self.period_id.date_to) self.date_range_id.date_start)
period_date_end = fields.Date.from_string(
self.date_range_id.date_end)
if date_from <= period_date_to and period_date_from <= date_to: # We need only the periods that overlap
overlap_date_from = max(period_date_from, date_from) # the dates introduced by the user.
overlap_date_to = min(period_date_to, date_to) if (date_start <= period_date_start <= date_end
days = (abs(overlap_date_to-overlap_date_from)).days + 1 or date_start <= period_date_end <= date_end):
overlap_date_start = max(period_date_start, date_start)
overlap_date_end = min(period_date_end, date_end)
days = (abs(overlap_date_end-overlap_date_start)).days + 1
return days * self.daily_qty return days * self.daily_qty
return 0.0 return 0.0

View File

@@ -1,49 +0,0 @@
# -*- 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.'))

View File

@@ -1,5 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink 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,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_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
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_stock_demand_estimate stock.orderpoint.demand.estimate model_stock_demand_estimate stock.group_stock_user 1 0 0 0
3 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

View File

@@ -1,22 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<openerp> <openerp>
<data noupdate="1"> <data noupdate="1">
<record model="ir.rule" id="stock_demand_estimate_comp_rule"> <record model="ir.rule" id="stock_demand_estimate_comp_rule">
<field name="name">Stock demand estimate multi-company</field> <field name="name">Stock demand estimate multi-company</field>
<field name="model_id" ref="model_stock_demand_estimate"/> <field name="model_id" ref="model_stock_demand_estimate"/>
<field name="global" eval="True"/> <field name="global" eval="True"/>
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field> <field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
</record> </record>
<record model="ir.rule" id="stock_demand_estimate_period_comp_rule"> </data>
<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> </openerp>

View File

@@ -1,49 +0,0 @@
<?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>

View File

@@ -8,7 +8,7 @@
<field name="model">stock.demand.estimate</field> <field name="model">stock.demand.estimate</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Stock Demand Estimate" editable="top"> <tree string="Stock Demand Estimate" editable="top">
<field name="period_id"/> <field name="date_range_id"/>
<field name="product_id"/> <field name="product_id"/>
<field name="location_id"/> <field name="location_id"/>
<field name="product_uom_qty"/> <field name="product_uom_qty"/>
@@ -25,7 +25,7 @@
<field name="model">stock.demand.estimate</field> <field name="model">stock.demand.estimate</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="Search Stock Demand Estimates"> <search string="Search Stock Demand Estimates">
<field name="period_id"/> <field name="date_range_id"/>
<field name="product_id"/> <field name="product_id"/>
<field name="location_id"/> <field name="location_id"/>
</search> </search>

View File

@@ -8,21 +8,16 @@ from openerp import api, fields, models, _
import openerp.addons.decimal_precision as dp import openerp.addons.decimal_precision as dp
from openerp.exceptions import Warning as UserError from openerp.exceptions import Warning as UserError
_PERIOD_SELECTION = [
('monthly', 'Monthly'),
('weekly', 'Weekly')
]
class StockDemandEstimateSheet(models.TransientModel): class StockDemandEstimateSheet(models.TransientModel):
_name = 'stock.demand.estimate.sheet' _name = 'stock.demand.estimate.sheet'
_description = 'Stock Demand Estimate Sheet' _description = 'Stock Demand Estimate Sheet'
def _default_date_from(self): def _default_date_start(self):
return self.env.context.get('date_from', False) return self.env.context.get('date_start', False)
def _default_date_to(self): def _default_date_end(self):
return self.env.context.get('date_to', False) return self.env.context.get('date_end', False)
def _default_location_id(self): def _default_location_id(self):
location_id = self.env.context.get('location_id', False) location_id = self.env.context.get('location_id', False)
@@ -32,13 +27,24 @@ class StockDemandEstimateSheet(models.TransientModel):
return False return False
def _default_estimate_ids(self): def _default_estimate_ids(self):
date_from = self.env.context.get('date_from', False) date_start = self.env.context.get('default_date_start', False)
date_to = self.env.context.get('date_to', False) date_end = self.env.context.get('default_date_end', False)
location_id = self.env.context.get('location_id', False) date_range_type_id = self.env.context.get('default_date_range_type_id',
product_ids = self.env.context.get('product_ids', False) False)
domain = [('date_from', '>=', date_from), location_id = self.env.context.get('default_location_id', False)
('date_to', '<=', date_to)] product_ids = self.env.context.get('default_product_ids', False)
periods = self.env['stock.demand.estimate.period'].search( domain = [('type_id', '=', date_range_type_id), '|', '&',
('date_start', '>=', date_start),
('date_start', '<=', date_end),
'&',
('date_end', '>=', date_start),
('date_end', '<=', date_end)]
periods = self.env['date.range'].search(
domain)
domain = [('type_id', '=', date_range_type_id),
('date_start', '<=', date_start),
('date_end', '>=', date_start)]
periods |= self.env['date.range'].search(
domain) domain)
products = self.env['product.product'].browse(product_ids) products = self.env['product.product'].browse(product_ids)
@@ -52,13 +58,13 @@ class StockDemandEstimateSheet(models.TransientModel):
for period in periods: for period in periods:
estimates = self.env['stock.demand.estimate'].search( estimates = self.env['stock.demand.estimate'].search(
[('product_id', '=', product.id), [('product_id', '=', product.id),
('period_id', '=', period.id), ('date_range_id', '=', period.id),
('location_id', '=', location_id)]) ('location_id', '=', location_id)])
if estimates: if estimates:
lines.append((0, 0, { lines.append((0, 0, {
'value_x': period.name, 'value_x': period.name,
'value_y': name_y, 'value_y': name_y,
'period_id': period.id, 'date_range_id': period.id,
'product_id': product.id, 'product_id': product.id,
'product_uom': estimates[0].product_uom.id, 'product_uom': estimates[0].product_uom.id,
'location_id': location_id, 'location_id': location_id,
@@ -69,7 +75,7 @@ class StockDemandEstimateSheet(models.TransientModel):
lines.append((0, 0, { lines.append((0, 0, {
'value_x': period.name, 'value_x': period.name,
'value_y': name_y, 'value_y': name_y,
'period_id': period.id, 'date_range_id': period.id,
'product_id': product.id, 'product_id': product.id,
'product_uom': product.uom_id.id, 'product_uom': product.uom_id.id,
'location_id': location_id, 'location_id': location_id,
@@ -77,13 +83,13 @@ class StockDemandEstimateSheet(models.TransientModel):
})) }))
return lines return lines
date_from = fields.Date(string="Date From", readonly=True, date_start = fields.Date(string="Date From", readonly=True)
default=_default_date_from) date_end = fields.Date(string="Date From", readonly=True)
date_to = fields.Date(string="Date From", readonly=True, date_range_type_id = fields.Many2one(string='Date Range Type',
default=_default_date_to) comodel_name='date.range.type',
readonly=True)
location_id = fields.Many2one(comodel_name="stock.location", location_id = fields.Many2one(comodel_name="stock.location",
string="Location", readonly=True, string="Location", readonly=True)
default=_default_location_id)
line_ids = fields.Many2many( line_ids = fields.Many2many(
string="Estimates", string="Estimates",
comodel_name='stock.demand.estimate.sheet.line', comodel_name='stock.demand.estimate.sheet.line',
@@ -93,7 +99,7 @@ class StockDemandEstimateSheet(models.TransientModel):
@api.model @api.model
def _prepare_estimate_data(self, line): def _prepare_estimate_data(self, line):
return { return {
'period_id': line.period_id.id, 'date_range_id': line.date_range_id.id,
'product_id': line.product_id.id, 'product_id': line.product_id.id,
'location_id': line.location_id.id, 'location_id': line.location_id.id,
'product_uom_qty': line.product_uom_qty, 'product_uom_qty': line.product_uom_qty,
@@ -129,7 +135,7 @@ class StockDemandEstimateSheetLine(models.TransientModel):
_description = 'Stock Demand Estimate Sheet Line' _description = 'Stock Demand Estimate Sheet Line'
estimate_id = fields.Many2one(comodel_name='stock.demand.estimate') estimate_id = fields.Many2one(comodel_name='stock.demand.estimate')
period_id = fields.Many2one( date_range_id = fields.Many2one(
comodel_name='stock.demand.estimate.period', comodel_name='stock.demand.estimate.period',
string='Period') string='Period')
location_id = fields.Many2one(comodel_name='stock.location', location_id = fields.Many2one(comodel_name='stock.location',
@@ -146,8 +152,11 @@ class DemandEstimateWizard(models.TransientModel):
_name = 'stock.demand.estimate.wizard' _name = 'stock.demand.estimate.wizard'
_description = 'Stock Demand Estimate Wizard' _description = 'Stock Demand Estimate Wizard'
date_from = fields.Date(string="Date From", required=True) date_start = fields.Date(string="Date From", required=True)
date_to = fields.Date(string="Date To", required=True) date_end = fields.Date(string="Date To", required=True)
date_range_type_id = fields.Many2one(string='Date Range Type',
comodel_name='date.range.type',
required=True)
location_id = fields.Many2one(comodel_name="stock.location", location_id = fields.Many2one(comodel_name="stock.location",
string="Location", required=True) string="Location", required=True)
product_ids = fields.Many2many( product_ids = fields.Many2many(
@@ -158,8 +167,9 @@ class DemandEstimateWizard(models.TransientModel):
def _prepare_demand_estimate_sheet(self): def _prepare_demand_estimate_sheet(self):
self.ensure_one() self.ensure_one()
return { return {
'date_from': self.date_from, 'date_start': self.date_start,
'date_to': self.date_to, 'date_end': self.date_end,
'date_range_type_id': self.date_range_type_id.id,
'location_id': self.location_id.id, 'location_id': self.location_id.id,
} }
@@ -170,10 +180,11 @@ class DemandEstimateWizard(models.TransientModel):
raise UserError(_('You must select at lease one product.')) raise UserError(_('You must select at lease one product.'))
context = { context = {
'date_from': self.date_from, 'default_date_start': self.date_start,
'date_to': self.date_to, 'default_date_end': self.date_end,
'location_id': self.location_id.id, 'default_date_range_type_id': self.date_range_type_id.id,
'product_ids': self.product_ids.ids 'default_location_id': self.location_id.id,
'default_product_ids': self.product_ids.ids
} }
res = { res = {
'context': context, 'context': context,

View File

@@ -10,11 +10,12 @@
<form string="Stock Demand Estimate Sheet"> <form string="Stock Demand Estimate Sheet">
<group> <group>
<group name="dates"> <group name="dates">
<label for="date_from" string="Timesheet Period"/> <label for="date_start" string="Timesheet Period"/>
<div><field name="date_from" class="oe_inline"/> to <field name="date_to" class="oe_inline"/></div> <div><field name="date_start" class="oe_inline"/> to <field name="date_end" class="oe_inline"/></div>
</group> </group>
<div/> <newline/>
<group name="attributes"> <group name="attributes">
<field name="date_range_type_id"/>
<field name="location_id"/> <field name="location_id"/>
</group> </group>
</group> </group>
@@ -47,10 +48,11 @@
<form string="Stock Demand Estimate Wizard"> <form string="Stock Demand Estimate Wizard">
<group> <group>
<group name="dates"> <group name="dates">
<label for="date_from" string="Period"/> <label for="date_start" string="Period"/>
<div><field name="date_from" class="oe_inline"/> to <field name="date_to" class="oe_inline"/></div> <div><field name="date_start" class="oe_inline"/> to <field name="date_end" class="oe_inline"/></div>
<field name="date_range_type_id"/>
</group> </group>
<div/> <newline/>
<group name="attributes"> <group name="attributes">
<field name="location_id"/> <field name="location_id"/>
</group> </group>