Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[16.0][IMP] ddmrp: Add customized Stock Moves view #446

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 43 additions & 54 deletions ddmrp/models/stock_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1383,17 +1383,6 @@
"domain": str([("id", "in", lines.ids)]),
}

def open_moves(self):
self.ensure_one()
# Utility method used to add an "Open Moves" button in the buffer
# planning view
domain = self._search_open_stock_moves_domain()
moves = self.env["stock.move"].search(domain)
moves = moves.filtered(
lambda move: move.location_dest_id.is_sublocation_of(self.location_id)
)
return self._stock_move_tree_view(moves)

def _get_horizon_adu_past_demand(self):
return self.adu_calculation_method.horizon_past or 0

Expand Down Expand Up @@ -1839,72 +1828,72 @@
wizard.make_procurement()
return True

def _search_purchase_order_lines_incoming(self, outside_dlt=False):
def action_view_supply_moves(self):
result = self.env["ir.actions.actions"]._for_xml_id("stock.stock_move_action")
result["context"] = {}
moves = self._search_stock_moves_incoming() + self._search_stock_moves_incoming(

Check warning on line 1834 in ddmrp/models/stock_buffer.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_buffer.py#L1832-L1834

Added lines #L1832 - L1834 were not covered by tests
outside_dlt=True
)
result["domain"] = [("id", "in", moves.ids)]
return result

Check warning on line 1838 in ddmrp/models/stock_buffer.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_buffer.py#L1837-L1838

Added lines #L1837 - L1838 were not covered by tests

def _get_rfq_dlt(self, outside_dlt=False):
self.ensure_one()

Check warning on line 1841 in ddmrp/models/stock_buffer.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_buffer.py#L1841

Added line #L1841 was not covered by tests
cut_date = self._get_incoming_supply_date_limit()
if not outside_dlt:
pols = self.purchase_line_ids.filtered(
lambda l: l.date_planned <= fields.Datetime.to_datetime(cut_date)
and l.order_id.state in ("draft", "sent")
and l.state in ("draft", "sent")
)
else:
pols = self.purchase_line_ids.filtered(
lambda l: l.date_planned > fields.Datetime.to_datetime(cut_date)
and l.order_id.state in ("draft", "sent")
and l.state in ("draft", "sent")
)
return pols

def action_view_supply(self, outside_dlt=False):
if self.item_type == "purchased":
pols = self._search_purchase_order_lines_incoming(outside_dlt)
moves = self._search_stock_moves_incoming(outside_dlt)
while moves.mapped("move_orig_ids"):
moves = moves.mapped("move_orig_ids")
pos = pols.mapped("order_id") + moves.mapped("purchase_line_id.order_id")
result = self.env["ir.actions.actions"]._for_xml_id("purchase.purchase_rfq")
# Remove the context since the action display RFQ and not PO.
result["context"] = {}
result["domain"] = [("id", "in", pos.ids)]
elif self.item_type == "manufactured":
moves = self._search_stock_moves_incoming(outside_dlt)
mos = moves.mapped("production_id")
result = self.env["ir.actions.actions"]._for_xml_id(
"mrp.mrp_production_action"
)
result["context"] = {}
result["domain"] = [("id", "in", mos.ids)]
else:
moves = self._search_stock_moves_incoming(outside_dlt)
picks = moves.mapped("picking_id")
result = self.env["ir.actions.actions"]._for_xml_id(
"stock.action_picking_tree_all"
)
result["context"] = {}
result["domain"] = [("id", "in", picks.ids)]
def action_view_supply_moves_inside_dlt_window(self):
result = self.env["ir.actions.actions"]._for_xml_id("stock.stock_move_action")
moves = self._search_stock_moves_incoming()
result["context"] = {}
result["domain"] = [("id", "in", moves.ids)]

Check warning on line 1859 in ddmrp/models/stock_buffer.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_buffer.py#L1856-L1859

