[IMP] stock_picking_batch_collect: demanded quantity on the move line lists
The move lists already show the demand, the move line ones do not: the detailed operations of the batch and of the transfer, and the operator (Basket Assembly) view. Adds a read-only column with the demand of the line's move, in the unit of the line, next to the ordered quantity. Closes #21 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
fac8299c9c
commit
18cfd38347
11 changed files with 93 additions and 1 deletions
|
|
@ -29,6 +29,11 @@ producto y una vista a pantalla completa para el almacén.
|
|||
comparar lo pedido con lo preparado en la misma pantalla. Está en las
|
||||
operaciones detalladas, la vista de operario, la pestaña *Operations* y el
|
||||
resumen por producto del lote, y en el albarán.
|
||||
- Columna **Cantidad demandada** (``move_demand_qty``), de sólo lectura, en las
|
||||
listas de líneas de movimiento, que no la traen de serie: las operaciones
|
||||
detalladas del lote y del albarán y la vista de operario. Es la demanda del
|
||||
movimiento completo, así que se repite en cada línea de un movimiento
|
||||
repartido en varias (lotes, ubicaciones).
|
||||
- Informe **Albaranes** en el lote: todos sus albaranes de entrega en un PDF.
|
||||
|
||||
Las columnas se añaden con ``optional="show"`` en la vista de líneas del lote
|
||||
|
|
@ -136,6 +141,8 @@ Uso
|
|||
9. La columna **Cantidad pedida** muestra lo que pidió el cliente, frente a la
|
||||
demanda (ya ajustada al peso) y la cantidad preparada. En el resumen por
|
||||
producto del lote es la suma de los pedidos.
|
||||
La columna **Cantidad demandada** está junto a ella en todas las vistas,
|
||||
también en la vista de operario.
|
||||
|
||||
10. **Imprimir > Albaranes** en el lote genera un único PDF con el albarán de
|
||||
entrega de cada uno de sus traslados (salvo los cancelados), ordenados por
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
{ # noqa: B018
|
||||
"name": "Stock Picking Batch Collect",
|
||||
"version": "18.0.2.1.0",
|
||||
"version": "18.0.2.2.0",
|
||||
"category": "Warehouse",
|
||||
"summary": "Collect batch operations: operator view, extra columns and product summary",
|
||||
"author": "Odoo Community Association (OCA), Criptomart",
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ msgid "Created on"
|
|||
msgstr "Creado el"
|
||||
|
||||
#. module: stock_picking_batch_collect
|
||||
#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_move_line__move_demand_qty
|
||||
#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__qty_demanded
|
||||
msgid "Demanded Quantity"
|
||||
msgstr "Cantidad demandada"
|
||||
|
|
@ -282,3 +283,8 @@ msgid ""
|
|||
msgstr ""
|
||||
"Hay que marcar como recogidas las operaciones de %(picking)s antes de validarlo.\n"
|
||||
"Productos pendientes: %(products)s"
|
||||
|
||||
#. module: stock_picking_batch_collect
|
||||
#: model_terms:ir.ui.view,arch_db:stock_picking_batch_collect.view_move_line_batch_operator
|
||||
msgid "Demand"
|
||||
msgstr "Demanda"
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ msgid "Created on"
|
|||
msgstr "Noiz sortua"
|
||||
|
||||
#. module: stock_picking_batch_collect
|
||||
#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_move_line__move_demand_qty
|
||||
#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__qty_demanded
|
||||
msgid "Demanded Quantity"
|
||||
msgstr "Eskatutako kantitatea"
|
||||
|
|
@ -282,3 +283,8 @@ msgid ""
|
|||
msgstr ""
|
||||
"%(picking)s balidatu aurretik, bere eragiketak jasota gisa markatu behar dira.\n"
|
||||
"Zain dauden produktuak: %(products)s"
|
||||
|
||||
#. module: stock_picking_batch_collect
|
||||
#: model_terms:ir.ui.view,arch_db:stock_picking_batch_collect.view_move_line_batch_operator
|
||||
msgid "Demand"
|
||||
msgstr "Eskaria"
|
||||
|
|
|
|||
|
|
@ -41,6 +41,11 @@ class StockMoveLine(models.Model):
|
|||
digits="Product Unit of Measure",
|
||||
compute="_compute_sale_ordered_qty",
|
||||
)
|
||||
move_demand_qty = fields.Float(
|
||||
string="Demanded Quantity",
|
||||
digits="Product Unit of Measure",
|
||||
compute="_compute_move_demand_qty",
|
||||
)
|
||||
|
||||
@api.depends("move_id.sale_ordered_qty", "move_id.product_uom", "product_uom_id")
|
||||
def _compute_sale_ordered_qty(self):
|
||||
|
|
@ -53,6 +58,18 @@ class StockMoveLine(models.Model):
|
|||
else:
|
||||
line.sale_ordered_qty = 0.0
|
||||
|
||||
@api.depends("move_id.product_uom_qty", "move_id.product_uom", "product_uom_id")
|
||||
def _compute_move_demand_qty(self):
|
||||
"""The demand of the whole move: every line of a split move shows it."""
|
||||
for line in self:
|
||||
move = line.move_id
|
||||
if move.product_uom and line.product_uom_id:
|
||||
line.move_demand_qty = move.product_uom._compute_quantity(
|
||||
move.product_uom_qty, line.product_uom_id, round=False
|
||||
)
|
||||
else:
|
||||
line.move_demand_qty = 0.0
|
||||
|
||||
def write(self, vals):
|
||||
res = super().write(vals)
|
||||
if vals.get("is_collected"):
|
||||
|
|
|
|||
|
|
@ -23,6 +23,11 @@ producto y una vista a pantalla completa para el almacén.
|
|||
comparar lo pedido con lo preparado en la misma pantalla. Está en las
|
||||
operaciones detalladas, la vista de operario, la pestaña *Operations* y el
|
||||
resumen por producto del lote, y en el albarán.
|
||||
- Columna **Cantidad demandada** (``move_demand_qty``), de sólo lectura, en las
|
||||
listas de líneas de movimiento, que no la traen de serie: las operaciones
|
||||
detalladas del lote y del albarán y la vista de operario. Es la demanda del
|
||||
movimiento completo, así que se repite en cada línea de un movimiento
|
||||
repartido en varias (lotes, ubicaciones).
|
||||
- Informe **Albaranes** en el lote: todos sus albaranes de entrega en un PDF.
|
||||
|
||||
Las columnas se añaden con ``optional="show"`` en la vista de líneas del lote
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ Uso
|
|||
9. La columna **Cantidad pedida** muestra lo que pidió el cliente, frente a la
|
||||
demanda (ya ajustada al peso) y la cantidad preparada. En el resumen por
|
||||
producto del lote es la suma de los pedidos.
|
||||
La columna **Cantidad demandada** está junto a ella en todas las vistas,
|
||||
también en la vista de operario.
|
||||
|
||||
10. **Imprimir > Albaranes** en el lote genera un único PDF con el albarán de
|
||||
entrega de cada uno de sus traslados (salvo los cancelados), ordenados por
|
||||
|
|
|
|||
|
|
@ -110,6 +110,50 @@ class TestPickingCollected(TransactionCase):
|
|||
self.assertEqual(move.sale_ordered_qty, 2.0)
|
||||
self.assertEqual(move.move_line_ids.sale_ordered_qty, 2.0)
|
||||
|
||||
def test_move_line_demand_follows_the_move(self):
|
||||
picking = self._create_sale_picking(2.0)
|
||||
move = picking.move_ids
|
||||
line = move.move_line_ids
|
||||
|
||||
self.assertEqual(line.move_demand_qty, 2.0)
|
||||
|
||||
gram = self.env.ref("uom.product_uom_gram")
|
||||
line.product_uom_id = gram
|
||||
self.assertEqual(line.move_demand_qty, 2000.0)
|
||||
|
||||
move.product_uom_qty = 3.0
|
||||
self.assertEqual(line.move_demand_qty, 3000.0)
|
||||
|
||||
def test_move_line_demand_without_sale(self):
|
||||
"""Unlike the ordered quantity, the demand needs no sale order."""
|
||||
picking = self.env["stock.picking"].create(
|
||||
{
|
||||
"picking_type_id": self.picking_type_out.id,
|
||||
"location_id": self.stock_location.id,
|
||||
"location_dest_id": self.env.ref("stock.stock_location_customers").id,
|
||||
"move_ids": [
|
||||
Command.create(
|
||||
{
|
||||
"name": self.product.name,
|
||||
"product_id": self.product.id,
|
||||
"product_uom_qty": 4.0,
|
||||
"product_uom": self.product.uom_id.id,
|
||||
"location_id": self.stock_location.id,
|
||||
"location_dest_id": self.env.ref(
|
||||
"stock.stock_location_customers"
|
||||
).id,
|
||||
}
|
||||
)
|
||||
],
|
||||
}
|
||||
)
|
||||
picking.action_confirm()
|
||||
picking.action_assign()
|
||||
line = picking.move_ids.move_line_ids
|
||||
|
||||
self.assertEqual(line.move_demand_qty, 4.0)
|
||||
self.assertEqual(line.sale_ordered_qty, 0.0)
|
||||
|
||||
def test_batch_summary_ordered_quantity(self):
|
||||
pickings = self._create_sale_picking(2.0) | self._create_sale_picking(3.0)
|
||||
batch = self.env["stock.picking.batch"].create(
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
<field name="reference" readonly="1" optional="hide"/>
|
||||
<field name="picking_partner_id" readonly="1" optional="show"/>
|
||||
<field name="sale_ordered_qty" string="Ordered" readonly="1" optional="show"/>
|
||||
<field name="move_demand_qty" string="Demand" readonly="1" optional="show"/>
|
||||
<field name="quantity" string="Cant."/>
|
||||
<!-- Loaded so `_onchange_quantity_manual` reaches the server. -->
|
||||
<field name="picked" column_invisible="True"/>
|
||||
|
|
@ -82,6 +83,7 @@
|
|||
</xpath>
|
||||
<xpath expr="//field[@name='quantity']" position="before">
|
||||
<field name="sale_ordered_qty" readonly="1" optional="show"/>
|
||||
<field name="move_demand_qty" readonly="1" optional="show"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='quantity']" position="after">
|
||||
<!-- Loaded so `_onchange_quantity_manual` reaches the server. -->
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
<xpath expr="//field[@name='quantity']" position="before">
|
||||
<field name="sale_ordered_qty" readonly="1" optional="show"
|
||||
column_invisible="context.get('picking_code') == 'incoming'"/>
|
||||
<field name="move_demand_qty" readonly="1" optional="show"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='quantity']" position="after">
|
||||
<field name="is_collected" widget="boolean_toggle" optional="show"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue