Merge PR #914 into 15.0

Signed-off-by LoisRForgeFlow
This commit is contained in:
OCA-git-bot
2022-12-29 07:25:31 +00:00
12 changed files with 169 additions and 0 deletions

View File

@@ -0,0 +1 @@
TO BE GENERATED

View File

@@ -0,0 +1 @@
from . import models

View File

@@ -0,0 +1,16 @@
# Copyright 2022 Camptocamp SA (https://www.camptocamp.com).
# @author Iván Todorovich <ivan.todorovich@camptocamp.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "MRP Production Date Planned Finished",
"summary": "Allows to plan production from the desired finish date",
"version": "15.0.1.0.0",
"author": "Camptocamp, Odoo Community Association (OCA)",
"maintainers": ["ivantodorovich"],
"website": "https://github.com/OCA/manufacture",
"license": "AGPL-3",
"category": "Manufacturing",
"depends": ["mrp"],
"data": ["views/mrp_production.xml"],
}

View File

@@ -0,0 +1 @@
from . import mrp_production

View File

@@ -0,0 +1,26 @@
# Copyright 2022 Camptocamp SA (https://www.camptocamp.com).
# @author Iván Todorovich <ivan.todorovich@camptocamp.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from dateutil.relativedelta import relativedelta
from odoo import api, models
class MrpProduction(models.Model):
_inherit = "mrp.production"
@api.onchange("date_planned_finished")
def _onchange_date_planned_finished_set_date_planned_start(self):
if self.date_planned_finished and not self.is_planned:
date_planned_start = self.date_planned_finished
date_planned_start -= relativedelta(days=self.product_id.produce_delay)
date_planned_start -= relativedelta(days=self.company_id.manufacturing_lead)
if date_planned_start == self.date_planned_finished:
date_planned_start -= relativedelta(hours=1)
if self.date_planned_start != date_planned_start:
self.date_planned_start = date_planned_start
self.move_raw_ids = [
(1, m.id, {"date": self.date_planned_start})
for m in self.move_raw_ids
]

View File

@@ -0,0 +1,3 @@
* `Camptocamp <https://www.camptocamp.com>`_
* Iván Todorovich <ivan.todorovich@camptocamp.com>

View File

@@ -0,0 +1,5 @@
Shows the Scheduled End Date on Manufacturing Orders, and allows to change the start
date from it, through an onchange.
It's useful for companies wanting to plan their manufacturing orders from the target
finish date. Usually these companies have long manufacturing times (days or weeks).

View File

@@ -0,0 +1 @@
from . import test_date_planned_finished

View File

@@ -0,0 +1,51 @@
# Copyright 2022 Camptocamp SA (https://www.camptocamp.com).
# @author Iván Todorovich <ivan.todorovich@camptocamp.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from lxml import etree
from odoo.tests import Form, TransactionCase
class TestDatePlannedFinished(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
cls.company = cls.env.ref("base.main_company")
cls.company.manufacturing_lead = 1
cls.product = cls.env.ref("mrp.product_product_computer_desk")
cls.product.produce_delay = 1
cls.product_bom = cls.env.ref("mrp.mrp_bom_desk")
def test_mrp_production_date_planned_finished_onchange(self):
"""Test that date_planned_start is set when date_planned_finished is changed."""
with Form(self.env["mrp.production"]) as mo:
mo.product_id = self.product
mo.bom_id = self.product_bom
mo.product_qty = 1
mo.date_planned_finished = "2022-10-10 10:00:00"
self.assertEqual(mo.date_planned_start, "2022-10-08 10:00:00")
def test_mrp_production_date_planned_finished_decoration(self):
"""Test that the date_planned_finished field is decorated properly
Its decoration has to exactly match the date_planned_start one.
As this might change if odoo updates their code, or during migrations,
this test case will track any mismatches and fail.
"""
res = self.env["mrp.production"].fields_view_get(view_type="form")
doc = etree.XML(res["arch"])
date_planned_start = doc.xpath("//field[@name='date_planned_start']")[0]
date_planned_finished = doc.xpath("//field[@name='date_planned_finished']")[0]
decoration_attrs = [
attr
for attr in date_planned_start.attrib.keys()
if attr.startswith("decoration-")
]
for attr in decoration_attrs:
self.assertEqual(
date_planned_start.attrib[attr],
date_planned_finished.attrib[attr],
f"date_planned_finished decoration mismatch: {attr}",
)

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2022 Camptocamp SA (https://www.camptocamp.com).
@author Iván Todorovich <ivan.todorovich@camptocamp.com>
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="mrp_production_form_view" model="ir.ui.view">
<field name="model">mrp.production</field>
<field name="inherit_id" ref="mrp.mrp_production_form_view" />
<field name="arch" type="xml">
<xpath
expr="//field[@name='date_planned_start']/parent::div"
position="after"
>
<field name="date_planned_finished" position="move" />
</xpath>
<field name="date_planned_finished" position="attributes">
<attribute name="invisible" />
<attribute t-translation="off" name="required">1</attribute>
<attribute
t-translation="off"
name="attrs"
>{"readonly": [("state", "in", ["close", "cancel"])]}</attribute>
<attribute
t-translation="off"
name="decoration-warning"
>state not in ('done', 'cancel') and date_planned_start &lt; now</attribute>
<attribute
t-translation="off"
name="decoration-danger"
>state not in ('done', 'cancel') and date_planned_start &lt; current_date</attribute>
<attribute
t-translation="off"
name="decoration-bf"
>state not in ('done', 'cancel') and (date_planned_start &lt; current_date or date_planned_start &lt; now)</attribute>
</field>
</field>
</record>
<record id="mrp_production_tree_view" model="ir.ui.view">
<field name="model">mrp.production</field>
<field name="inherit_id" ref="mrp.mrp_production_tree_view" />
<field name="arch" type="xml">
<field name="date_planned_start" position="after">
<field
name="date_planned_finished"
readonly="1"
optional="show"
widget="remaining_days"
/>
</field>
</field>
</record>
</odoo>

View File

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

View File

@@ -0,0 +1,6 @@
import setuptools
setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)