Added lines #L1856 - L1859 were not covered by tests
return result

def action_view_supply_inside_dlt_window(self):
return self.action_view_supply()
def action_view_supply_moves_outside_dlt_window(self):
result = self.env["ir.actions.actions"]._for_xml_id("stock.stock_move_action")
moves = self._search_stock_moves_incoming(outside_dlt=True)
result["context"] = {}
result["domain"] = [("id", "in", moves.ids)]
return result

Check warning on line 1867 in ddmrp/models/stock_buffer.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_buffer.py#L1863-L1867

Added lines #L1863 - L1867 were not covered by tests

def action_view_supply_outside_dlt_window(self):
return self.action_view_supply(outside_dlt=True)
def action_view_supply_rfq_inside_dlt_window(self):
result = self.env["ir.actions.actions"]._for_xml_id("purchase.purchase_rfq")
pols = self._get_rfq_dlt()
pos = pols.mapped("order_id")
result["context"] = {}
result["domain"] = [("id", "in", pos.ids)]
return result

Check warning on line 1875 in ddmrp/models/stock_buffer.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_buffer.py#L1870-L1875

Added lines #L1870 - L1875 were not covered by tests

def action_view_qualified_demand_pickings(self):
moves = self.qualified_demand_stock_move_ids
picks = moves.mapped("picking_id")
result = self.env["ir.actions.actions"]._for_xml_id(
"stock.action_picking_tree_all"
)
def action_view_supply_rfq_outside_dlt_window(self):
result = self.env["ir.actions.actions"]._for_xml_id("purchase.purchase_rfq")
pols = self._get_rfq_dlt(outside_dlt=True)
pos = pols.mapped("order_id")

Check warning on line 1880 in ddmrp/models/stock_buffer.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_buffer.py#L1878-L1880

Added lines #L1878 - L1880 were not covered by tests
result["context"] = {}
result["domain"] = [("id", "in", picks.ids)]
result["domain"] = [("id", "in", pos.ids)]
return result

Check warning on line 1883 in ddmrp/models/stock_buffer.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_buffer.py#L1882-L1883

Added lines #L1882 - L1883 were not covered by tests

def action_view_qualified_demand_moves(self):
result = self.env["ir.actions.actions"]._for_xml_id("stock.stock_move_action")
result["context"] = {}
result["domain"] = [("id", "in", self.qualified_demand_stock_move_ids.ids)]

Check warning on line 1888 in ddmrp/models/stock_buffer.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_buffer.py#L1886-L1888

Added lines #L1886 - L1888 were not covered by tests
return result

def action_view_qualified_demand_mrp(self):
mrp_moves = self.qualified_demand_mrp_move_ids
result = self.env["ir.actions.actions"]._for_xml_id(
"mrp_multi_level.mrp_move_action"
)
result["context"] = {}
result["domain"] = [("id", "in", mrp_moves.ids)]
result["domain"] = [("id", "in", self.qualified_demand_mrp_move_ids.ids)]

Check warning on line 1896 in ddmrp/models/stock_buffer.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_buffer.py#L1896

Added line #L1896 was not covered by tests
return result

def action_view_past_adu_direct_demand(self):
Expand Down
68 changes: 67 additions & 1 deletion ddmrp/models/stock_move.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Copyright 2019-20 ForgeFlow S.L. (http://www.forgeflow.com)
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).

from odoo import api, fields, models
from odoo import _, api, fields, models


class StockMove(models.Model):
Expand Down Expand Up @@ -84,3 +84,69 @@
buffer.cron_actions(only_nfp="out")
for buffer in in_buffers.with_context(no_ddmrp_history=True):
buffer.cron_actions(only_nfp="in")

def _get_all_linked_moves(self):
"""Retrieve all linked moves both origin and destination recursively."""

def get_moves(move_set, attr):
new_moves = move_set.mapped(attr)

Check warning on line 92 in ddmrp/models/stock_move.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_move.py#L91-L92

Added lines #L91 - L92 were not covered by tests
while new_moves:
move_set |= new_moves
new_moves = new_moves.mapped(attr)
return move_set

Check warning on line 96 in ddmrp/models/stock_move.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_move.py#L94-L96

Added lines #L94 - L96 were not covered by tests

all_moves = (

Check warning on line 98 in ddmrp/models/stock_move.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_move.py#L98

Added line #L98 was not covered by tests
self | get_moves(self, "move_orig_ids") | get_moves(self, "move_dest_ids")
)
return all_moves

Check warning on line 101 in ddmrp/models/stock_move.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_move.py#L101

Added line #L101 was not covered by tests

def _get_source_field_candidates(self):
"""Extend for more source field candidates."""
return [

Check warning on line 105 in ddmrp/models/stock_move.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_move.py#L105

Added line #L105 was not covered by tests
"sale_line_id.order_id",
"purchase_line_id.order_id",
"production_id",
"raw_material_production_id",
"unbuild_id",
"repair_id",
"rma_line_id",
"picking_id",
]

def _has_nested_field(self, field):
"""Check if an object has a nested chain of fields."""
current_object = self
try:

Check warning on line 119 in ddmrp/models/stock_move.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_move.py#L118-L119

Added lines #L118 - L119 were not covered by tests
for field in field.split("."):
current_object = getattr(current_object, field)
return True
except AttributeError:
return False

Check warning on line 124 in ddmrp/models/stock_move.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_move.py#L121-L124

Added lines #L121 - L124 were not covered by tests

def _get_source_record(self):
"""Find the first source record in the field candidates linked with the moves,
prioritizing the order of field candidates."""
moves = self._get_all_linked_moves()
field_candidates = self._get_source_field_candidates()

Check warning on line 130 in ddmrp/models/stock_move.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_move.py#L129-L130

Added lines #L129 - L130 were not covered by tests
# Iterate over the prioritized list of candidate fields
for field in field_candidates:
if self._has_nested_field(field):
for move in moves:
record = move.mapped(field)

Check warning on line 135 in ddmrp/models/stock_move.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_move.py#L135

Added line #L135 was not covered by tests
if record:
return record
return False

Check warning on line 138 in ddmrp/models/stock_move.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_move.py#L137-L138

Added lines #L137 - L138 were not covered by tests

def action_open_stock_move_source(self):
"""Open the source record of the stock move, if it exists."""
self.ensure_one()
record = self._get_source_record()

Check warning on line 143 in ddmrp/models/stock_move.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_move.py#L142-L143

Added lines #L142 - L143 were not covered by tests
if record:
return {

Check warning on line 145 in ddmrp/models/stock_move.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_move.py#L145

Added line #L145 was not covered by tests
"name": getattr(record, "name", _("Stock Move Source")),
"view_mode": "form",
"res_model": record._name,
"type": "ir.actions.act_window",
"res_id": record.id,
}
return False

Check warning on line 152 in ddmrp/models/stock_move.py

View check run for this annotation

Codecov / codecov/patch

ddmrp/models/stock_move.py#L152

