Merge PR #270 into 13.0

Signed-off-by dreispt
This commit is contained in:
OCA-git-bot
2024-05-02 15:13:23 +00:00
15 changed files with 288 additions and 0 deletions

View File

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

View File

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

View File

View File

@@ -0,0 +1,5 @@
# Copyright 2023 ForgeFlow S.L.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import models
from . import report

View File

@@ -0,0 +1,17 @@
# Copyright 2023 ForgeFlow S.L.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Stock Move Delay Report",
"summary": "Stock Move Delay Report",
"version": "13.0.1.0.0",
"license": "AGPL-3",
"author": "ForgeFlow, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/stock-logistics-reporting",
"depends": ["stock"],
"data": [
"security/ir.model.access.csv",
"security/report_security.xml",
"report/delay_report_views.xml",
],
}

View File

@@ -0,0 +1,4 @@
# Copyright 2023 ForgeFlow S.L.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import stock_move

View File

@@ -0,0 +1,40 @@
# Copyright 2023 ForgeFlow S.L.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class StockMove(models.Model):
_inherit = "stock.move"
date_delay = fields.Float(
compute="_compute_date_delay",
store=True,
help="If the move is done, the difference between "
"the scheduled date and the deadline",
)
responsible_id = fields.Many2one(
comodel_name="res.partner",
compute="_compute_responsible",
store=True,
help="Partner responsible of completing the move on time.",
)
@api.depends("state")
def _compute_date_delay(self):
for rec in self:
if rec.state == "done" and rec.date_expected:
rec.date_delay = (rec.date - rec.date_expected).days
elif not rec.date_expected:
rec.date_delay = 0
else:
rec.date_delay = None
@api.depends("state")
def _compute_responsible(self):
for rec in self:
if rec.picking_id.picking_type_id.code == "incoming":
rec.responsible_id = rec.picking_id.partner_id
elif rec.picking_id.picking_type_id.code == "outgoing":
rec.responsible_id = rec.picking_id.company_id.partner_id

View File

@@ -0,0 +1,2 @@
* `ForgeFlow <https://www.forgeflow.com>`_:
* David Jiménez <david.jimenez@forgeflow.com>

View File

@@ -0,0 +1 @@
This module adds a report to check the delay from incoming and outgoing moves grouped by Responsible Partner.

View File

@@ -0,0 +1,9 @@
Go to Inventory -> Reporting -> Delay Analysis.
Here there are 3 views:
Graph View: Shows the mean delay days of the stock moves for each partner with incoming or outgoing moves.
Pivot View: Shows the mean delay days of the stock moves for each partner with incoming or outgoing moves. Also shows the % of moves done on time.
Tree View: Shows all the done moves grouped by the partner responsible (in charge) of the picking.

View File

@@ -0,0 +1,4 @@
# Copyright 2023 ForgeFlow S.L.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import delay_report

View File

@@ -0,0 +1,78 @@
# Copyright 2023 ForgeFlow S.L.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models, tools
class StockMoveDelayReport(models.Model):
_name = "stock.move.delay.report"
_description = "Delay Analysis Report"
_auto = False
date = fields.Date("Date Scheduled", readonly=True)
move_id = fields.Many2one("stock.move", "Stock Move #", readonly=True)
product_id = fields.Many2one("product.product", "Product", readonly=True)
reference = fields.Char("Reference", readonly=True)
location_src_id = fields.Many2one("stock.location", "From", readonly=True)
location_dest_id = fields.Many2one("stock.location", "To", readonly=True)
date_delay = fields.Float("Date Delay", group_operator="avg", readonly=True)
done_on_time = fields.Float("Done on Time", group_operator="avg", readonly=True)
product_uom = fields.Many2one("uom.uom", "Unit of Measure", readonly=True)
responsible_id = fields.Many2one("res.partner", "Responsible", readonly=True)
company_id = fields.Many2one("res.company", string="Company")
def _done_on_time(self):
return """
case when sm.date_delay > 0 then 0.0 else 100.0 end as done_on_time
"""
def _select(self):
return """
sm.id,
sm.date,
sm.id AS move_id,
sm.product_id,
sm.reference,
sm.location_id AS location_src_id,
sm.location_dest_id,
sm.date_delay,
%s,
sm.product_uom,
sm.responsible_id,
sm.company_id
""" % (
self._done_on_time()
)
def _from(self):
return """
stock_move AS sm
"""
def _where(self):
if len(self.env.company) == 1:
return """
sm.state = 'done' AND sm.responsible_id IS NOT NULL
"""
else:
return """
sm.state = 'done' AND sm.responsible_id IS NOT NULL
"""
def _query(self):
return """
(SELECT %s
FROM %s
WHERE %s)
""" % (
self._select(),
self._from(),
self._where(),
)
def init(self):
tools.drop_view_if_exists(self.env.cr, self._table)
# pylint: disable=E8103
self.env.cr.execute(
"""CREATE or REPLACE VIEW %s as (%s)""" % (self._table, self._query())
)

