- The collected checks also apply to transfers outside a batch, opt-in per
operation type ("Require Collected Lines"), with the batch restrictions of
the settings. A per-product toggle in the transfer's Operations tab collects
all its lines.
- Read-only ordered quantity from the sale line on every batch and transfer
view, since the weighed demand overwrites it. Adds a dependency on
sale_stock; a migration fills it in the summary of open batches.
- "Delivery Slips" report on the batch: all its delivery slips in one PDF.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
55 lines
1.8 KiB
Python
55 lines
1.8 KiB
Python
# Copyright 2026 Criptomart
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
|
|
from odoo import api
|
|
from odoo import fields
|
|
from odoo import models
|
|
|
|
|
|
class StockMove(models.Model):
|
|
_inherit = "stock.move"
|
|
|
|
is_collected = fields.Boolean(
|
|
string="Collected",
|
|
compute="_compute_is_collected",
|
|
inverse="_inverse_is_collected",
|
|
)
|
|
sale_ordered_qty = fields.Float(
|
|
string="Ordered Quantity",
|
|
digits="Product Unit of Measure",
|
|
compute="_compute_sale_ordered_qty",
|
|
)
|
|
|
|
@api.depends("move_line_ids.is_collected")
|
|
def _compute_is_collected(self):
|
|
for move in self:
|
|
lines = move.move_line_ids
|
|
move.is_collected = bool(lines) and all(lines.mapped("is_collected"))
|
|
|
|
def _inverse_is_collected(self):
|
|
collected = self.filtered("is_collected")
|
|
collected.move_line_ids.filtered(
|
|
lambda line: not line.is_collected
|
|
).is_collected = True
|
|
(self - collected).move_line_ids.filtered("is_collected").is_collected = False
|
|
|
|
@api.depends(
|
|
"product_id",
|
|
"product_uom",
|
|
"sale_line_id.product_id",
|
|
"sale_line_id.product_uom",
|
|
"sale_line_id.product_uom_qty",
|
|
)
|
|
def _compute_sale_ordered_qty(self):
|
|
"""What the customer ordered, which the weighed demand overwrites.
|
|
|
|
Kit components carry the kit's sale line, whose quantity is not theirs.
|
|
"""
|
|
for move in self:
|
|
line = move.sale_line_id
|
|
if line and line.product_id == move.product_id and move.product_uom:
|
|
move.sale_ordered_qty = line.product_uom._compute_quantity(
|
|
line.product_uom_qty, move.product_uom, round=False
|
|
)
|
|
else:
|
|
move.sale_ordered_qty = 0.0
|