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

[IMP] stock_move_packaging_qty: report done packaging qtys #1988

Merged
merged 1 commit into from
Apr 12, 2024
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
13 changes: 11 additions & 2 deletions stock_move_packaging_qty/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Stock Packaging Qty
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:ac3969cedf86da72ca20a93812053d6d9054a9f5d8e0c896eab57fe2b835eefc
!! source digest: sha256:5b4005788a852d7f71c44042e6c8839be5963fd5d6ac95822b93c48c660a2730
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
Expand All @@ -28,13 +28,22 @@ Stock Packaging Qty

|badge1| |badge2| |badge3| |badge4| |badge5|

Add packaging fields in the stock moves and their reports.
Add packaging fields in the stock moves, their lines and their reports.

**Table of contents**

.. contents::
:local:

Known issues / Roadmap
======================

* Maybe we should track also reserved packaging quantities?

* Since we store done product packaging quantities in the stock move lines, we
should be able to use this information in quants to provide real
packaging-based stock data.

Bug Tracker
===========

Expand Down
3 changes: 2 additions & 1 deletion stock_move_packaging_qty/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"depends": ["stock"],
"data": [
"views/report_stock_picking.xml",
"views/stock_move_tree_view.xml",
"views/stock_move_line_view.xml",
"views/stock_move_view.xml",
"views/stock_picking_form_view.xml",
],
"license": "LGPL-3",
Expand Down
1 change: 1 addition & 0 deletions stock_move_packaging_qty/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from . import stock_move
from . import stock_move_line
75 changes: 70 additions & 5 deletions stock_move_packaging_qty/models/stock_move.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
# Copyright 2020 Camptocamp SA
# Copyright 2021 ForgeFlow, S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
from odoo import api, fields, models
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
from odoo import _, api, exceptions, fields, models
from odoo.tools import float_compare


class StockPicking(models.Model):
class StockMove(models.Model):
_inherit = "stock.move"

product_packaging_qty = fields.Float(
string="Pkg. Qty.",
string="Pkgs. Demand",
compute="_compute_product_packaging_qty",
inverse="_inverse_product_packaging_qty",
help="Amount of packages demanded.",
help="Amount of product packagings demanded.",
)
product_packaging_qty_done = fields.Float(
string="Pkgs. Done",
compute="_compute_product_packaging_qty_done",
inverse="_inverse_product_packaging_qty_done",
help="Amount of product packagings done.",
)

@api.depends(
Expand All @@ -31,6 +38,18 @@ def _compute_product_packaging_qty(self):
move.product_uom_qty / move._get_single_package_uom_qty()
)

@api.depends(
"move_line_ids.product_packaging_qty_done",
"move_line_nosuggest_ids.product_packaging_qty_done",
)
def _compute_product_packaging_qty_done(self):
"""Get the sum of done packaging qtys from move lines."""
for move in self:
lines = move._get_move_lines()
move.product_packaging_qty_done = sum(
yajo marked this conversation as resolved.
Show resolved Hide resolved
lines.mapped("product_packaging_qty_done")
)

@api.onchange("product_packaging_qty")
def _inverse_product_packaging_qty(self):
"""Store the quantity in the product's UoM.
Expand All @@ -43,6 +62,23 @@ def _inverse_product_packaging_qty(self):
uom_factor = move._get_single_package_uom_qty()
move.product_uom_qty = move.product_packaging_qty * uom_factor

def _inverse_product_packaging_qty_done(self):
"""Store the done packaging dqty in the move line if there's just one."""
for move in self:
lines = move._get_move_lines()
# Setting 0 done pkgs with no lines? Nothing to do
if not lines and not move.product_packaging_qty_done:
continue
if len(lines) != 1:
raise exceptions.UserError(
_(
"There are %d move lines involved. "
"Please set their product packaging done qty directly.",
len(lines),
)
)
lines.product_packaging_qty_done = move.product_packaging_qty_done

@api.onchange("product_packaging_id")
def _onchange_product_packaging(self):
"""Add a default qty if the packaging has an invalid value."""
Expand All @@ -62,3 +98,32 @@ def _get_single_package_uom_qty(self):
return self.product_packaging_id.product_uom_id._compute_quantity(
self.product_packaging_id.qty, self.product_uom
)

def _set_quantities_to_reservation(self):
"""Add packaging qtys when clicking on "Set Quantities"."""
result = super()._set_quantities_to_reservation()
digits = self.env["stock.move.line"].fields_get(["qty_done"], ["digits"])[
"qty_done"
]["digits"][1]
for line in self.move_line_ids:
if float_compare(line.qty_done, line.reserved_uom_qty, digits):
continue
if not line.product_packaging_id:
line.product_packaging_qty_done = 0
continue
line.product_packaging_qty_done = (
line.product_packaging_id._check_qty(
line.qty_done, line.product_uom_id, "DOWN"
)
/ line.product_packaging_id.qty
)
return result