Added line #L152 was not covered by tests
60 changes: 44 additions & 16 deletions ddmrp/views/stock_buffer_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,24 +47,19 @@
type="object"
/>
<field name="incoming_dlt_qty" string="Incoming Within DLT" />
<field
name="incoming_total_qty"
string="Total Incoming"
optional="show"
/>
<field
name="incoming_outside_dlt_qty"
string="Incoming Outside DLT"
optional="hide"
/>
<field
name="rfq_outside_dlt_qty"
string="RFQ Qty Outside DLT"
optional="hide"
name="incoming_total_qty"
string="Total Incoming"
optional="show"
/>
<button
title="Open Non-completed Moves"
name="open_moves"
title="Total Incoming"
name="action_view_supply_moves"
icon="fa-exchange"
type="object"
/>
Expand All @@ -80,13 +75,22 @@
/>
<button
title="Some incoming quantities are outside of the DLT Horizon and may require rescheduling. Press this button to display the involved supply orders"
name="action_view_supply_outside_dlt_window"
name="action_view_supply_moves_outside_dlt_window"
icon="fa-warning"
type="object"
attrs="{'invisible':[('incoming_outside_dlt_qty', '=', 0), ('rfq_outside_dlt_qty', '=', 0)]}"
attrs="{'invisible':[('incoming_outside_dlt_qty', '=', 0)]}"
/>
<field name="rfq_outside_dlt_qty" invisible="1" />
<button
title="No stock available on source location for distributed buffer"
title="Some RFQ quantities are outside of the DLT Horizon and may require rescheduling.
Press this button to display the involved RFQs"
name="action_view_supply_rfq_outside_dlt_window"
icon="fa-warning"
type="object"
attrs="{'invisible':[('rfq_outside_dlt_qty', '=', 0)]}"
/>
<button
title="No stock available in source location for distributed buffer"
name="action_dummy"
icon="fa-warning"
type="object"
Expand Down Expand Up @@ -412,13 +416,37 @@
<div name="incoming_dlt_qty" class="o_row">
<field name="incoming_dlt_qty" class="oe_inline" />
<button
title="View Incoming (Within DLT)"
name="action_view_supply_inside_dlt_window"
title="View Incoming Moves (Within DLT)"
name="action_view_supply_moves_inside_dlt_window"
icon="fa-search"
type="object"
attrs="{'invisible': [('incoming_dlt_qty', '=', 0)]}"
/>
</div>
<label for="incoming_outside_dlt_qty" />
<div name="incoming_outside_dlt_qty" class="o_row">
<field
name="incoming_outside_dlt_qty"
class="oe_inline"
/>
<button
title="Some incoming qty is outside of the DLT Horizon and may require rescheduling.
Press this button to display the involved supply orders"
name="action_view_supply_moves_outside_dlt_window"
icon="fa-warning"
type="object"
attrs="{'invisible':[('incoming_outside_dlt_qty', '=', 0)]}"
/>
<field name="rfq_outside_dlt_qty" invisible="1" />
<button
title="Some incoming RFQs are outside of the DLT Horizon and may require rescheduling.
Press this button to display the involved supply orders"
name="action_view_supply_rfq_outside_dlt_window"
icon="fa-warning"
type="object"
attrs="{'invisible':[('rfq_outside_dlt_qty', '=', 0)]}"
/>
</div>
<label for="qualified_demand" />
<div name="qualified_demand" class="o_row">
<field name="qualified_demand" class="oe_inline" />
Expand All @@ -432,7 +460,7 @@
/>
<button
title="View Qualified Demand from Pickings"
name="action_view_qualified_demand_pickings"
name="action_view_qualified_demand_moves"
icon="fa-search"
type="object"
attrs="{'invisible': ['|', ('qualified_demand', '=', 0), ('qualified_demand_stock_move_ids', '=', [])]}"
Expand Down
11 changes: 7 additions & 4 deletions ddmrp/views/stock_move_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@
<!-- Copyright 2018-20 ForgeFlow S.L. (http://www.forgeflow.com)
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0) -->
<odoo>
<!--Fixes to show date on stock move report-->
<!--If someday Odoo corrects this, we could remove this views-->
<record id="view_move_tree" model="ir.ui.view">
<field name="name">stock.move.tree</field>
<field name="model">stock.move</field>
<field name="inherit_id" ref="stock.view_move_tree" />
<field name="arch" type="xml">
<field name="date" position="after">
<field name="date" />
<field name="state" position="after">
<button
title="Go to Source"
name="action_open_stock_move_source"
icon="fa-arrow-right"
type="object"
/>
</field>
</field>
</record>
Expand Down
Loading