mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
[MIG] stock_demand_estimate_matrix: Migration to 14.0
This commit is contained in:
@@ -3,12 +3,13 @@
|
||||
{
|
||||
"name": "Stock Demand Estimate Matrix",
|
||||
"summary": "Allows to create demand estimates.",
|
||||
"version": "13.0.1.0.0",
|
||||
"version": "14.0.1.0.0",
|
||||
"author": "ForgeFlow, Odoo Community Association (OCA)",
|
||||
"website": "https://github.com/OCA/stock-logistics-warehouse",
|
||||
"category": "Warehouse Management",
|
||||
"category": "Warehouse",
|
||||
"depends": ["stock_demand_estimate", "web_widget_x2many_2d_matrix", "date_range"],
|
||||
"data": [
|
||||
"security/ir.model.access.csv",
|
||||
"views/stock_demand_estimate_view.xml",
|
||||
"views/date_range.xml",
|
||||
"wizards/stock_demand_estimate_wizard_view.xml",
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_stock_demand_estimate_sheet,access stock.demand.estimate.sheet,model_stock_demand_estimate_sheet,base.group_user,1,1,1,1
|
||||
access_stock_demand_estimate_sheet_line,access stock.demand.estimate.sheet.line,model_stock_demand_estimate_sheet_line,base.group_user,1,1,1,1
|
||||
access_stock_demand_estimate_wizard,access stock.demand.estimate.wizard,model_stock_demand_estimate_wizard,base.group_user,1,1,1,1
|
||||
|
@@ -2,7 +2,7 @@
|
||||
<odoo>
|
||||
<menuitem
|
||||
id="date_range_menu"
|
||||
string="Date Ranges"
|
||||
name="Date Ranges"
|
||||
parent="stock.menu_stock_config_settings"
|
||||
action="date_range.date_range_action"
|
||||
sequence="99"
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import stock_demand_estimate_wizard
|
||||
from . import stock_demand_estimate_sheet
|
||||
from . import stock_demand_estimate_sheet_line
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
# Copyright 2019 ForgeFlow S.L. (https://www.forgeflow.com)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.osv import expression
|
||||
|
||||
|
||||
class StockDemandEstimateSheet(models.TransientModel):
|
||||
_name = "stock.demand.estimate.sheet"
|
||||
_description = "Stock Demand Estimate Sheet"
|
||||
|
||||
date_start = fields.Date(
|
||||
string="Date From",
|
||||
readonly=True,
|
||||
)
|
||||
date_end = fields.Date(
|
||||
string="Date to",
|
||||
readonly=True,
|
||||
)
|
||||
date_range_type_id = fields.Many2one(
|
||||
string="Date Range Type",
|
||||
comodel_name="date.range.type",
|
||||
readonly=True,
|
||||
)
|
||||
location_id = fields.Many2one(
|
||||
comodel_name="stock.location",
|
||||
string="Location",
|
||||
readonly=True,
|
||||
)
|
||||
line_ids = fields.Many2many(
|
||||
string="Estimates",
|
||||
comodel_name="stock.demand.estimate.sheet.line",
|
||||
relation="stock_demand_estimate_line_rel",
|
||||
)
|
||||
product_ids = fields.Many2many(
|
||||
string="Products",
|
||||
comodel_name="product.product",
|
||||
)
|
||||
|
||||
@api.onchange(
|
||||
"date_start",
|
||||
"date_end",
|
||||
"date_range_type_id",
|
||||
)
|
||||
def _onchange_dates(self):
|
||||
for sheet in self:
|
||||
if not all([sheet.date_start, sheet.date_end, sheet.date_range_type_id]):
|
||||
return
|
||||
ranges = sheet._get_ranges()
|
||||
if not ranges:
|
||||
raise UserError(_("There is no ranges created."))
|
||||
estimates = self.env["stock.demand.estimate"].search(
|
||||
[
|
||||
("product_id", "in", sheet.product_ids.ids),
|
||||
("date_range_id", "in", ranges.ids),
|
||||
("location_id", "=", sheet.location_id.id),
|
||||
]
|
||||
)
|
||||
lines = []
|
||||
for product in sheet.product_ids:
|
||||
for _range in ranges:
|
||||
estimate = estimates.filtered(
|
||||
lambda x: (
|
||||
x.date_range_id == _range and x.product_id == product
|
||||
)
|
||||
)
|
||||
if estimate:
|
||||
uom_id = fields.first(estimate).product_uom.id
|
||||
uom_qty = estimate[0].product_uom_qty
|
||||
estimate_id = estimate[0].id
|
||||
else:
|
||||
uom_id = product.uom_id.id
|
||||
uom_qty = 0.0
|
||||
estimate_id = None
|
||||
lines.append(
|
||||
(
|
||||
0,
|
||||
0,
|
||||
sheet._get_default_estimate_line(
|
||||
_range,
|
||||
product,
|
||||
uom_id,
|
||||
uom_qty,
|
||||
estimate_id=estimate_id,
|
||||
),
|
||||
)
|
||||
)
|
||||
sheet.line_ids = lines
|
||||
|
||||
def _get_ranges(self):
|
||||
domain_1 = [
|
||||
"&",
|
||||
("type_id", "=", self.date_range_type_id.id),
|
||||
"|",
|
||||
"&",
|
||||
("date_start", ">=", self.date_start),
|
||||
("date_start", "<=", self.date_end),
|
||||
"&",
|
||||
("date_end", ">=", self.date_start),
|
||||
("date_end", "<=", self.date_end),
|
||||
]
|
||||
domain_2 = [
|
||||
"&",
|
||||
("type_id", "=", self.date_range_type_id.id),
|
||||
"&",
|
||||
("date_start", "<=", self.date_start),
|
||||
("date_end", ">=", self.date_start),
|
||||
]
|
||||
domain = expression.OR([domain_1, domain_2])
|
||||
ranges = self.env["date.range"].search(domain)
|
||||
return ranges
|
||||
|
||||
def _get_default_estimate_line(
|
||||
self, _range, product, uom_id, uom_qty, estimate_id=None
|
||||
):
|
||||
name_y = "{} - {}".format(product.name, product.uom_id.name)
|
||||
if product.default_code:
|
||||
name_y += "[{}] {}".format(product.default_code, name_y)
|
||||
values = {
|
||||
"value_x": _range.name,
|
||||
"value_y": name_y,
|
||||
"date_range_id": _range.id,
|
||||
"product_id": product.id,
|
||||
"product_uom": uom_id,
|
||||
"product_uom_qty": uom_qty,
|
||||
"location_id": self.location_id.id,
|
||||
"estimate_id": estimate_id,
|
||||
}
|
||||
return values
|
||||
|
||||
@api.model
|
||||
def _prepare_estimate_data(self, line):
|
||||
return {
|
||||
"date_range_id": line.date_range_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,
|
||||
}
|
||||
|
||||
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
|
||||
@@ -0,0 +1,20 @@
|
||||
# Copyright 2019 ForgeFlow S.L. (https://www.forgeflow.com)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
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")
|
||||
date_range_id = fields.Many2one(comodel_name="date.range", 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 Name")
|
||||
value_y = fields.Char(string="Product Name")
|
||||
product_uom = fields.Many2one(comodel_name="uom.uom", string="Unit of measure")
|
||||
product_uom_qty = fields.Float(string="Quantity", digits="Product UoM")
|
||||
@@ -3,178 +3,6 @@
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.osv import expression
|
||||
|
||||
|
||||
class StockDemandEstimateSheet(models.TransientModel):
|
||||
_name = "stock.demand.estimate.sheet"
|
||||
_description = "Stock Demand Estimate Sheet"
|
||||
|
||||
date_start = fields.Date(
|
||||
string="Date From",
|
||||
readonly=True,
|
||||
)
|
||||
date_end = fields.Date(
|
||||
string="Date to",
|
||||
readonly=True,
|
||||
)
|
||||
date_range_type_id = fields.Many2one(
|
||||
string="Date Range Type",
|
||||
comodel_name="date.range.type",
|
||||
readonly=True,
|
||||
)
|
||||
location_id = fields.Many2one(
|
||||
comodel_name="stock.location",
|
||||
string="Location",
|
||||
readonly=True,
|
||||
)
|
||||
line_ids = fields.Many2many(
|
||||
string="Estimates",
|
||||
comodel_name="stock.demand.estimate.sheet.line",
|
||||
relation="stock_demand_estimate_line_rel",
|
||||
)
|
||||
product_ids = fields.Many2many(
|
||||
string="Products",
|
||||
comodel_name="product.product",
|
||||
)
|
||||
|
||||
@api.onchange(
|
||||
"date_start",
|
||||
"date_end",
|
||||
"date_range_type_id",
|
||||
)
|
||||
def _onchange_dates(self):
|
||||
for sheet in self:
|
||||
if not all([sheet.date_start, sheet.date_end, sheet.date_range_type_id]):
|
||||
return
|
||||
ranges = sheet._get_ranges()
|
||||
if not ranges:
|
||||
raise UserError(_("There is no ranges created."))
|
||||
estimates = self.env["stock.demand.estimate"].search(
|
||||
[
|
||||
("product_id", "in", sheet.product_ids.ids),
|
||||
("date_range_id", "in", ranges.ids),
|
||||
("location_id", "=", sheet.location_id.id),
|
||||
]
|
||||
)
|
||||
lines = []
|
||||
for product in sheet.product_ids:
|
||||
for _range in ranges:
|
||||
estimate = estimates.filtered(
|
||||
lambda x: (
|
||||
x.date_range_id == _range and x.product_id == product
|
||||
)
|
||||
)
|
||||
if estimate:
|
||||
uom_id = fields.first(estimate).product_uom.id
|
||||
uom_qty = estimate[0].product_uom_qty
|
||||
estimate_id = estimate[0].id
|
||||
else:
|
||||
uom_id = product.uom_id.id
|
||||
uom_qty = 0.0
|
||||
estimate_id = None
|
||||
lines.append(
|
||||
(
|
||||
0,
|
||||
0,
|
||||
sheet._get_default_estimate_line(
|
||||
_range,
|
||||
product,
|
||||
uom_id,
|
||||
uom_qty,
|
||||
estimate_id=estimate_id,
|
||||
),
|
||||
)
|
||||
)
|
||||
sheet.line_ids = lines
|
||||
|
||||
def _get_ranges(self):
|
||||
domain_1 = [
|
||||
"&",
|
||||
("type_id", "=", self.date_range_type_id.id),
|
||||
"|",
|
||||
"&",
|
||||
("date_start", ">=", self.date_start),
|
||||
("date_start", "<=", self.date_end),
|
||||
"&",
|
||||
("date_end", ">=", self.date_start),
|
||||
("date_end", "<=", self.date_end),
|
||||
]
|
||||
domain_2 = [
|
||||
"&",
|
||||
("type_id", "=", self.date_range_type_id.id),
|
||||
"&",
|
||||
("date_start", "<=", self.date_start),
|
||||
("date_end", ">=", self.date_start),
|
||||
]
|
||||
domain = expression.OR([domain_1, domain_2])
|
||||
ranges = self.env["date.range"].search(domain)
|
||||
return ranges
|
||||
|
||||
def _get_default_estimate_line(
|
||||
self, _range, product, uom_id, uom_qty, estimate_id=None
|
||||
):
|
||||
name_y = "{} - {}".format(product.name, product.uom_id.name)
|
||||
if product.default_code:
|
||||
name_y += "[{}] {}".format(product.default_code, name_y)
|
||||
values = {
|
||||
"value_x": _range.name,
|
||||
"value_y": name_y,
|
||||
"date_range_id": _range.id,
|
||||
"product_id": product.id,
|
||||
"product_uom": uom_id,
|
||||
"product_uom_qty": uom_qty,
|
||||
"location_id": self.location_id.id,
|
||||
"estimate_id": estimate_id,
|
||||
}
|
||||
return values
|
||||
|
||||
@api.model
|
||||
def _prepare_estimate_data(self, line):
|
||||
return {
|
||||
"date_range_id": line.date_range_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,
|
||||
}
|
||||
|
||||
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")
|
||||
date_range_id = fields.Many2one(comodel_name="date.range", 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 Name")
|
||||
value_y = fields.Char(string="Product Name")
|
||||
product_uom = fields.Many2one(comodel_name="uom.uom", string="Unit of measure")
|
||||
product_uom_qty = fields.Float(string="Quantity", digits="Product UoM")
|
||||
|
||||
|
||||
class DemandEstimateWizard(models.TransientModel):
|
||||
|
||||
@@ -85,14 +85,13 @@
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<act_window
|
||||
name="Create Stock Demand Estimates"
|
||||
res_model="stock.demand.estimate.wizard"
|
||||
binding_model="stock.demand.estimate.sheet"
|
||||
view_mode="form"
|
||||
target="new"
|
||||
id="stock_demand_estimate_wizard_action"
|
||||
/>
|
||||
<record id="stock_demand_estimate_wizard_action" model="ir.actions.act_window">
|
||||
<field name="name">Create Stock Demand Estimates</field>
|
||||
<field name="res_model">stock.demand.estimate.wizard</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="binding_model_id" ref="model_stock_demand_estimate_sheet" />
|
||||
</record>
|
||||
<menuitem
|
||||
id="stock_demand_estimate_wizard_menu"
|
||||
parent="stock_demand_estimate.stock_demand_planning_menu"
|
||||
|
||||
Reference in New Issue
Block a user