def _clear_quantities_to_zero(self):
"""Clear packaging qtys when clicking on "Clear Quantities"."""
result = super()._clear_quantities_to_zero()
for line in self.move_line_ids:
if line.qty_done:
continue
line.product_packaging_qty_done = 0
return result
49 changes: 49 additions & 0 deletions stock_move_packaging_qty/models/stock_move_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copyright 2024 Moduon Team S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0)
from odoo import fields, models


class StockMoveLine(models.Model):
_inherit = "stock.move.line"

product_packaging_id = fields.Many2one(
related="move_id.product_packaging_id", readonly=True
)
product_packaging_qty_done = fields.Float(
string="Done Pkg. Qty.",
help="Product packaging quantity done.",
)

def _get_aggregated_properties(self, move_line=False, move=False):
"""Aggregate by product packaging too."""
result = super()._get_aggregated_properties(move_line, move)
pkg = result["move"].product_packaging_id
result["product_packaging"] = pkg
result["line_key"] += f"_{pkg.id}"
return result

def _get_aggregated_product_quantities(self, **kwargs):
"""Aggregate by product packaging too."""
result = super()._get_aggregated_product_quantities(**kwargs)
# Know all involved move lines, following upstream criteria
all_lines = self.browse()
processed_moves = all_lines.move_id
if kwargs.get("except_package"):
all_lines |= self - self.filtered("result_package_id")
if not kwargs.get("strict"):
moves = (self.picking_id | self.picking_id.backorder_ids).move_ids
all_lines |= moves.move_line_ids | moves.move_line_nosuggest_ids
# Aggregate product packaging quantities
for move_line in all_lines:
props = self._get_aggregated_properties(move_line)
try:
agg = result[props["line_key"]]
except KeyError:
continue # Missing aggregation; nothing to do
agg.setdefault("product_packaging_qty", 0.0)
agg.setdefault("product_packaging_qty_done", 0.0)
agg["product_packaging_qty_done"] += move_line.product_packaging_qty_done
if move_line.move_id not in processed_moves:
agg["product_packaging_qty"] += move_line.move_id.product_packaging_qty
processed_moves |= move_line.move_id
return result
2 changes: 1 addition & 1 deletion stock_move_packaging_qty/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Add packaging fields in the stock moves and their reports.
Add packaging fields in the stock moves, their lines and their reports.
5 changes: 5 additions & 0 deletions stock_move_packaging_qty/readme/ROADMAP.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
* Maybe we should track also reserved packaging quantities?