View File

@@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="stock_move_delay_report_pivot_view" model="ir.ui.view">
<field name="name">stock.move.delay.report.pivot</field>
<field name="model">stock.move.delay.report</field>
<field name="arch" type="xml">
<pivot string="Delay Analysis" disable_linking="True">
<field name="responsible_id" type="row" />
<field name="date_delay" type="measure" string="Mean Days Delay" />
<field name="done_on_time" type="measure" />
</pivot>
</field>
</record>
<record id="stock_move_delay_report_graph_view" model="ir.ui.view">
<field name="name">stock.move.delay.report.graph</field>
<field name="model">stock.move.delay.report</field>
<field name="arch" type="xml">
<graph string="Delay Analysis" type="line">
<field name="responsible_id" type="row" />
<field name="date_delay" type="measure" string="Mean Days Delay" />
</graph>
</field>
</record>
<record id="stock_move_delay_report_tree_view" model="ir.ui.view">
<field name="name">stock.move.delay.report.tree</field>
<field name="model">stock.move.delay.report</field>
<field name="arch" type="xml">
<tree create="0">
<field name="responsible_id" />
<field name="date" />
<field name="move_id" />
<field name="product_id" />
<field name="product_uom" optional="0" />
<field name="reference" />
<field name="location_src_id" />
<field name="location_dest_id" />
<field name="date_delay" />
<field name="company_id" />
</tree>
</field>
</record>
<record id="stock_move_delay_report_search_view" model="ir.ui.view">
<field name="name">stock.move.delay.report.search</field>
<field name="model">stock.move.delay.report</field>
<field name="arch" type="xml">
<search>
<field name="responsible_id" />
<filter
name="group_responsible_id"
string="Responsible"
icon="terp-partner"
context="{'group_by':'responsible_id'}"
/>
<filter
string="Only Products"
name="only_products"
domain="[('product_id.type', '=', 'product')]"
/>
<filter
string="Only Services"
name="only_services"
domain="[('product_id.type', '=', 'service')]"
/>
<filter
string="Only Consumable"
name="only_consumable"
domain="[('product_id.type', '=', 'consu')]"
/>
<filter
string="Date"
name="today"
date="date"
help="Scheduled or processing date"
/>
</search>
</field>
</record>
<record id="action_stock_move_delay_report" model="ir.actions.act_window">
<field name="name">Delay Analysis</field>
<field name="res_model">stock.move.delay.report</field>
<field name="view_mode">graph,pivot,tree</field>
<field name="search_view_id" ref="stock_move_delay_report_search_view" />
<field name="context">{
'search_default_group_responsible_id': 1,
'search_default_only_products': 1,
}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
No data yet!
</p><p>
Complete a new stock move
</p>
</field>
</record>
<menuitem
action="action_stock_move_delay_report"
id="menu_stock_move_delay_report"
parent="stock.menu_warehouse_report"
sequence="140"
/>
</odoo>

View File

@@ -0,0 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_stock_move_delay_report_user,stock.move.delay.report.user,model_stock_move_delay_report,base.group_user,1,0,0,0
access_stock_move_delay_report_manager,stock.move.delay.report.manager,model_stock_move_delay_report,base.group_system,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_stock_move_delay_report_user stock.move.delay.report.user model_stock_move_delay_report base.group_user 1 0 0 0
3 access_stock_move_delay_report_manager stock.move.delay.report.manager model_stock_move_delay_report base.group_system 1 1 1 1

View File

@@ -0,0 +1,10 @@
<odoo>
<record model="ir.rule" id="stock_move_delay_report_comp_rule">
<field name="name">Stock Move Delay Analysis multi-company</field>
<field name="model_id" ref="model_stock_move_delay_report" />
<field name="global" eval="True" />
<field
name="domain_force"
>['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
</record>
</odoo>