[IMP] stock_picking_batch_collect: collected checks on transfers, ordered quantity, delivery slips report

- 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>
This commit is contained in:
GitHub Copilot 2026-10-04 14:32:38 +02:00
parent 76dc355c6c
commit 9c81cb986d
Signed by: snt
GPG key ID: A9FD34930EADBE71
24 changed files with 630 additions and 39 deletions

View file

@ -0,0 +1,55 @@
# 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