[MIG] mrp_bom_version: Migration to 16.0

This commit is contained in:
Kay K. Cross
2024-10-18 11:55:17 +02:00
parent c15be7dac5
commit a90ab95717
12 changed files with 243 additions and 269 deletions

View File

@@ -36,8 +36,17 @@ jobs:
matrix:
include:
- container: ghcr.io/oca/oca-ci/py3.10-odoo16.0:latest
include: "mrp_bom_version"
name: test with Odoo
- container: ghcr.io/oca/oca-ci/py3.10-ocb16.0:latest
include: "mrp_bom_version"
name: test with OCB
makepot: "true"
- container: ghcr.io/oca/oca-ci/py3.10-odoo16.0:latest
exclude: "mrp_bom_version"
name: test with Odoo
- container: ghcr.io/oca/oca-ci/py3.10-ocb16.0:latest
exclude: "mrp_bom_version"
name: test with OCB
makepot: "true"
services:
@@ -49,6 +58,9 @@ jobs:
POSTGRES_DB: odoo
ports:
- 5432:5432
env:
INCLUDE: "${{ matrix.include }}"
EXCLUDE: "${{ matrix.exclude }}"
steps:
- uses: actions/checkout@v3
with:

View File

@@ -5,7 +5,7 @@
{
"name": "MRP - BoM version",
"summary": "BoM versioning",
"version": "8.0.1.0.0",
"version": "16.0.1.0.0",
"license": "AGPL-3",
"author": "OdooMRP team,"
"AvanzOSC,"

View File

@@ -1,11 +1,9 @@
<?xml version="1.0" encoding="UTF-8" ?>
<openerp>
<data>
<record id="mt_active" model="mail.message.subtype">
<field name="name">MRP BoM Active</field>
<field name="res_model">mrp.bom</field>
<field name="default" eval="False" />
<field name="description">MRP BoM Active</field>
</record>
</data>
</openerp>
<odoo>
<record id="mt_active" model="mail.message.subtype">
<field name="name">MRP BoM Active</field>
<field name="res_model">mrp.bom</field>
<field name="default" eval="False" />
<field name="description">MRP BoM Active</field>
</record>
</odoo>

View File

@@ -1,28 +1,21 @@
# (c) 2015 Oihane Crucelaegui - AvanzOSC
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
from openerp import api, fields, models
from openerp.tools import config
from odoo import api, fields, models
from odoo.tools import config
class MrpBom(models.Model):
_inherit = "mrp.bom"
_track = {
"state": {
"mrp_bom_version.mt_active": lambda self, cr, uid, obj, ctx=None: obj.state
== "active",
},
}
@api.one
def _get_old_versions(self):
parent = self.parent_bom
old_version = self.env["mrp.bom"]
while parent:
old_version += parent
parent = parent.parent_bom
self.old_versions = old_version
def _compute_old_versions(self):
for bom in self:
parent = bom.parent_bom
old_version = self.env["mrp.bom"]
while parent:
old_version |= parent
parent = parent.parent_bom
bom.old_versions = [(6, 0, old_version.ids)]
def _default_active(self):
"""Needed for preserving normal flow when testing other modules."""
@@ -41,14 +34,14 @@ class MrpBom(models.Model):
active = fields.Boolean(
default=_default_active, readonly=True, states={"draft": [("readonly", False)]}
)
historical_date = fields.Date(string="Historical Date", readonly=True)
historical_date = fields.Date(readonly=True, copy=False)
state = fields.Selection(
selection=[
("draft", "Draft"),
("active", "Active"),
("historical", "Historical"),
],
string="State",
string="Status",
index=True,
readonly=True,
default=_default_state,
@@ -59,23 +52,23 @@ class MrpBom(models.Model):
)
product_id = fields.Many2one(readonly=True, states={"draft": [("readonly", False)]})
product_qty = fields.Float(readonly=True, states={"draft": [("readonly", False)]})
name = fields.Char(states={"historical": [("readonly", True)]})
code = fields.Char(states={"historical": [("readonly", True)]})
type = fields.Selection(states={"historical": [("readonly", True)]})
company_id = fields.Many2one(states={"historical": [("readonly", True)]})
product_uom = fields.Many2one(states={"historical": [("readonly", True)]})
routing_id = fields.Many2one(readonly=True, states={"draft": [("readonly", False)]})
product_uom_id = fields.Many2one(states={"historical": [("readonly", True)]})
bom_line_ids = fields.One2many(
readonly=True, states={"draft": [("readonly", False)]}
)
position = fields.Char(states={"historical": [("readonly", True)]})
date_start = fields.Date(states={"historical": [("readonly", True)]})
date_stop = fields.Date(states={"historical": [("readonly", True)]})
property_ids = fields.Many2many(states={"historical": [("readonly", True)]})
product_rounding = fields.Float(states={"historical": [("readonly", True)]})
product_efficiency = fields.Float(states={"historical": [("readonly", True)]})
message_follower_ids = fields.Many2many(states={"historical": [("readonly", True)]})
message_ids = fields.One2many(states={"historical": [("readonly", True)]})
byproduct_ids = fields.One2many(
readonly=True, states={"draft": [("readonly", False)]}
)
sequence = fields.Integer(states={"historical": [("readonly", True)]})
operation_ids = fields.One2many(
readonly=True, states={"draft": [("readonly", False)]}
)
ready_to_produce = fields.Selection(states={"historical": [("readonly", True)]})
picking_type_id = fields.Many2one(states={"historical": [("readonly", True)]})
consumption = fields.Selection(states={"historical": [("readonly", True)]})
version = fields.Integer(
states={"historical": [("readonly", True)]}, copy=False, default=1
)
@@ -83,20 +76,24 @@ class MrpBom(models.Model):
comodel_name="mrp.bom", string="Parent BoM", copy=False
)
old_versions = fields.Many2many(
comodel_name="mrp.bom", string="Old Versions", compute="_get_old_versions"
comodel_name="mrp.bom", compute="_compute_old_versions"
)
@api.multi
def _track_subtype(self, init_values):
if "state" in init_values and self.state == "active":
return self.env.ref("mrp_bom_version.mt_active")
return super()._track_subtype(init_values)
def button_draft(self):
active_draft = self.env["mrp.config.settings"]._get_parameter("active.draft")
get_param = self.env["ir.config_parameter"].sudo().get_param
active_draft = get_param("mrp_bom_version.active_draft")
self.write(
{
"active": active_draft and active_draft.value or False,
"active": active_draft,
"state": "draft",
}
)
@api.multi
def button_new_version(self):
self.ensure_one()
new_bom = self._copy_bom()
@@ -111,21 +108,20 @@ class MrpBom(models.Model):
}
def _copy_bom(self):
active_draft = self.env["mrp.config.settings"]._get_parameter("active.draft")
get_param = self.env["ir.config_parameter"].sudo().get_param
active_draft = get_param("mrp_bom_version.active_draft")
new_bom = self.copy(
{
"version": self.version + 1,
"active": active_draft and active_draft.value or False,
"active": active_draft,
"parent_bom": self.id,
}
)
return new_bom
@api.multi
def button_activate(self):
self.write({"active": True, "state": "active"})
@api.multi
def button_historical(self):
self.write(
{
@@ -135,39 +131,35 @@ class MrpBom(models.Model):
}
)
def search(
self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False
):
@api.model
def search(self, args, offset=0, limit=None, order=None, count=False):
"""Add search argument for field type if the context says so. This
should be in old API because context argument is not the last one.
"""
if context is None:
context = {}
search_state = context.get("state", False)
search_state = self.env.context.get("state", False)
if search_state:
args += [("state", "=", search_state)]
return super(MrpBom, self).search(
cr,
uid,
return super().search(
args,
offset=offset,
limit=limit,
order=order,
context=context,
count=count,
)
@api.model
def _bom_find(self, product_tmpl_id=None, product_id=None, properties=None):
"""Finds BoM for particular product and product uom.
@param product_tmpl_id: Selected product.
@param product_uom: Unit of measure of a product.
@param properties: List of related properties.
@return: False or BoM id.
def _bom_find(self, products, picking_type=None, company_id=False, bom_type=False):
"""Find the first BoM for each products
:param products: `product.product` recordset
:return: One bom (or empty recordset `mrp.bom` if none find)
by product (`product.product` record)
:rtype: defaultdict(`lambda: self.env['mrp.bom']`)
"""
bom_id = super(MrpBom, self.with_context(state="active"))._bom_find(
product_tmpl_id=product_tmpl_id,
product_id=product_id,
properties=properties,
products,
picking_type=picking_type,
company_id=company_id,
bom_type=bom_type,
)
return bom_id

View File

@@ -1,11 +1,11 @@
# (c) 2015 Oihane Crucelaegui - AvanzOSC
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
from openerp import api, fields, models
from odoo import fields, models
class MrpConfigSettings(models.TransientModel):
_inherit = "mrp.config.settings"
_inherit = "res.config.settings"
group_mrp_bom_version = fields.Boolean(
string="Allow to re-edit BoMs",
@@ -16,34 +16,5 @@ class MrpConfigSettings(models.TransientModel):
string="Keep re-editing BoM active",
help="This will allow you to define if those BoM passed back to draft"
" are still activated or not",
config_parameter="mrp_bom_version.active_draft",
)
def _get_parameter(self, key, default=False):
param_obj = self.env["ir.config_parameter"]
rec = param_obj.search([("key", "=", key)])
return rec or default
def _write_or_create_param(self, key, value):
param_obj = self.env["ir.config_parameter"]
rec = self._get_parameter(key)
if rec:
if not value:
rec.unlink()
else:
rec.value = value
elif value:
param_obj.create({"key": key, "value": value})
@api.multi
def get_default_parameters(self):
def get_value(key, default=""):
rec = self._get_parameter(key)
return rec and rec.value or default
return {
"active_draft": get_value("active.draft", False),
}
@api.multi
def set_parameters(self):
self._write_or_create_param("active.draft", self.active_draft)

View File

@@ -1,9 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<openerp>
<data noupdate="1">
<record id="group_mrp_bom_version" model="res.groups">
<field name="name">MRP BoM version</field>
<field name="category_id" ref="base.module_category_hidden" />
</record>
</data>
</openerp>
<odoo noupdate="1">
<record id="group_mrp_bom_version" model="res.groups">
<field name="name">MRP BoM version</field>
<field name="category_id" ref="base.module_category_hidden" />
</record>
</odoo>

View File

@@ -1,26 +1,27 @@
# (c) 2015 Alfredo de la Fuente - AvanzOSC
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
import openerp.tests.common as common
import odoo.tests as common
class TestMrpBomVersion(common.TransactionCase):
def setUp(self):
super(TestMrpBomVersion, self).setUp()
self.parameter_model = self.env["ir.config_parameter"]
self.bom_model = self.env["mrp.bom"].with_context(test_mrp_bom_version=True)
self.company = self.env.ref("base.main_company")
@classmethod
def setUpClass(cls):
super(TestMrpBomVersion, cls).setUpClass()
cls.parameter_model = cls.env["ir.config_parameter"].sudo()
cls.bom_model = cls.env["mrp.bom"].with_context(test_mrp_bom_version=True)
cls.company = cls.env.ref("base.main_company")
vals = {
"company_id": self.company.id,
"product_tmpl_id": self.env.ref(
"company_id": cls.company.id,
"product_tmpl_id": cls.env.ref(
"product.product_product_11_product_template"
).id,
"bom_line_ids": [
(0, 0, {"product_id": self.env.ref("product.product_product_5").id}),
(0, 0, {"product_id": self.env.ref("product.product_product_6").id}),
(0, 0, {"product_id": cls.env.ref("product.product_product_5").id}),
(0, 0, {"product_id": cls.env.ref("product.product_product_6").id}),
],
}
self.mrp_bom = self.bom_model.create(vals)
cls.mrp_bom = cls.bom_model.create(vals)
def test_mrp_bom(self):
self.assertEqual(
@@ -49,7 +50,7 @@ class TestMrpBomVersion(common.TransactionCase):
self.assertFalse(self.mrp_bom.active, "Check must be False")
def test_mrp_bom_back2draft_active(self):
self.parameter_model.create({"key": "active.draft", "value": True})
self.parameter_model.set_param("mrp_bom_version.active_draft", True)
self.mrp_bom.button_activate()
self.mrp_bom.button_draft()
self.assertTrue(self.mrp_bom.active, "Check must be True, as set in parameters")
@@ -65,7 +66,11 @@ class TestMrpBomVersion(common.TransactionCase):
"historical",
"Incorrect state, it must have been historified",
)
new_boms = self.bom_model.search([("parent_bom", "=", self.mrp_bom.id)])
new_boms = self.bom_model.with_context(active_test=False).search(
[
("parent_bom", "=", self.mrp_bom.id),
]
)
for new_bom in new_boms:
self.assertEqual(
new_bom.version,

View File

@@ -1,54 +1,84 @@
<?xml version="1.0" encoding="utf-8" ?>
<openerp>
<data>
<record model="ir.actions.act_window" id="mrp.mrp_bom_form_action">
<field name="domain">['|',('active','=',True),('active','=',False)]</field>
</record>
<odoo>
<record model="ir.actions.act_window" id="mrp.mrp_bom_form_action">
<field name="domain">['|',('active','=',True),('active','=',False)]</field>
</record>
<record id="mrp.mrp_bom_tree_parent_view" model="ir.ui.view">
<field name="name">mrp.bom.tree</field>
<field name="model">mrp.bom</field>
<field name="arch" type="xml">
<tree>
<field name="name" />
<field name="code" />
<field name="sequence" />
</tree>
<record model="ir.ui.view" id="mrp_bom_version_tree_view">
<field name="model">mrp.bom</field>
<field name="inherit_id" ref="mrp.mrp_bom_tree_view" />
<field name="arch" type="xml">
<tree position="attributes">
<attribute name="decoration-muted">not active</attribute>
</tree>
<field name="code" position="after">
<field name="version" />
<field name="state" />
<field name="historical_date" />
<button
name="button_draft"
type="object"
title="Draft"
groups="mrp_bom_version.group_mrp_bom_version"
attrs="{'invisible':[('state','!=','active')]}"
icon="fa-plus-square"
/>
<button
name="button_activate"
type="object"
title="Activate"
attrs="{'invisible':[('state','not in',(False, 'draft'))]}"
icon="fa-check-square"
confirm="You will activate the BoM, then you won't be able to edit it after this. Are you sure you want to proceed?"
/>
<button
name="button_new_version"
type="object"
title="New version"
attrs="{'invisible':[('state','==','historical')]}"
icon="fa-gears"
confirm="You are going to create a new version of this BoM. Are you sure?"
/>
<button
name="button_historical"
type="object"
title="Historical"
attrs="{'invisible':[('state','!=','active')]}"
icon="fa-history"
confirm="You are going to historize an BoM. Doing, not be able to unlock it unless you make a copy. Are you sure you want to proceed?"
/>
</field>
</record>
</field>
</record>
<record model="ir.ui.view" id="mrp_bom_version_tree_view">
<field name="name">mrp.bom.version.tree</field>
<field name="model">mrp.bom</field>
<field name="inherit_id" ref="mrp.mrp_bom_tree_parent_view" />
<field name="arch" type="xml">
<field name="name" position="after">
<field name="active" />
<field name="version" />
<field name="state" />
<field name="historical_date" />
<record model="ir.ui.view" id="mrp_bom_version_form_view">
<field name="model">mrp.bom</field>
<field name="inherit_id" ref="mrp.mrp_bom_form_view" />
<field name="arch" type="xml">
<sheet position="before">
<header>
<button
name="button_draft"
type="object"
string="Draft"
groups="mrp_bom_version.group_mrp_bom_version"
attrs="{'invisible':[('state','!=','active')]}"
icon="terp-document-new"
class="oe_highlight"
/>
<button
name="button_activate"
type="object"
string="Activate"
attrs="{'invisible':[('state','not in',(False, 'draft'))]}"
icon="terp-camera_test"
confirm="You will activate the BoM. If you haven't set a route yet, then you won't be able to do it after this. Are you sure you want to proceed?"
class="oe_highlight"
confirm="YYou will activate the BoM, then you won't be able to edit it after this. Are you sure you want to proceed?"
/>
<button
name="button_new_version"
type="object"
string="New version"
attrs="{'invisible':[('state','==','historical')]}"
icon="gtk-execute"
attrs="{'invisible':[('state','=','historical')]}"
class="oe_highlight"
confirm="You are going to create a new version of this BoM. Are you sure?"
/>
<button
@@ -56,105 +86,59 @@
type="object"
string="Historical"
attrs="{'invisible':[('state','!=','active')]}"
icon="gtk-convert"
class="oe_highlight"
confirm="You are going to historize an BoM. Doing, not be able to unlock it unless you make a copy. Are you sure you want to proceed?"
/>
</field>
</field>
</record>
<record model="ir.ui.view" id="mrp_bom_version_form_view">
<field name="name">mrp.bom.version.form</field>
<field name="model">mrp.bom</field>
<field name="inherit_id" ref="mrp.mrp_bom_form_view" />
<field name="arch" type="xml">
<xpath expr="//form/group" position="before">
<header>
<button
name="button_draft"
type="object"
string="Draft"
groups="mrp_bom_version.group_mrp_bom_version"
attrs="{'invisible':[('state','!=','active')]}"
class="oe_highlight"
/>
<button
name="button_activate"
type="object"
string="Activate"
attrs="{'invisible':[('state','not in',(False, 'draft'))]}"
class="oe_highlight"
confirm="You will activate the BoM. If you haven't set a route yet, then you won't be able to do it after this. Are you sure you want to proceed?"
/>
<button
name="button_new_version"
type="object"
string="New version"
attrs="{'invisible':[('state','==','historical')]}"
class="oe_highlight"
confirm="You are going to create a new version of this BoM. Are you sure?"
/>
<button
name="button_historical"
type="object"
string="Historical"
attrs="{'invisible':[('state','!=','active')]}"
class="oe_highlight"
confirm="You are going to historize an BoM. Doing, not be able to unlock it unless you make a copy. Are you sure you want to proceed?"
/>
<field
name="state"
widget="statusbar"
statusbar_visible="draft,active,historical"
/>
</header>
</xpath>
<field name="company_id" position="after">
<field name="version" />
<field
name="historical_date"
attrs="{'invisible': [('state','!=','historical')]}"
name="state"
widget="statusbar"
statusbar_visible="draft,active,historical"
/>
</field>
<notebook position="inside">
<page string="Versions">
<field name="old_versions" />
</page>
</notebook>
</header>
</sheet>
<field name="company_id" position="before">
<field name="version" />
<field
name="historical_date"
attrs="{'invisible': [('state','!=','historical')]}"
/>
</field>
</record>
<notebook position="inside">
<page string="Versions">
<field name="old_versions" />
</page>
</notebook>
</field>
</record>
<record model="ir.ui.view" id="mrp_bom_version_search_view">
<field name="name">mrp.bom.version.search</field>
<field name="model">mrp.bom</field>
<field name="inherit_id" ref="mrp.view_mrp_bom_filter" />
<field name="arch" type="xml">
<field name="name" position="after">
<field name="active" />
<field name="state" />
</field>
<group string="Group By..." position="before">
<filter
string="Active"
domain="[('active','=',True)]"
name="is_active_filter"
/>
<filter
string="Inactive"
domain="[('active','=',False)]"
name="is_inactive_filter"
/>
</group>
<group string="Group By..." position="inside">
<filter
string="Active"
domain="[]"
context="{'group_by':'active'}"
/>
<filter string="State" domain="[]" context="{'group_by':'state'}" />
</group>
</field>
</record>
</data>
</openerp>
<record model="ir.ui.view" id="mrp_bom_version_search_view">
<field name="model">mrp.bom</field>
<field name="inherit_id" ref="mrp.view_mrp_bom_filter" />
<field name="arch" type="xml">
<filter name="normal" position="before">
<field name="state" />
</filter>
<filter name="inactive" position="before">
<filter
string="Active"
domain="[('active','=',True)]"
name="is_active_filter"
/>
</filter>
<filter name="default_unit_of_measure" position="after">
<filter
string="Active"
name="group_active"
domain="[]"
context="{'group_by':'active'}"
/>
<filter
string="Status"
name="group_state"
domain="[]"
context="{'group_by':'state'}"
/>
</filter>
</field>
</record>
</odoo>

View File

@@ -1,22 +1,37 @@
<?xml version="1.0" encoding="UTF-8" ?>
<openerp>
<data>
<record model="ir.ui.view" id="mrp_config_settings_versioning">
<field name="name">mrp.config.settings.versioning</field>
<field name="model">mrp.config.settings</field>
<field name="inherit_id" ref="mrp.view_mrp_config" />
<field name="arch" type="xml">
<xpath expr="//field[@name='module_mrp_repair']/.." position="after">
<div>
<field name="group_mrp_bom_version" class="oe_inline" />
<odoo>
<record model="ir.ui.view" id="mrp_config_settings_versioning">
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="mrp.res_config_settings_view_form" />
<field name="arch" type="xml">
<div id="mrp_reception_report" position="after">
<div class="col-12 col-lg-6 o_setting_box" id="mrp_bom_version">
<div class="o_setting_left_pane">
<field name="group_mrp_bom_version" />
</div>
<div class="o_setting_right_pane">
<label for="group_mrp_bom_version" />
<div class="text-muted">
Allow to re-edit BoMs
</div>
<div
class="row mt-2"
attrs="{'invisible': [('group_mrp_bom_version','=',False)]}"
>
<field
name="active_draft"
class="col flex-grow-0 ml16 mr0 pe-2"
/>
<div class="col ps-0">
<label for="active_draft" />
<div class="text-muted">
Keep re-editing BoM active
</div>
</div>
</div>
</div>
<div attrs="{'invisible': [('group_mrp_bom_version', '=', False)]}">
<field name="active_draft" class="oe_inline" />
<label for="active_draft" />
</div>
</xpath>
</field>
</record>
</data>
</openerp>
</div>
</div>
</field>
</record>
</odoo>

View File

@@ -0,0 +1 @@
../../../../mrp_bom_version

View File

@@ -1 +0,0 @@
__import__('pkg_resources').declare_namespace(__name__)

View File

@@ -1 +0,0 @@
../../../mrp_bom_version