* Since we store done product packaging quantities in the stock move lines, we
should be able to use this information in quants to provide real
packaging-based stock data.
35 changes: 23 additions & 12 deletions stock_move_packaging_qty/static/description/index.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
Expand Down Expand Up @@ -366,48 +367,58 @@ <h1 class="title">Stock Packaging Qty</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:ac3969cedf86da72ca20a93812053d6d9054a9f5d8e0c896eab57fe2b835eefc
!! source digest: sha256:5b4005788a852d7f71c44042e6c8839be5963fd5d6ac95822b93c48c660a2730
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/licence-LGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/stock-logistics-warehouse/tree/16.0/stock_move_packaging_qty"><img alt="OCA/stock-logistics-warehouse" src="https://img.shields.io/badge/github-OCA%2Fstock--logistics--warehouse-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/stock-logistics-warehouse-16-0/stock-logistics-warehouse-16-0-stock_move_packaging_qty"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/stock-logistics-warehouse&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>Add packaging fields in the stock moves and their reports.</p>
<p>Add packaging fields in the stock moves, their lines and their reports.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-1">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-2">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-3">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-4">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-5">Maintainers</a></li>
<li><a class="reference internal" href="#known-issues-roadmap" id="toc-entry-1">Known issues / Roadmap</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-2">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-3">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-4">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-5">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-6">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="known-issues-roadmap">
<h1><a class="toc-backref" href="#toc-entry-1">Known issues / Roadmap</a></h1>
<ul class="simple">
<li>Maybe we should track also reserved packaging quantities?</li>
<li>Since we store done product packaging quantities in the stock move lines, we
should be able to use this information in quants to provide real
packaging-based stock data.</li>
</ul>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-1">Bug Tracker</a></h1>
<h1><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/stock-logistics-warehouse/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/stock-logistics-warehouse/issues/new?body=module:%20stock_move_packaging_qty%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#toc-entry-2">Credits</a></h1>
<h1><a class="toc-backref" href="#toc-entry-3">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-3">Authors</a></h2>
<h2><a class="toc-backref" href="#toc-entry-4">Authors</a></h2>
<ul class="simple">
<li>ForgeFlow</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-4">Contributors</a></h2>
<h2><a class="toc-backref" href="#toc-entry-5">Contributors</a></h2>
<ul class="simple">
<li>Mateu Griful &lt;<a class="reference external" href="mailto:mateu.griful&#64;forgeflow.com">mateu.griful&#64;forgeflow.com</a>&gt;</li>
<li>Lois Rilo &lt;<a class="reference external" href="mailto:lois.rilo&#64;forgeflow.com">lois.rilo&#64;forgeflow.com</a>&gt;</li>
<li>Jairo Llopis (<a class="reference external" href="https://www.moduon.team/">Moduon</a>)</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-5">Maintainers</a></h2>
<h2><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
Expand Down
26 changes: 25 additions & 1 deletion stock_move_packaging_qty/tests/test_stock_move_packaging_qty.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@ def setUpClass(cls):
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
cls.env.user.groups_id |= cls.env.ref("product.group_stock_packaging")
cls.partner = cls.env.ref("base.res_partner_12")
cls.product = cls.env.ref("product.product_product_9")
cls.product = cls.env["product.product"].create(
{
"name": "Test product",
"type": "consu",
"uom_id": cls.env.ref("uom.product_uom_unit").id,
"uom_po_id": cls.env.ref("uom.product_uom_unit").id,
}
)
cls.packaging = cls.env["product.packaging"].create(
{"name": "Test packaging", "product_id": cls.product.id, "qty": 5.0}
)
Expand Down Expand Up @@ -59,3 +66,20 @@ def test_product_uom_qty_change(self):
move_f.product_packaging_id = self.packaging
self.assertEqual(move_f.product_uom_qty, 5)
self.assertEqual(move_f.product_packaging_qty, 1)
picking = picking_f.save()
self.assertEqual(picking.state, "draft")
picking.action_assign()
picking.action_set_quantities_to_reservation()
yajo marked this conversation as resolved.
Show resolved Hide resolved
yajo marked this conversation as resolved.
Show resolved Hide resolved
self.assertRecordValues(
picking.move_ids_without_package,
[
{
"product_id": self.product.id,
"product_packaging_id": self.packaging.id,
"product_packaging_qty_done": 1,
"product_packaging_qty": 1,
"product_uom_qty": 5,
}
],
)
picking.button_validate()
67 changes: 67 additions & 0 deletions stock_move_packaging_qty/views/report_stock_picking.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,72 @@
<span t-field="move.product_packaging_qty" />
</div>
</xpath>

<xpath
expr="//table[@name='stock_move_table']/tbody//td[
1 + count(
//table[@name='stock_move_table']
//th[@name='th_sm_quantity']
/preceding-sibling::*
)
]"
position="inside"
>
<div
t-if="move.product_packaging_id"
class="text-secondary"
groups="product.group_stock_packaging"
>
<span t-field="move.product_packaging_id" />:
<span t-field="move.product_packaging_qty_done" />
</div>
</xpath>
</template>

<template
id="stock_report_delivery_aggregated_move_lines"
inherit_id="stock.stock_report_delivery_aggregated_move_lines"
>
<xpath expr="//td[@name='move_line_aggregated_qty_ordered']">
<div
t-if="aggregated_lines[line]['product_packaging']"
class="text-secondary"
groups="product.group_stock_packaging"
>
<span
t-esc="aggregated_lines[line]['product_packaging'].display_name"
/>:
<span t-esc="aggregated_lines[line]['product_packaging_qty']" />
</div>
</xpath>

<xpath expr="//td[@name='move_line_aggregated_qty_done']">
<div
t-if="aggregated_lines[line]['product_packaging']"
class="text-secondary"
groups="product.group_stock_packaging"
>
<span
t-esc="aggregated_lines[line]['product_packaging'].display_name"
/>:
<span t-esc="aggregated_lines[line]['product_packaging_qty_done']" />
</div>
</xpath>
</template>

<template
id="stock_report_delivery_has_serial_move_line"
inherit_id="stock.stock_report_delivery_has_serial_move_line"
>
<xpath expr="//td[@name='move_line_lot_qty_done']">
<div
t-if="ml.product_packaging_id"
class="text-secondary"
groups="product.group_stock_packaging"
>
<span t-field="ml.product_packaging_id" />:
<span t-field="ml.product_packaging_qty_done" />
</div>
</xpath>
</template>
</data>
Loading
Loading