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

[FIX]stock_secondary_unit: partial delivery #2224

Open
wants to merge 1 commit into
base: 16.0
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion stock_secondary_unit/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{
"name": "Stock Secondary Unit",
"summary": "Get product quantities in a secondary unit",
"version": "16.0.1.1.2",
"version": "16.0.1.1.3",
"development_status": "Production/Stable",
"category": "stock",
"website": "https://github.com/OCA/stock-logistics-warehouse",
Expand Down
2 changes: 2 additions & 0 deletions stock_secondary_unit/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
from . import product_product
from . import product_template
from . import stock_move
from . import stock_move_line
from . import stock_picking
87 changes: 87 additions & 0 deletions stock_secondary_unit/models/stock_move_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
from odoo.tools import float_is_zero
from odoo.addons.stock.models.stock_move_line import StockMoveLine

def _new_get_aggregated_product_quantities(self, **kwargs):
""" Returns a dictionary of products (key = id+name+description+uom) and corresponding values of interest.
Allows aggregation of data across separate move lines for the same product. This is expected to be useful
in things such as delivery reports. Dict key is made as a combination of values we expect to want to group
the products by (i.e. so data is not lost). This function purposely ignores lots/SNs because these are
expected to already be properly grouped by line.
returns: dictionary {product_id+name+description+uom: {product, name, description, qty_done, product_uom}, ...}
"""
aggregated_move_lines = {}

Check warning on line 12 in stock_secondary_unit/models/stock_move_line.py

View check run for this annotation

Codecov / codecov/patch

stock_secondary_unit/models/stock_move_line.py#L12

Added line #L12 was not covered by tests

# Loops to get backorders, backorders' backorders, and so and so...
backorders = self.env['stock.picking']
pickings = self.picking_id

Check warning on line 16 in stock_secondary_unit/models/stock_move_line.py

View check run for this annotation

Codecov / codecov/patch

stock_secondary_unit/models/stock_move_line.py#L15-L16

Added lines #L15 - L16 were not covered by tests
while pickings.backorder_ids:
backorders |= pickings.backorder_ids
pickings = pickings.backorder_ids

Check warning on line 19 in stock_secondary_unit/models/stock_move_line.py

View check run for this annotation

Codecov / codecov/patch

stock_secondary_unit/models/stock_move_line.py#L18-L19

Added lines #L18 - L19 were not covered by tests

for move_line in self:

if kwargs.get('except_package') and move_line.result_package_id:
continue
aggregated_properties = self._get_aggregated_properties(move_line=move_line)
line_key = f"{aggregated_properties['line_key']}_{move_line.id}"
uom = aggregated_properties['product_uom']
qty_done = move_line.product_uom_id._compute_quantity(move_line.qty_done, uom)

Check warning on line 28 in stock_secondary_unit/models/stock_move_line.py

View check run for this annotation

Codecov / codecov/patch

stock_secondary_unit/models/stock_move_line.py#L24-L28

Added lines #L24 - L28 were not covered by tests
if line_key not in aggregated_move_lines:
qty_ordered = None

Check warning on line 30 in stock_secondary_unit/models/stock_move_line.py

View check run for this annotation

Codecov / codecov/patch

stock_secondary_unit/models/stock_move_line.py#L30

Added line #L30 was not covered by tests
if backorders and not kwargs.get('strict'):
qty_ordered = move_line.move_id.product_uom_qty

Check warning on line 32 in stock_secondary_unit/models/stock_move_line.py

View check run for this annotation

Codecov / codecov/patch

stock_secondary_unit/models/stock_move_line.py#L32

Added line #L32 was not covered by tests
# Filters on the aggregation key (product, description and uom) to add the
# quantities delayed to backorders to retrieve the original ordered qty.
following_move_lines = backorders.move_line_ids.filtered(

Check warning on line 35 in stock_secondary_unit/models/stock_move_line.py

View check run for this annotation

Codecov / codecov/patch

stock_secondary_unit/models/stock_move_line.py#L35

Added line #L35 was not covered by tests
lambda ml: self._get_aggregated_properties(move=ml.move_id)['line_key'] == line_key
)
qty_ordered += sum(following_move_lines.move_id.mapped('product_uom_qty'))

Check warning on line 38 in stock_secondary_unit/models/stock_move_line.py

View check run for this annotation

Codecov / codecov/patch

stock_secondary_unit/models/stock_move_line.py#L38

Added line #L38 was not covered by tests
# Remove the done quantities of the other move lines of the stock move
previous_move_lines = move_line.move_id.move_line_ids.filtered(

Check warning on line 40 in stock_secondary_unit/models/stock_move_line.py

View check run for this annotation

Codecov / codecov/patch

stock_secondary_unit/models/stock_move_line.py#L40

Added line #L40 was not covered by tests
lambda ml: self._get_aggregated_properties(move=ml.move_id)['line_key'] == line_key and ml.id != move_line.id
)
qty_ordered -= sum(map(lambda m: m.product_uom_id._compute_quantity(m.qty_done, aggregated_properties['product_uom']), previous_move_lines))
aggregated_move_lines[line_key] = {

Check warning on line 44 in stock_secondary_unit/models/stock_move_line.py

View check run for this annotation

Codecov / codecov/patch

stock_secondary_unit/models/stock_move_line.py#L43-L44

Added lines #L43 - L44 were not covered by tests
**aggregated_properties,
'qty_done': qty_done,
'qty_ordered': qty_ordered or qty_done,
'product': move_line.product_id,
'secondary_uom_qty': move_line.secondary_uom_qty,
'secondary_uom_id': move_line.secondary_uom_id.name

}
else:
aggregated_move_lines[line_key]['qty_ordered'] += qty_done
aggregated_move_lines[line_key]['qty_done'] += qty_done

Check warning on line 55 in stock_secondary_unit/models/stock_move_line.py

View check run for this annotation

Codecov / codecov/patch

stock_secondary_unit/models/stock_move_line.py#L54-L55

Added lines #L54 - L55 were not covered by tests

# Does the same for empty move line to retrieve the ordered qty. for partially done moves
# (as they are splitted when the transfer is done and empty moves don't have move lines).
if kwargs.get('strict'):
return aggregated_move_lines
pickings = (self.picking_id | backorders)

Check warning on line 61 in stock_secondary_unit/models/stock_move_line.py

View check run for this annotation

Codecov / codecov/patch

stock_secondary_unit/models/stock_move_line.py#L60-L61

Added lines #L60 - L61 were not covered by tests
for empty_move in pickings.move_ids:
to_bypass = False

Check warning on line 63 in stock_secondary_unit/models/stock_move_line.py

View check run for this annotation

Codecov / codecov/patch

stock_secondary_unit/models/stock_move_line.py#L63

Added line #L63 was not covered by tests
if not (empty_move.product_uom_qty and float_is_zero(empty_move.quantity_done, precision_rounding=empty_move.product_uom.rounding)):
continue

Check warning on line 65 in stock_secondary_unit/models/stock_move_line.py

View check run for this annotation

Codecov / codecov/patch

stock_secondary_unit/models/stock_move_line.py#L65

Added line #L65 was not covered by tests
if empty_move.state != "cancel":
if empty_move.state != "confirmed" or empty_move.move_line_ids:
continue

Check warning on line 68 in stock_secondary_unit/models/stock_move_line.py

View check run for this annotation

Codecov / codecov/patch

stock_secondary_unit/models/stock_move_line.py#L68

Added line #L68 was not covered by tests
else:
to_bypass = True
aggregated_properties = self._get_aggregated_properties(move=empty_move)
line_key = aggregated_properties['line_key']

Check warning on line 72 in stock_secondary_unit/models/stock_move_line.py

View check run for this annotation

Codecov / codecov/patch

stock_secondary_unit/models/stock_move_line.py#L70-L72

Added lines #L70 - L72 were not covered by tests

if line_key not in aggregated_move_lines and not to_bypass:
qty_ordered = empty_move.product_uom_qty
aggregated_move_lines[line_key] = {

Check warning on line 76 in stock_secondary_unit/models/stock_move_line.py

View check run for this annotation

Codecov / codecov/patch

stock_secondary_unit/models/stock_move_line.py#L75-L76

Added lines #L75 - L76 were not covered by tests
**aggregated_properties,
'qty_done': False,
'qty_ordered': qty_ordered,
'product': empty_move.product_id,
}
elif line_key in aggregated_move_lines:
aggregated_move_lines[line_key]['qty_ordered'] += empty_move.product_uom_qty

Check warning on line 83 in stock_secondary_unit/models/stock_move_line.py

View check run for this annotation

Codecov / codecov/patch

stock_secondary_unit/models/stock_move_line.py#L83

Added line #L83 was not covered by tests
# import pdb;pdb.set_trace()
return aggregated_move_lines

Check warning on line 85 in stock_secondary_unit/models/stock_move_line.py

View check run for this annotation

Codecov / codecov/patch

stock_secondary_unit/models/stock_move_line.py#L85

Added line #L85 was not covered by tests

StockMoveLine._get_aggregated_product_quantities = _new_get_aggregated_product_quantities
29 changes: 29 additions & 0 deletions stock_secondary_unit/models/stock_picking.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from odoo import models


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

def _create_backorder(self):
res = super(StockPicking, self)._create_backorder()
for original_move in self.move_ids:
corresponding_move = next(
(
move
for move in res.move_ids
if move.product_id == original_move.product_id
),
None,
)
if corresponding_move and corresponding_move.secondary_uom_qty:
# To avoid rounding errors, Saving the current value of product_uom_qty
# before recalculating the secondary unit. Afterward,
# I'll restore the original value
product_uom_qty = corresponding_move.product_uom_qty
corresponding_move.with_context(

Check warning on line 23 in stock_secondary_unit/models/stock_picking.py

View check run for this annotation

Codecov / codecov/patch

stock_secondary_unit/models/stock_picking.py#L22-L23

Added lines #L22 - L23 were not covered by tests
bypass_compute_field_qty=True
)._compute_secondary_uom_qty()
corresponding_move.product_uom_qty = product_uom_qty

Check warning on line 26 in stock_secondary_unit/models/stock_picking.py

View check run for this annotation

Codecov / codecov/patch

stock_secondary_unit/models/stock_picking.py#L26

Added line #L26 was not covered by tests
else:
continue
return res
34 changes: 17 additions & 17 deletions stock_secondary_unit/report/report_deliveryslip.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,8 @@
<!-- Copyright 2018 Tecnativa - Sergio Teruel
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<template
id="report_delivery_document"
inherit_id="stock.report_delivery_document"
priority="8"
>
<xpath
expr='//table[@t-if="o.state!=&apos;done&apos;"]/thead/tr/th'
position="after"
>
<template id="report_delivery_document" inherit_id="stock.report_delivery_document" priority="8">
<xpath expr='//table[@t-if="o.state!=&apos;done&apos;"]/thead/tr/th' position="after">
<th>
<strong>Secondary Qty</strong>
</th>
Expand All @@ -21,24 +14,31 @@
<span t-field="move.secondary_uom_id.name" />
</td>
</xpath>
<xpath
expr='//table[@t-if="o.move_line_ids and o.state==&apos;done&apos;"]/thead/tr/th'
position="after"
>
<xpath expr='//table[@t-if="o.move_line_ids and o.state==&apos;done&apos;"]/thead/tr/th' position="after">
<th>
<strong>Secondary Qty</strong>
</th>
</xpath>
</template>
<template
id="stock_report_delivery_has_serial_move_line"
inherit_id="stock.stock_report_delivery_has_serial_move_line"
>
<template id="stock_report_delivery_has_serial_move_line" inherit_id="stock.stock_report_delivery_has_serial_move_line">
<xpath expr="//span[@t-field='move_line.product_id']/.." position="after">
<td>
<span t-field="move_line.secondary_uom_qty" />
<span t-field="move_line.secondary_uom_id" />
</td>
</xpath>
</template>

<template id="stock_report_delivery_aggregated_move_lines_ux" inherit_id="stock.stock_report_delivery_aggregated_move_lines">
<xpath expr="//td[@name='move_line_aggregated_qty_done']" position="before">
<td class="text-center" name="move_line_aggregated_secondary_unit">
<t t-if="aggregated_lines[line]['qty_done']">
<span t-esc="aggregated_lines[line]['secondary_uom_qty']"/>
<span t-esc="aggregated_lines[line]['secondary_uom_id']"/>

</t>
</td>

</xpath>
</template>
</odoo>
Loading