diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index cb37e4b..0f33715 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -189,9 +189,11 @@ addons-cm/ ├── membership_monthly_invoicing/ # Factura mensual de membresía por socio (cron) ├── membership_expiry_reminder/ # Email recordatorio de renovación próxima ├── # --- Logística y contabilidad --- -├── stock_picking_batch_custom/ # Batch picking: columnas extra + vista operario (Basket Assembly) +├── stock_picking_batch_collect/ # Batch picking: columnas extra + vista operario (Basket Assembly) ├── account_banking_mandate_batch/ # Crear/validar mandatos SEPA en bloque desde contactos -└── l10n_es_edi_tbai_reagyp_recibidas/ # Fix TicketBAI REAGYP facturas recibidas (19 → 02) +├── l10n_es_edi_tbai_reagyp_recibidas/ # Fix TicketBAI REAGYP facturas recibidas (19 → 02) +├── # --- UI de backend --- +└── web_list_striped/ # Efecto cebra en todas las listas del backend (sólo CSS) ```` @@ -233,7 +235,8 @@ addons-cm/ **Logística y contabilidad** -- [stock_picking_batch_custom](../stock_picking_batch_custom/README.rst) - Columnas extra y vista operario para batch picking +- [stock_picking_batch_collect](../stock_picking_batch_collect/README.rst) - Columnas extra, resumen por producto y vista operario para batch picking +- [web_list_striped](../web_list_striped/README.rst) - Efecto cebra en todas las listas del backend (sólo CSS) - [account_banking_mandate_batch](../account_banking_mandate_batch/README.rst) - Creación masiva de mandatos SEPA desde contactos - [l10n_es_edi_tbai_reagyp_recibidas](../l10n_es_edi_tbai_reagyp_recibidas/README.rst) - Fix TicketBAI REAGYP en facturas recibidas (clave régimen 19 → 02) @@ -758,6 +761,10 @@ last_purchase_price_compute_type != "manual_update" # Para auto-cálculo `product_pricelist_total_margin`, `product_origin_char`, `l10n_es_edi_tbai_reagyp_recibidas`. `product_origin` (OCA) sustituido por `product_origin_char` (custom). - **2026-06-04**: `product_sale_price_from_pricelist` aplica descuentos de proveedor desde `supplierinfo`. +- **2026-08-27**: `stock_picking_batch_custom` renombrado a `stock_picking_batch_collect` + (v18.0.2.0.0). Se invierte la dependencia: ya no depende de `website_sale_aplicoop`; es este + el que depende de él e inyecta las columnas de grupo de consumo. El efecto cebra global se + extrae al nuevo addon `web_list_striped`. El renombrado en BD lo hace un `pre_init_hook`. - **2026-06**: `stock_picking_batch_custom` — vista operario a pantalla completa (Basket Assembly), ordenación de operaciones por categoría/producto/partner. - **2026-02-18**: Refactor `product_main_seller` - Remover alias innecesario `default_supplier_id` diff --git a/README.md b/README.md index 8dbf2e0..2a34a8b 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,9 @@ Addons desarrollados por Criptomart para necesidades específicas del proyecto. | [product_price_category_supplier](product_price_category_supplier/) | 18.0.1.0.0 | Categoría de precio por defecto en proveedor + actualización masiva de productos | | [product_pricelist_total_margin](product_pricelist_total_margin/) | 18.0.1.2.0 | Margen aditivo (no compuesto) en tarifas encadenadas, con límites globales | | [product_sale_price_from_pricelist](product_sale_price_from_pricelist/) | 18.0.2.7.0 | Calcula precio de venta desde último precio de compra vía tarifa configurable | -| [stock_picking_batch_custom](stock_picking_batch_custom/) | 18.0.1.0.0 | Columnas extra en operaciones detalladas de lotes: partner, categoría, recogido | -| [website_sale_aplicoop](website_sale_aplicoop/) | 18.0.1.9.0 | Sistema de pedidos colaborativos para grupos de consumo (reemplazo de Aplicoop) | +| [stock_picking_batch_collect](stock_picking_batch_collect/) | 18.0.2.0.0 | Montaje de cestas en lotes: columnas extra, resumen por producto y vista operario | +| [web_list_striped](web_list_striped/) | 18.0.1.0.0 | Efecto cebra y hover suave en todas las listas del backend (sólo CSS) | +| [website_sale_aplicoop](website_sale_aplicoop/) | 18.0.1.17.0 | Sistema de pedidos colaborativos para grupos de consumo (reemplazo de Aplicoop) | ## Dependencias entre addons custom @@ -40,6 +41,12 @@ website_sale_aplicoop └── product_main_seller └── product_price_category_supplier └── product_price_category + └── stock_picking_batch_collect + └── stock_move_manual_quantity + +stock_picking_batch_collect + └── stock_move_manual_quantity + └── stock_picking_batch (Odoo core) account_invoice_triple_discount_readonly └── account_invoice_triple_discount diff --git a/stock_picking_batch_collect/README.rst b/stock_picking_batch_collect/README.rst new file mode 100644 index 0000000..75a70b6 --- /dev/null +++ b/stock_picking_batch_collect/README.rst @@ -0,0 +1,127 @@ +=========================== +Stock Picking Batch Collect +=========================== + +Visión general +============== +Este módulo convierte un lote de picking en una hoja de trabajo para el operario +que monta las cestas: amplía las operaciones detalladas, añade un resumen por +producto y una vista a pantalla completa para el almacén. + +- ``picking_partner_id`` (Partner del albarán) para que el personal de almacén + identifique rápido el cliente/proveedor. +- ``product_categ_id`` (Categoría de producto) para ordenar y agrupar. Las + líneas del lote se ordenan por categoría, producto y partner. +- ``product_default_code`` (Referencia interna) como columna opcional. +- ``is_collected`` (Recogido) como check manual en cada línea para marcar si se + ha recolectado. +- Nueva pestaña **Product Summary** con totales por producto (demandado, hecho, + pendiente), categoría y el check de recogido consolidado. +- Botón **Basket Assembly**: una vista de lista a pantalla completa, con + cantidades grandes y controles táctiles, pensada para tablet en el almacén. +- Restricciones de validación configurables por compañía: el lote no se puede + validar hasta que las líneas estén marcadas como recogidas. + +Las columnas se añaden con ``optional="show"`` en la vista de líneas del lote +(salvo ``product_default_code``, oculta por defecto), de modo que el usuario +puede desactivarlas desde el selector de columnas sin recargar la vista. + +Si además está instalado ``website_sale_aplicoop``, ese módulo añade a estas +mismas vistas las columnas de grupo de consumo (**Consumer Group** y **Home +Delivery**). Este módulo no depende de él: funciona igual sin la parte de +eCommerce. + +Instalación +=========== + +Actualizar o instalar el módulo: + +:: + + docker-compose run --rm odoo odoo -d odoo --stop-after-init -u stock_picking_batch_collect + +Este módulo sustituye a ``stock_picking_batch_custom``. Al instalarlo sobre una +base de datos que tuviera el módulo antiguo, un ``pre_init_hook`` adopta sus +datos (ver ``hooks.py``): se conservan las líneas recogidas, el resumen por +producto y la configuración por compañía. + +Configuración +============= + +Restricciones de validación +--------------------------- + +En **Inventory > Configuration > Settings**, bloque *Operations*, hay dos +ajustes por compañía: + +- **Restricciones del resumen de productos**: exige que las líneas de la + pestaña *Product Summary* estén marcadas como recogidas para validar el lote. + Desactivado por defecto (el check es sólo informativo). +- **Restricciones de operaciones detalladas**: exige que las líneas de la + pestaña *Detailed Operations* estén marcadas como recogidas. + **Activado por defecto**: recién instalado el módulo, un lote no se puede + validar hasta marcar las líneas. + +Cada restricción tiene un alcance: + +- *Sólo procesadas*: se comprueban únicamente las líneas con cantidad hecha + mayor que cero (por defecto). +- *Todas*: se comprueban todas las líneas del lote, procesadas o no. + +Columnas +-------- + +Las columnas están visibles por defecto. Para ajustarlas: + +- Abrir un **Lote de picking**. +- Ir a la pestaña **Detailed Operations**. +- Abrir el **selector de columnas** y activar o desactivar *Partner*, + *Product Category*, *Product Code* o *Collected* según necesidad. + +Uso +=== + +1. Accede a **Inventory > Operations > Batch Transfers** y abre un lote. +2. Pestaña **Detailed Operations**: usa el selector de columnas para ajustar: + + - **Partner** (``picking_partner_id``) para ver el cliente/proveedor. + - **Product Category** (``product_categ_id``) para ordenar/agrupación por categoría. + - **Collected** (``is_collected``) para marcar manualmente líneas recolectadas. + +3. Pestaña **Product Summary**: consulta los totales por producto (demandado, + hecho y pendiente) y marca el check de recogido consolidado si corresponde. + +4. Con el lote **en progreso**, el botón **Basket Assembly** abre la vista de + operario: la misma lista de líneas a pantalla completa, con la cantidad en + grande y el check *Collected* como interruptor táctil. Está pensada para + trabajar desde una tablet mientras se montan las cestas. + +5. Ordena o agrupa por categoría en cualquiera de las vistas según convenga. + +6. La cantidad que teclea el operario (el peso real de la balanza) queda fijada: + se marca como *Picked* y ni el planificador ni la validación de otros + albaranes vuelven a modificarla. Marcar **Collected** protege igualmente la + cantidad de la línea. Ver ``stock_move_manual_quantity``. + +7. Al validar el lote, según la configuración de la compañía, se comprueba que + las líneas estén recogidas y se avisa con la lista de productos pendientes. + La comprobación se ejecuta después de resolver el backorder, de modo que + sólo bloquea sobre las líneas que realmente se van a procesar. + +Contribuidores +============== + +* Criptomart + +Créditos +======== + +Autor +----- + +* Criptomart + +Financiador +----------- + +* Elika Bilbo diff --git a/stock_picking_batch_collect/__init__.py b/stock_picking_batch_collect/__init__.py new file mode 100644 index 0000000..4a5c3e3 --- /dev/null +++ b/stock_picking_batch_collect/__init__.py @@ -0,0 +1,2 @@ +from . import models # noqa: F401 +from .hooks import pre_init_hook # noqa: F401 diff --git a/stock_picking_batch_custom/__manifest__.py b/stock_picking_batch_collect/__manifest__.py similarity index 63% rename from stock_picking_batch_custom/__manifest__.py rename to stock_picking_batch_collect/__manifest__.py index 7ad2a39..7e61eac 100644 --- a/stock_picking_batch_custom/__manifest__.py +++ b/stock_picking_batch_collect/__manifest__.py @@ -1,10 +1,10 @@ # Copyright 2026 Criptomart # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { # noqa: B018 - "name": "Stock Picking Batch Custom", - "version": "18.0.1.0.0", + "name": "Stock Picking Batch Collect", + "version": "18.0.2.0.0", "category": "Warehouse", - "summary": "Extra columns for batch detailed operations", + "summary": "Collect batch operations: operator view, extra columns and product summary", "author": "Odoo Community Association (OCA), Criptomart", "maintainers": ["Criptomart"], "website": "https://github.com/Criptomart", @@ -14,9 +14,6 @@ # re-reserved by the scheduler. "stock_move_manual_quantity", "stock_picking_batch", - # Ensure our related fields to sale/picking (home_delivery, pickup_slot_label) - # are available by depending on the Aplicoop website_sale extension. - "website_sale_aplicoop", ], "data": [ "security/ir.model.access.csv", @@ -25,7 +22,10 @@ ], "assets": { "web.assets_backend": [ - "stock_picking_batch_custom/static/src/css/stock_picking_batch.css", + "stock_picking_batch_collect/static/src/css/stock_picking_batch.css", ], }, + # Adopts the data of the former `stock_picking_batch_custom` when upgrading + # a database where that module was installed. See `hooks.py`. + "pre_init_hook": "pre_init_hook", } diff --git a/stock_picking_batch_collect/hooks.py b/stock_picking_batch_collect/hooks.py new file mode 100644 index 0000000..7dcdaf4 --- /dev/null +++ b/stock_picking_batch_collect/hooks.py @@ -0,0 +1,117 @@ +# Copyright 2026 Criptomart +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging + +_logger = logging.getLogger(__name__) + +OLD_MODULE = "stock_picking_batch_custom" +NEW_MODULE = "stock_picking_batch_collect" + +# Fields handed over to `website_sale_aplicoop`, which declares the very same +# ones. Dropping just the xmlid is enough and is what we want: Odoo matches the +# existing row again by (model, name) and re-registers it under aplicoop's +# ownership later in the same run (aplicoop depends on us, so it loads after +# us). Both are non-stored, so no column is touched. +HANDED_OVER = ( + "field_stock_move_line__home_delivery", + "field_stock_move_line__consumer_group_id", +) + +# Artifacts that disappear for good, because aplicoop already stores the same +# value as `stock.picking.consumer_group_id`. Here the record itself has to go +# too, not only the xmlid: deleting an `ir_model_data` row does not cascade, so +# the field would survive as an orphan manual field and the view as a custom +# view still pointing at it. Mapped as table -> xmlids. +DROPPED = { + "ir_model_fields": ("field_stock_picking__batch_consumer_group_id",), + "ir_ui_view": ("view_stock_picking_batch_picking_tree_consumer_group",), +} + + +def pre_init_hook(env): + """Adopt the database records of the former ``stock_picking_batch_custom``. + + A renamed addon is a brand new module for Odoo, so a versioned + ``migrations/`` script would never run. This hook does instead, on install, + after the Python is imported but before ``registry.load()`` and + ``init_models()``: remapping ``ir_model_data`` in that window makes Odoo + reuse the existing tables and columns instead of creating new ones, so + ``stock_move_line.is_collected``, the ``stock_picking_batch_summary_line`` + table and the ``res_company.batch_*`` settings all survive untouched. + + A no-op on a database where the old module was never installed. + """ + + cr = env.cr + cr.execute("SELECT id FROM ir_module_module WHERE name = %s", (OLD_MODULE,)) + old = cr.fetchone() + if not old: + return + old_id = old[0] + + cr.execute("SELECT id FROM ir_module_module WHERE name = %s", (NEW_MODULE,)) + new = cr.fetchone() + if not new: + # Should not happen: the module list is refreshed before installing. + _logger.warning("%s: no module row to adopt %s into", NEW_MODULE, OLD_MODULE) + return + new_id = new[0] + + _logger.info( + "Adopting %s (id=%s) as %s (id=%s)", OLD_MODULE, old_id, NEW_MODULE, new_id + ) + + # 1. Hand every xmlid over to the new module name. + cr.execute( + "UPDATE ir_model_data SET module = %s WHERE module = %s", + (NEW_MODULE, OLD_MODULE), + ) + _logger.info("Moved %s xmlids to %s", cr.rowcount, NEW_MODULE) + + # 2. Give back what is no longer ours, so aplicoop can claim it. + cr.execute( + "DELETE FROM ir_model_data WHERE module = %s AND name IN %s", + (NEW_MODULE, HANDED_OVER), + ) + + # 3. Drop for good what neither module defines any more, record included. + for table, xmlids in DROPPED.items(): + cr.execute( + "DELETE FROM %s WHERE id IN (" + " SELECT res_id FROM ir_model_data" + " WHERE module = %%s AND name IN %%s" + ")" % table, + (NEW_MODULE, xmlids), + ) + if cr.rowcount: + _logger.info("Dropped %s obsolete row(s) from %s", cr.rowcount, table) + cr.execute( + "DELETE FROM ir_model_data WHERE module = %s AND name IN %s", + (NEW_MODULE, tuple(name for names in DROPPED.values() for name in names)), + ) + + # 4. `ir_model_constraint.module` and `ir_model_relation.module` are integer + # FKs to `ir_module_module` with ON DELETE CASCADE: they must be + # repointed *before* the old row goes away, or the bookkeeping for our + # SQL constraints is silently destroyed with it. + cr.execute( + "UPDATE ir_model_constraint SET module = %s WHERE module = %s", + (new_id, old_id), + ) + cr.execute( + "UPDATE ir_model_relation SET module = %s WHERE module = %s", + (new_id, old_id), + ) + + # 5. Drop the dependency rows, both ours and any pointing at the old name. + cr.execute( + "DELETE FROM ir_module_module_dependency WHERE module_id = %s OR name = %s", + (old_id, OLD_MODULE), + ) + + # 6. Finally the module row itself. We delete the *old* one and keep the + # new one: the loader already holds the new row's id in memory, so + # renaming the old row in place would leave Odoo writing to a record + # that no longer exists. + cr.execute("DELETE FROM ir_module_module WHERE id = %s", (old_id,)) diff --git a/stock_picking_batch_collect/i18n/es.po b/stock_picking_batch_collect/i18n/es.po new file mode 100644 index 0000000..4bad2cb --- /dev/null +++ b/stock_picking_batch_collect/i18n/es.po @@ -0,0 +1,235 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_picking_batch_collect +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-05-21 13:18+0000\n" +"PO-Revision-Date: 2026-05-21 13:18+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields.selection,name:stock_picking_batch_collect.selection__res_company__batch_detailed_restriction_scope__all +msgid "All detailed lines" +msgstr "Todas las líneas detalladas" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields.selection,name:stock_picking_batch_collect.selection__res_company__batch_summary_restriction_scope__all +msgid "All summary products" +msgstr "Todos los productos del resumen" + +#. module: stock_picking_batch_collect +#: model:ir.model,name:stock_picking_batch_collect.model_stock_backorder_confirmation +msgid "Backorder Confirmation" +msgstr "Confirmación de entrega parcial" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__batch_id +msgid "Batch" +msgstr "Lote" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking__batch_consumer_group_id +msgid "Batch Consumer Group" +msgstr "Grupo de consumidores del lote" + +#. module: stock_picking_batch_collect +#: model_terms:ir.ui.view,arch_db:stock_picking_batch_collect.res_config_settings_view_form_inherit_batch_custom +msgid "Batch Detailed Operations Restriction" +msgstr "Restricción de operaciones detalladas del lote" + +#. module: stock_picking_batch_collect +#: model:ir.model,name:stock_picking_batch_collect.model_stock_picking_batch_summary_line +msgid "Batch Product Summary Line" +msgstr "Línea de resumen de productos del lote" + +#. module: stock_picking_batch_collect +#: model_terms:ir.ui.view,arch_db:stock_picking_batch_collect.res_config_settings_view_form_inherit_batch_custom +msgid "Batch Product Summary Restriction" +msgstr "Restricción del resumen de productos del lote" + +#. module: stock_picking_batch_collect +#: model:ir.model,name:stock_picking_batch_collect.model_stock_picking_batch +msgid "Batch Transfer" +msgstr "Traslado por lote" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_move_line__is_collected +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__is_collected +msgid "Collected" +msgstr "Recogido" + +#. module: stock_picking_batch_collect +#: model:ir.model,name:stock_picking_batch_collect.model_res_company +msgid "Companies" +msgstr "Compañías" + +#. module: stock_picking_batch_collect +#: model:ir.model,name:stock_picking_batch_collect.model_res_config_settings +msgid "Config Settings" +msgstr "Ajustes de configuración" + +#. module: stock_picking_batch_collect +#: model_terms:ir.ui.view,arch_db:stock_picking_batch_collect.res_config_settings_view_form_inherit_batch_custom +msgid "Configuración de restricciones para la pestaña Operaciones Detalladas." +msgstr "" +"Configuración de restricciones para la pestaña Operaciones Detalladas." + +#. module: stock_picking_batch_collect +#: model_terms:ir.ui.view,arch_db:stock_picking_batch_collect.res_config_settings_view_form_inherit_batch_custom +msgid "Configuración de restricciones para la pestaña Product Summary." +msgstr "Configuración de restricciones para la pestaña Resumen de productos." + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_move_line__consumer_group_id +msgid "Consumer Group" +msgstr "Grupo de consumidores" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__create_date +msgid "Created on" +msgstr "Creado el" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__qty_demanded +msgid "Demanded Quantity" +msgstr "Cantidad demandada" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_res_company__batch_detailed_restriction_scope +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_res_config_settings__batch_detailed_restriction_scope +msgid "Detailed Operations Restriction Scope" +msgstr "Ámbito de restricción de operaciones detalladas" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__display_name +msgid "Display Name" +msgstr "Nombre mostrado" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__qty_done +msgid "Done Quantity" +msgstr "Cantidad hecha" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_res_company__batch_detailed_restriction_enabled +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_res_config_settings__batch_detailed_restriction_enabled +msgid "Enforce Detailed Operations Restriction" +msgstr "Aplicar restricción de operaciones detalladas" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_res_company__batch_summary_restriction_enabled +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_res_config_settings__batch_summary_restriction_enabled +msgid "Enforce Product Summary Restriction" +msgstr "Aplicar restricción del resumen de productos" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_move_line__home_delivery +msgid "Home Delivery" +msgstr "Entrega a domicilio" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__id +msgid "ID" +msgstr "ID" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__write_uid +msgid "Last Updated by" +msgstr "Última actualización por" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__write_date +msgid "Last Updated on" +msgstr "Última actualización el" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields.selection,name:stock_picking_batch_collect.selection__res_company__batch_detailed_restriction_scope__processed +msgid "Only processed lines" +msgstr "Solo líneas procesadas" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields.selection,name:stock_picking_batch_collect.selection__res_company__batch_summary_restriction_scope__processed +msgid "Only processed products" +msgstr "Solo productos procesados" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__qty_pending +msgid "Pending Quantity" +msgstr "Cantidad pendiente" + +#. module: stock_picking_batch_collect +#. odoo-python +#: code:addons/stock_picking_batch_collect/models/stock_picking_batch.py:0 +msgid "Pending products: %(products)s" +msgstr "Productos pendientes: %(products)s" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__product_id +msgid "Product" +msgstr "Producto" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__product_categ_id +msgid "Product Category" +msgstr "Categoría de producto" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_move_line__product_categ_id +msgid "Product Category (Batch)" +msgstr "Categoría de producto (lote)" + +#. module: stock_picking_batch_collect +#: model:ir.model,name:stock_picking_batch_collect.model_stock_move_line +msgid "Product Moves (Stock Move Line)" +msgstr "Movimientos de producto (línea de movimiento de stock)" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch__summary_line_ids +#: model_terms:ir.ui.view,arch_db:stock_picking_batch_collect.view_stock_picking_batch_form_inherit_summary +msgid "Product Summary" +msgstr "Resumen de productos" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_res_company__batch_summary_restriction_scope +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_res_config_settings__batch_summary_restriction_scope +msgid "Product Summary Restriction Scope" +msgstr "Ámbito de restricción del resumen de productos" + +#. module: stock_picking_batch_collect +#: model:ir.model.constraint,message:stock_picking_batch_collect.constraint_stock_picking_batch_summary_line_product_required +msgid "Product is required for summary lines." +msgstr "El producto es obligatorio en las líneas de resumen." + +#. module: stock_picking_batch_collect +#: model:ir.model,name:stock_picking_batch_collect.model_stock_picking +msgid "Transfer" +msgstr "Traslado" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__product_uom_id +msgid "Unit of Measure" +msgstr "Unidad de medida" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,help:stock_picking_batch_collect.field_stock_move_line__home_delivery +msgid "Whether this picking includes home delivery (from sale order)" +msgstr "Si este albarán incluye entrega a domicilio (del pedido de venta)" + +#. module: stock_picking_batch_collect +#: model_terms:ir.ui.view,arch_db:stock_picking_batch_collect.view_stock_picking_batch_form_inherit_summary +msgid "Basket Assembly" +msgstr "Montaje de Cestas" diff --git a/stock_picking_batch_collect/i18n/eu.po b/stock_picking_batch_collect/i18n/eu.po new file mode 100644 index 0000000..62cd2c9 --- /dev/null +++ b/stock_picking_batch_collect/i18n/eu.po @@ -0,0 +1,235 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_picking_batch_collect +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-05-21 13:21+0000\n" +"PO-Revision-Date: 2026-05-21 13:21+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields.selection,name:stock_picking_batch_collect.selection__res_company__batch_detailed_restriction_scope__all +msgid "All detailed lines" +msgstr "Lerro xehatu guztiak" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields.selection,name:stock_picking_batch_collect.selection__res_company__batch_summary_restriction_scope__all +msgid "All summary products" +msgstr "Laburpeneko produktu guztiak" + +#. module: stock_picking_batch_collect +#: model:ir.model,name:stock_picking_batch_collect.model_stock_backorder_confirmation +msgid "Backorder Confirmation" +msgstr "Eskaeraren informazioa" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__batch_id +msgid "Batch" +msgstr "Lotea" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking__batch_consumer_group_id +msgid "Batch Consumer Group" +msgstr "Loteko kontsumitzaile taldea" + +#. module: stock_picking_batch_collect +#: model_terms:ir.ui.view,arch_db:stock_picking_batch_collect.res_config_settings_view_form_inherit_batch_custom +msgid "Batch Detailed Operations Restriction" +msgstr "Loteko eragiketa xehatuen murrizketa" + +#. module: stock_picking_batch_collect +#: model:ir.model,name:stock_picking_batch_collect.model_stock_picking_batch_summary_line +msgid "Batch Product Summary Line" +msgstr "Loteko produktuen laburpen-lerroa" + +#. module: stock_picking_batch_collect +#: model_terms:ir.ui.view,arch_db:stock_picking_batch_collect.res_config_settings_view_form_inherit_batch_custom +msgid "Batch Product Summary Restriction" +msgstr "Loteko produktuen laburpenaren murrizketa" + +#. module: stock_picking_batch_collect +#: model:ir.model,name:stock_picking_batch_collect.model_stock_picking_batch +msgid "Batch Transfer" +msgstr "Lote-transferentzia" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_move_line__is_collected +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__is_collected +msgid "Collected" +msgstr "Jasota" + +#. module: stock_picking_batch_collect +#: model:ir.model,name:stock_picking_batch_collect.model_res_company +msgid "Companies" +msgstr "Enpresak" + +#. module: stock_picking_batch_collect +#: model:ir.model,name:stock_picking_batch_collect.model_res_config_settings +msgid "Config Settings" +msgstr "Konfigurazio ezarpenak" + +#. module: stock_picking_batch_collect +#: model_terms:ir.ui.view,arch_db:stock_picking_batch_collect.res_config_settings_view_form_inherit_batch_custom +msgid "Configuración de restricciones para la pestaña Operaciones Detalladas." +msgstr "Eragiketa xehatuak fitxarako murrizketen konfigurazioa." + +#. module: stock_picking_batch_collect +#: model_terms:ir.ui.view,arch_db:stock_picking_batch_collect.res_config_settings_view_form_inherit_batch_custom +msgid "Configuración de restricciones para la pestaña Product Summary." +msgstr "Produktuen laburpena fitxarako murrizketen konfigurazioa." + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_move_line__consumer_group_id +msgid "Consumer Group" +msgstr "Kontsumitzaile taldea" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__create_uid +msgid "Created by" +msgstr "Nork sortua" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__create_date +msgid "Created on" +msgstr "Noiz sortua" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__qty_demanded +msgid "Demanded Quantity" +msgstr "Eskatutako kantitatea" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_res_company__batch_detailed_restriction_scope +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_res_config_settings__batch_detailed_restriction_scope +msgid "Detailed Operations Restriction Scope" +msgstr "Eragiketa xehatuen murrizketaren irismena" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__display_name +msgid "Display Name" +msgstr "Bistaratzeko izena" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__qty_done +msgid "Done Quantity" +msgstr "Egindako kantitatea" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_res_company__batch_detailed_restriction_enabled +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_res_config_settings__batch_detailed_restriction_enabled +msgid "Enforce Detailed Operations Restriction" +msgstr "Eragiketa xehatuen murrizketa aplikatu" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_res_company__batch_summary_restriction_enabled +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_res_config_settings__batch_summary_restriction_enabled +msgid "Enforce Product Summary Restriction" +msgstr "Produktuen laburpenaren murrizketa aplikatu" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_move_line__home_delivery +msgid "Home Delivery" +msgstr "Etxez etxeko entrega" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__id +msgid "ID" +msgstr "ID" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__write_uid +msgid "Last Updated by" +msgstr "Azken eguneratzailea" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__write_date +msgid "Last Updated on" +msgstr "Azken eguneratzea" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields.selection,name:stock_picking_batch_collect.selection__res_company__batch_detailed_restriction_scope__processed +msgid "Only processed lines" +msgstr "Prozesatutako lerroak soilik" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields.selection,name:stock_picking_batch_collect.selection__res_company__batch_summary_restriction_scope__processed +msgid "Only processed products" +msgstr "Prozesatutako produktuak soilik" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__qty_pending +msgid "Pending Quantity" +msgstr "Zain dagoen kantitatea" + +#. module: stock_picking_batch_collect +#. odoo-python +#: code:addons/stock_picking_batch_collect/models/stock_picking_batch.py:0 +msgid "Pending products: %(products)s" +msgstr "Zain dauden produktuak: %(products)s" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__product_id +msgid "Product" +msgstr "Produktua" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__product_categ_id +msgid "Product Category" +msgstr "Produktu-kategoria" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_move_line__product_categ_id +msgid "Product Category (Batch)" +msgstr "Produktu-kategoria (lotea)" + +#. module: stock_picking_batch_collect +#: model:ir.model,name:stock_picking_batch_collect.model_stock_move_line +msgid "Product Moves (Stock Move Line)" +msgstr "Produktuen mugimenduak (stock mugimenduaren lerroa)" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch__summary_line_ids +#: model_terms:ir.ui.view,arch_db:stock_picking_batch_collect.view_stock_picking_batch_form_inherit_summary +msgid "Product Summary" +msgstr "Produktuen laburpena" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_res_company__batch_summary_restriction_scope +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_res_config_settings__batch_summary_restriction_scope +msgid "Product Summary Restriction Scope" +msgstr "Produktuen laburpenaren murrizketaren irismena" + +#. module: stock_picking_batch_collect +#: model:ir.model.constraint,message:stock_picking_batch_collect.constraint_stock_picking_batch_summary_line_product_required +msgid "Product is required for summary lines." +msgstr "Produktua derrigorrezkoa da laburpen-lerroetan." + +#. module: stock_picking_batch_collect +#: model:ir.model,name:stock_picking_batch_collect.model_stock_picking +msgid "Transfer" +msgstr "Transferentzia" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,field_description:stock_picking_batch_collect.field_stock_picking_batch_summary_line__product_uom_id +msgid "Unit of Measure" +msgstr "Neurri-unitatea" + +#. module: stock_picking_batch_collect +#: model:ir.model.fields,help:stock_picking_batch_collect.field_stock_move_line__home_delivery +msgid "Whether this picking includes home delivery (from sale order)" +msgstr "" +"Albaran honek etxez etxeko entrega barne hartzen duen (salmenta-eskaeratik)" + +#. module: stock_picking_batch_collect +#: model_terms:ir.ui.view,arch_db:stock_picking_batch_collect.view_stock_picking_batch_form_inherit_summary +msgid "Basket Assembly" +msgstr "Saskien Prestaketa" diff --git a/stock_picking_batch_custom/models/__init__.py b/stock_picking_batch_collect/models/__init__.py similarity index 100% rename from stock_picking_batch_custom/models/__init__.py rename to stock_picking_batch_collect/models/__init__.py index 8be5195..5b85812 100644 --- a/stock_picking_batch_custom/models/__init__.py +++ b/stock_picking_batch_collect/models/__init__.py @@ -1,6 +1,6 @@ from . import res_company # noqa: F401 from . import res_config_settings # noqa: F401 -from . import stock_move_line # noqa: F401 from . import stock_backorder_confirmation # noqa: F401 +from . import stock_move_line # noqa: F401 from . import stock_picking # noqa: F401 from . import stock_picking_batch # noqa: F401 diff --git a/stock_picking_batch_custom/models/res_company.py b/stock_picking_batch_collect/models/res_company.py similarity index 100% rename from stock_picking_batch_custom/models/res_company.py rename to stock_picking_batch_collect/models/res_company.py diff --git a/stock_picking_batch_custom/models/res_config_settings.py b/stock_picking_batch_collect/models/res_config_settings.py similarity index 100% rename from stock_picking_batch_custom/models/res_config_settings.py rename to stock_picking_batch_collect/models/res_config_settings.py diff --git a/stock_picking_batch_custom/models/stock_backorder_confirmation.py b/stock_picking_batch_collect/models/stock_backorder_confirmation.py similarity index 100% rename from stock_picking_batch_custom/models/stock_backorder_confirmation.py rename to stock_picking_batch_collect/models/stock_backorder_confirmation.py diff --git a/stock_picking_batch_custom/models/stock_move_line.py b/stock_picking_batch_collect/models/stock_move_line.py similarity index 72% rename from stock_picking_batch_custom/models/stock_move_line.py rename to stock_picking_batch_collect/models/stock_move_line.py index 03f575e..c87320a 100644 --- a/stock_picking_batch_custom/models/stock_move_line.py +++ b/stock_picking_batch_collect/models/stock_move_line.py @@ -1,7 +1,6 @@ # 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 @@ -36,17 +35,6 @@ class StockMoveLine(models.Model): copy=False, ) - home_delivery = fields.Boolean( - related="picking_id.home_delivery", - readonly=True, - ) - - consumer_group_id = fields.Many2one( - comodel_name="res.partner", - compute="_compute_consumer_group_id", - readonly=True, - ) - def write(self, vals): res = super().write(vals) if vals.get("is_collected"): @@ -61,12 +49,3 @@ class StockMoveLine(models.Model): lines.picked = True lines._freeze_manual_quantity(align_demand=False) return res - - @api.depends("picking_id") - def _compute_consumer_group_id(self): - for line in self: - picking = line.picking_id - if picking: - line.consumer_group_id = picking.batch_consumer_group_id - else: - line.consumer_group_id = False diff --git a/stock_picking_batch_custom/models/stock_picking.py b/stock_picking_batch_collect/models/stock_picking.py similarity index 68% rename from stock_picking_batch_custom/models/stock_picking.py rename to stock_picking_batch_collect/models/stock_picking.py index 2e94ffa..1cb06ef 100644 --- a/stock_picking_batch_custom/models/stock_picking.py +++ b/stock_picking_batch_collect/models/stock_picking.py @@ -1,28 +1,12 @@ # Copyright 2026 Criptomart # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import fields from odoo import models class StockPicking(models.Model): _inherit = "stock.picking" - batch_consumer_group_id = fields.Many2one( - comodel_name="res.partner", - compute="_compute_batch_consumer_group_id", - readonly=True, - string="Batch Consumer Group", - ) - - def _compute_batch_consumer_group_id(self): - for picking in self: - sale = picking.sale_id if "sale_id" in picking._fields else False - if sale and "consumer_group_id" in sale._fields: - picking.batch_consumer_group_id = sale.consumer_group_id - else: - picking.batch_consumer_group_id = False - def _pre_action_done_hook(self): """Run collected checks only after Odoo resolves backorders. diff --git a/stock_picking_batch_custom/models/stock_picking_batch.py b/stock_picking_batch_collect/models/stock_picking_batch.py similarity index 99% rename from stock_picking_batch_custom/models/stock_picking_batch.py rename to stock_picking_batch_collect/models/stock_picking_batch.py index 6c7a409..553796a 100644 --- a/stock_picking_batch_custom/models/stock_picking_batch.py +++ b/stock_picking_batch_collect/models/stock_picking_batch.py @@ -231,7 +231,7 @@ class StockPickingBatch(models.Model): "views": [ ( self.env.ref( - "stock_picking_batch_custom.view_move_line_batch_operator" + "stock_picking_batch_collect.view_move_line_batch_operator" ).id, "list", ) diff --git a/stock_picking_batch_collect/readme/CONFIGURE.rst b/stock_picking_batch_collect/readme/CONFIGURE.rst new file mode 100644 index 0000000..bda97fc --- /dev/null +++ b/stock_picking_batch_collect/readme/CONFIGURE.rst @@ -0,0 +1,32 @@ +Configuración +============= + +Restricciones de validación +--------------------------- + +En **Inventory > Configuration > Settings**, bloque *Operations*, hay dos +ajustes por compañía: + +- **Restricciones del resumen de productos**: exige que las líneas de la + pestaña *Product Summary* estén marcadas como recogidas para validar el lote. + Desactivado por defecto (el check es sólo informativo). +- **Restricciones de operaciones detalladas**: exige que las líneas de la + pestaña *Detailed Operations* estén marcadas como recogidas. + **Activado por defecto**: recién instalado el módulo, un lote no se puede + validar hasta marcar las líneas. + +Cada restricción tiene un alcance: + +- *Sólo procesadas*: se comprueban únicamente las líneas con cantidad hecha + mayor que cero (por defecto). +- *Todas*: se comprueban todas las líneas del lote, procesadas o no. + +Columnas +-------- + +Las columnas están visibles por defecto. Para ajustarlas: + +- Abrir un **Lote de picking**. +- Ir a la pestaña **Detailed Operations**. +- Abrir el **selector de columnas** y activar o desactivar *Partner*, + *Product Category*, *Product Code* o *Collected* según necesidad. diff --git a/stock_picking_batch_custom/readme/CONTRIBUTORS.rst b/stock_picking_batch_collect/readme/CONTRIBUTORS.rst similarity index 100% rename from stock_picking_batch_custom/readme/CONTRIBUTORS.rst rename to stock_picking_batch_collect/readme/CONTRIBUTORS.rst diff --git a/stock_picking_batch_custom/readme/CREDITS.rst b/stock_picking_batch_collect/readme/CREDITS.rst similarity index 100% rename from stock_picking_batch_custom/readme/CREDITS.rst rename to stock_picking_batch_collect/readme/CREDITS.rst diff --git a/stock_picking_batch_collect/readme/DESCRIPTION.rst b/stock_picking_batch_collect/readme/DESCRIPTION.rst new file mode 100644 index 0000000..dc348e7 --- /dev/null +++ b/stock_picking_batch_collect/readme/DESCRIPTION.rst @@ -0,0 +1,26 @@ +Este módulo convierte un lote de picking en una hoja de trabajo para el operario +que monta las cestas: amplía las operaciones detalladas, añade un resumen por +producto y una vista a pantalla completa para el almacén. + +- ``picking_partner_id`` (Partner del albarán) para que el personal de almacén + identifique rápido el cliente/proveedor. +- ``product_categ_id`` (Categoría de producto) para ordenar y agrupar. Las + líneas del lote se ordenan por categoría, producto y partner. +- ``product_default_code`` (Referencia interna) como columna opcional. +- ``is_collected`` (Recogido) como check manual en cada línea para marcar si se + ha recolectado. +- Nueva pestaña **Product Summary** con totales por producto (demandado, hecho, + pendiente), categoría y el check de recogido consolidado. +- Botón **Basket Assembly**: una vista de lista a pantalla completa, con + cantidades grandes y controles táctiles, pensada para tablet en el almacén. +- Restricciones de validación configurables por compañía: el lote no se puede + validar hasta que las líneas estén marcadas como recogidas. + +Las columnas se añaden con ``optional="show"`` en la vista de líneas del lote +(salvo ``product_default_code``, oculta por defecto), de modo que el usuario +puede desactivarlas desde el selector de columnas sin recargar la vista. + +Si además está instalado ``website_sale_aplicoop``, ese módulo añade a estas +mismas vistas las columnas de grupo de consumo (**Consumer Group** y **Home +Delivery**). Este módulo no depende de él: funciona igual sin la parte de +eCommerce. diff --git a/stock_picking_batch_custom/readme/INSTALL.rst b/stock_picking_batch_collect/readme/INSTALL.rst similarity index 80% rename from stock_picking_batch_custom/readme/INSTALL.rst rename to stock_picking_batch_collect/readme/INSTALL.rst index b259091..05042a7 100644 --- a/stock_picking_batch_custom/readme/INSTALL.rst +++ b/stock_picking_batch_collect/readme/INSTALL.rst @@ -5,4 +5,4 @@ Actualizar o instalar el módulo: :: - docker-compose run --rm odoo odoo -d odoo --stop-after-init -u stock_picking_batch_custom + docker-compose run --rm odoo odoo -d odoo --stop-after-init -u stock_picking_batch_collect diff --git a/stock_picking_batch_custom/readme/USAGE.rst b/stock_picking_batch_collect/readme/USAGE.rst similarity index 51% rename from stock_picking_batch_custom/readme/USAGE.rst rename to stock_picking_batch_collect/readme/USAGE.rst index 5dcdde0..73eea25 100644 --- a/stock_picking_batch_custom/readme/USAGE.rst +++ b/stock_picking_batch_collect/readme/USAGE.rst @@ -2,7 +2,7 @@ Uso === 1. Accede a **Inventory > Operations > Batch Transfers** y abre un lote. -2. Pestaña **Detailed Operations**: usa el selector de columnas para activar: +2. Pestaña **Detailed Operations**: usa el selector de columnas para ajustar: - **Partner** (``picking_partner_id``) para ver el cliente/proveedor. - **Product Category** (``product_categ_id``) para ordenar/agrupación por categoría. @@ -11,9 +11,19 @@ Uso 3. Pestaña **Product Summary**: consulta los totales por producto (demandado, hecho y pendiente) y marca el check de recogido consolidado si corresponde. -4. Ordena o agrupa por categoría en cualquiera de las vistas según convenga. +4. Con el lote **en progreso**, el botón **Basket Assembly** abre la vista de + operario: la misma lista de líneas a pantalla completa, con la cantidad en + grande y el check *Collected* como interruptor táctil. Está pensada para + trabajar desde una tablet mientras se montan las cestas. -5. La cantidad que teclea el operario (el peso real de la balanza) queda fijada: +5. Ordena o agrupa por categoría en cualquiera de las vistas según convenga. + +6. La cantidad que teclea el operario (el peso real de la balanza) queda fijada: se marca como *Picked* y ni el planificador ni la validación de otros albaranes vuelven a modificarla. Marcar **Collected** protege igualmente la cantidad de la línea. Ver ``stock_move_manual_quantity``. + +7. Al validar el lote, según la configuración de la compañía, se comprueba que + las líneas estén recogidas y se avisa con la lista de productos pendientes. + La comprobación se ejecuta después de resolver el backorder, de modo que + sólo bloquea sobre las líneas que realmente se van a procesar. diff --git a/stock_picking_batch_custom/security/ir.model.access.csv b/stock_picking_batch_collect/security/ir.model.access.csv similarity index 100% rename from stock_picking_batch_custom/security/ir.model.access.csv rename to stock_picking_batch_collect/security/ir.model.access.csv diff --git a/stock_picking_batch_custom/static/description/icon.png b/stock_picking_batch_collect/static/description/icon.png similarity index 100% rename from stock_picking_batch_custom/static/description/icon.png rename to stock_picking_batch_collect/static/description/icon.png diff --git a/stock_picking_batch_custom/static/src/css/stock_picking_batch.css b/stock_picking_batch_collect/static/src/css/stock_picking_batch.css similarity index 82% rename from stock_picking_batch_custom/static/src/css/stock_picking_batch.css rename to stock_picking_batch_collect/static/src/css/stock_picking_batch.css index eada54e..549a93a 100644 --- a/stock_picking_batch_custom/static/src/css/stock_picking_batch.css +++ b/stock_picking_batch_collect/static/src/css/stock_picking_batch.css @@ -1,13 +1,3 @@ -/* zebra striping for list views in this module (Odoo 18 selectors) */ - -table.o_list_table tbody tr.o_data_row:nth-child(even) td { - background-color: rgba(0, 0, 0, 0.03); -} - -table.o_list_table tbody tr.o_data_row:hover td { - background-color: rgba(0, 0, 0, 0.045); -} - /* Widen the quantity column in detailed operations so it is easier to tap */ /* Note: arch class lands on the root
of the list controller, not */ .o_batch_move_line_list th[data-name="quantity"], diff --git a/stock_picking_batch_custom/tests/__init__.py b/stock_picking_batch_collect/tests/__init__.py similarity index 100% rename from stock_picking_batch_custom/tests/__init__.py rename to stock_picking_batch_collect/tests/__init__.py diff --git a/stock_picking_batch_custom/tests/test_batch_summary.py b/stock_picking_batch_collect/tests/test_batch_summary.py similarity index 100% rename from stock_picking_batch_custom/tests/test_batch_summary.py rename to stock_picking_batch_collect/tests/test_batch_summary.py diff --git a/stock_picking_batch_custom/tests/test_collected_picked.py b/stock_picking_batch_collect/tests/test_collected_picked.py similarity index 100% rename from stock_picking_batch_custom/tests/test_collected_picked.py rename to stock_picking_batch_collect/tests/test_collected_picked.py diff --git a/stock_picking_batch_custom/views/res_config_settings_views.xml b/stock_picking_batch_collect/views/res_config_settings_views.xml similarity index 100% rename from stock_picking_batch_custom/views/res_config_settings_views.xml rename to stock_picking_batch_collect/views/res_config_settings_views.xml diff --git a/stock_picking_batch_custom/views/stock_picking_batch_views.xml b/stock_picking_batch_collect/views/stock_picking_batch_views.xml similarity index 83% rename from stock_picking_batch_custom/views/stock_picking_batch_views.xml rename to stock_picking_batch_collect/views/stock_picking_batch_views.xml index 0300795..38c8d70 100644 --- a/stock_picking_batch_custom/views/stock_picking_batch_views.xml +++ b/stock_picking_batch_collect/views/stock_picking_batch_views.xml @@ -30,8 +30,6 @@ context="{'display_default_code': False}"/> - - @@ -54,23 +52,12 @@ - + - - stock.picking.batch.picking.tree.consumer.group - stock.picking - - - - - - - - stock.move.line.list.batch.custom stock.move.line @@ -89,8 +76,6 @@ - - @@ -115,5 +100,4 @@ - diff --git a/stock_picking_batch_custom/README.rst b/stock_picking_batch_custom/README.rst deleted file mode 100644 index 964a1a7..0000000 --- a/stock_picking_batch_custom/README.rst +++ /dev/null @@ -1,66 +0,0 @@ -============================ -Stock Picking Batch Custom -============================ - -Visión general -============== -Este módulo amplía las operaciones detalladas y añade un resumen por producto -en los lotes de picking: - -- ``picking_partner_id`` (Partner del albarán) para identificar cliente/proveedor. -- ``product_categ_id`` (Categoría de producto) para ordenar y agrupar. -- ``is_collected`` (Recogido) como check manual en cada línea para marcar si se ha - recolectado. -- Nueva pestaña **Product Summary** con totales por producto (demandado, hecho, - pendiente), categoría y el check de recogido consolidado. - -Instalación -=========== - -Actualizar o instalar el módulo: - -:: - - docker-compose run --rm odoo odoo -d odoo --stop-after-init -u stock_picking_batch_custom - -Configuración -============= - -No requiere configuración adicional. Para usar las columnas: - -- Abrir un **Lote de picking**. -- Ir a la pestaña **Detailed Operations**. -- Abrir el **selector de columnas** y activar *Partner*, *Product Category* y *Collected* según necesidad. - -Uso -=== - -1. Accede a **Inventory > Operations > Batch Transfers** y abre un lote. -2. Pestaña **Detailed Operations**: usa el selector de columnas para activar: - - - **Partner** (``picking_partner_id``) para ver el cliente/proveedor. - - **Product Category** (``product_categ_id``) para ordenar/agrupación por categoría. - - **Collected** (``is_collected``) para marcar manualmente líneas recolectadas. - -3. Pestaña **Product Summary**: consulta los totales por producto (demandado, - hecho y pendiente) y marca el check de recogido consolidado si corresponde. - -4. Ordena o agrupa por categoría en cualquiera de las vistas según convenga. - -Contribuidores -============== - -* Criptomart - -Créditos -======== - -Autor ------ - -* Criptomart - -Financiador ------------ - -* Elika Bilbo diff --git a/stock_picking_batch_custom/__init__.py b/stock_picking_batch_custom/__init__.py deleted file mode 100644 index ce9807d..0000000 --- a/stock_picking_batch_custom/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import models # noqa: F401 diff --git a/stock_picking_batch_custom/i18n/es.po b/stock_picking_batch_custom/i18n/es.po deleted file mode 100644 index e0a4108..0000000 --- a/stock_picking_batch_custom/i18n/es.po +++ /dev/null @@ -1,235 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * stock_picking_batch_custom -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 18.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-21 13:18+0000\n" -"PO-Revision-Date: 2026-05-21 13:18+0000\n" -"Last-Translator: \n" -"Language-Team: \n" -"Language: es\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields.selection,name:stock_picking_batch_custom.selection__res_company__batch_detailed_restriction_scope__all -msgid "All detailed lines" -msgstr "Todas las líneas detalladas" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields.selection,name:stock_picking_batch_custom.selection__res_company__batch_summary_restriction_scope__all -msgid "All summary products" -msgstr "Todos los productos del resumen" - -#. module: stock_picking_batch_custom -#: model:ir.model,name:stock_picking_batch_custom.model_stock_backorder_confirmation -msgid "Backorder Confirmation" -msgstr "Confirmación de entrega parcial" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__batch_id -msgid "Batch" -msgstr "Lote" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking__batch_consumer_group_id -msgid "Batch Consumer Group" -msgstr "Grupo de consumidores del lote" - -#. module: stock_picking_batch_custom -#: model_terms:ir.ui.view,arch_db:stock_picking_batch_custom.res_config_settings_view_form_inherit_batch_custom -msgid "Batch Detailed Operations Restriction" -msgstr "Restricción de operaciones detalladas del lote" - -#. module: stock_picking_batch_custom -#: model:ir.model,name:stock_picking_batch_custom.model_stock_picking_batch_summary_line -msgid "Batch Product Summary Line" -msgstr "Línea de resumen de productos del lote" - -#. module: stock_picking_batch_custom -#: model_terms:ir.ui.view,arch_db:stock_picking_batch_custom.res_config_settings_view_form_inherit_batch_custom -msgid "Batch Product Summary Restriction" -msgstr "Restricción del resumen de productos del lote" - -#. module: stock_picking_batch_custom -#: model:ir.model,name:stock_picking_batch_custom.model_stock_picking_batch -msgid "Batch Transfer" -msgstr "Traslado por lote" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_move_line__is_collected -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__is_collected -msgid "Collected" -msgstr "Recogido" - -#. module: stock_picking_batch_custom -#: model:ir.model,name:stock_picking_batch_custom.model_res_company -msgid "Companies" -msgstr "Compañías" - -#. module: stock_picking_batch_custom -#: model:ir.model,name:stock_picking_batch_custom.model_res_config_settings -msgid "Config Settings" -msgstr "Ajustes de configuración" - -#. module: stock_picking_batch_custom -#: model_terms:ir.ui.view,arch_db:stock_picking_batch_custom.res_config_settings_view_form_inherit_batch_custom -msgid "Configuración de restricciones para la pestaña Operaciones Detalladas." -msgstr "" -"Configuración de restricciones para la pestaña Operaciones Detalladas." - -#. module: stock_picking_batch_custom -#: model_terms:ir.ui.view,arch_db:stock_picking_batch_custom.res_config_settings_view_form_inherit_batch_custom -msgid "Configuración de restricciones para la pestaña Product Summary." -msgstr "Configuración de restricciones para la pestaña Resumen de productos." - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_move_line__consumer_group_id -msgid "Consumer Group" -msgstr "Grupo de consumidores" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__create_uid -msgid "Created by" -msgstr "Creado por" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__create_date -msgid "Created on" -msgstr "Creado el" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__qty_demanded -msgid "Demanded Quantity" -msgstr "Cantidad demandada" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_res_company__batch_detailed_restriction_scope -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_res_config_settings__batch_detailed_restriction_scope -msgid "Detailed Operations Restriction Scope" -msgstr "Ámbito de restricción de operaciones detalladas" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__display_name -msgid "Display Name" -msgstr "Nombre mostrado" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__qty_done -msgid "Done Quantity" -msgstr "Cantidad hecha" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_res_company__batch_detailed_restriction_enabled -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_res_config_settings__batch_detailed_restriction_enabled -msgid "Enforce Detailed Operations Restriction" -msgstr "Aplicar restricción de operaciones detalladas" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_res_company__batch_summary_restriction_enabled -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_res_config_settings__batch_summary_restriction_enabled -msgid "Enforce Product Summary Restriction" -msgstr "Aplicar restricción del resumen de productos" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_move_line__home_delivery -msgid "Home Delivery" -msgstr "Entrega a domicilio" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__id -msgid "ID" -msgstr "ID" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__write_uid -msgid "Last Updated by" -msgstr "Última actualización por" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__write_date -msgid "Last Updated on" -msgstr "Última actualización el" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields.selection,name:stock_picking_batch_custom.selection__res_company__batch_detailed_restriction_scope__processed -msgid "Only processed lines" -msgstr "Solo líneas procesadas" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields.selection,name:stock_picking_batch_custom.selection__res_company__batch_summary_restriction_scope__processed -msgid "Only processed products" -msgstr "Solo productos procesados" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__qty_pending -msgid "Pending Quantity" -msgstr "Cantidad pendiente" - -#. module: stock_picking_batch_custom -#. odoo-python -#: code:addons/stock_picking_batch_custom/models/stock_picking_batch.py:0 -msgid "Pending products: %(products)s" -msgstr "Productos pendientes: %(products)s" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__product_id -msgid "Product" -msgstr "Producto" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__product_categ_id -msgid "Product Category" -msgstr "Categoría de producto" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_move_line__product_categ_id -msgid "Product Category (Batch)" -msgstr "Categoría de producto (lote)" - -#. module: stock_picking_batch_custom -#: model:ir.model,name:stock_picking_batch_custom.model_stock_move_line -msgid "Product Moves (Stock Move Line)" -msgstr "Movimientos de producto (línea de movimiento de stock)" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch__summary_line_ids -#: model_terms:ir.ui.view,arch_db:stock_picking_batch_custom.view_stock_picking_batch_form_inherit_summary -msgid "Product Summary" -msgstr "Resumen de productos" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_res_company__batch_summary_restriction_scope -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_res_config_settings__batch_summary_restriction_scope -msgid "Product Summary Restriction Scope" -msgstr "Ámbito de restricción del resumen de productos" - -#. module: stock_picking_batch_custom -#: model:ir.model.constraint,message:stock_picking_batch_custom.constraint_stock_picking_batch_summary_line_product_required -msgid "Product is required for summary lines." -msgstr "El producto es obligatorio en las líneas de resumen." - -#. module: stock_picking_batch_custom -#: model:ir.model,name:stock_picking_batch_custom.model_stock_picking -msgid "Transfer" -msgstr "Traslado" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__product_uom_id -msgid "Unit of Measure" -msgstr "Unidad de medida" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,help:stock_picking_batch_custom.field_stock_move_line__home_delivery -msgid "Whether this picking includes home delivery (from sale order)" -msgstr "Si este albarán incluye entrega a domicilio (del pedido de venta)" - -#. module: stock_picking_batch_custom -#: model_terms:ir.ui.view,arch_db:stock_picking_batch_custom.view_stock_picking_batch_form_inherit_summary -msgid "Basket Assembly" -msgstr "Montaje de Cestas" diff --git a/stock_picking_batch_custom/i18n/eu.po b/stock_picking_batch_custom/i18n/eu.po deleted file mode 100644 index 82b3d93..0000000 --- a/stock_picking_batch_custom/i18n/eu.po +++ /dev/null @@ -1,235 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * stock_picking_batch_custom -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 18.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-05-21 13:21+0000\n" -"PO-Revision-Date: 2026-05-21 13:21+0000\n" -"Last-Translator: \n" -"Language-Team: \n" -"Language: eu\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields.selection,name:stock_picking_batch_custom.selection__res_company__batch_detailed_restriction_scope__all -msgid "All detailed lines" -msgstr "Lerro xehatu guztiak" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields.selection,name:stock_picking_batch_custom.selection__res_company__batch_summary_restriction_scope__all -msgid "All summary products" -msgstr "Laburpeneko produktu guztiak" - -#. module: stock_picking_batch_custom -#: model:ir.model,name:stock_picking_batch_custom.model_stock_backorder_confirmation -msgid "Backorder Confirmation" -msgstr "Eskaeraren informazioa" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__batch_id -msgid "Batch" -msgstr "Lotea" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking__batch_consumer_group_id -msgid "Batch Consumer Group" -msgstr "Loteko kontsumitzaile taldea" - -#. module: stock_picking_batch_custom -#: model_terms:ir.ui.view,arch_db:stock_picking_batch_custom.res_config_settings_view_form_inherit_batch_custom -msgid "Batch Detailed Operations Restriction" -msgstr "Loteko eragiketa xehatuen murrizketa" - -#. module: stock_picking_batch_custom -#: model:ir.model,name:stock_picking_batch_custom.model_stock_picking_batch_summary_line -msgid "Batch Product Summary Line" -msgstr "Loteko produktuen laburpen-lerroa" - -#. module: stock_picking_batch_custom -#: model_terms:ir.ui.view,arch_db:stock_picking_batch_custom.res_config_settings_view_form_inherit_batch_custom -msgid "Batch Product Summary Restriction" -msgstr "Loteko produktuen laburpenaren murrizketa" - -#. module: stock_picking_batch_custom -#: model:ir.model,name:stock_picking_batch_custom.model_stock_picking_batch -msgid "Batch Transfer" -msgstr "Lote-transferentzia" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_move_line__is_collected -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__is_collected -msgid "Collected" -msgstr "Jasota" - -#. module: stock_picking_batch_custom -#: model:ir.model,name:stock_picking_batch_custom.model_res_company -msgid "Companies" -msgstr "Enpresak" - -#. module: stock_picking_batch_custom -#: model:ir.model,name:stock_picking_batch_custom.model_res_config_settings -msgid "Config Settings" -msgstr "Konfigurazio ezarpenak" - -#. module: stock_picking_batch_custom -#: model_terms:ir.ui.view,arch_db:stock_picking_batch_custom.res_config_settings_view_form_inherit_batch_custom -msgid "Configuración de restricciones para la pestaña Operaciones Detalladas." -msgstr "Eragiketa xehatuak fitxarako murrizketen konfigurazioa." - -#. module: stock_picking_batch_custom -#: model_terms:ir.ui.view,arch_db:stock_picking_batch_custom.res_config_settings_view_form_inherit_batch_custom -msgid "Configuración de restricciones para la pestaña Product Summary." -msgstr "Produktuen laburpena fitxarako murrizketen konfigurazioa." - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_move_line__consumer_group_id -msgid "Consumer Group" -msgstr "Kontsumitzaile taldea" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__create_uid -msgid "Created by" -msgstr "Nork sortua" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__create_date -msgid "Created on" -msgstr "Noiz sortua" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__qty_demanded -msgid "Demanded Quantity" -msgstr "Eskatutako kantitatea" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_res_company__batch_detailed_restriction_scope -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_res_config_settings__batch_detailed_restriction_scope -msgid "Detailed Operations Restriction Scope" -msgstr "Eragiketa xehatuen murrizketaren irismena" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__display_name -msgid "Display Name" -msgstr "Bistaratzeko izena" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__qty_done -msgid "Done Quantity" -msgstr "Egindako kantitatea" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_res_company__batch_detailed_restriction_enabled -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_res_config_settings__batch_detailed_restriction_enabled -msgid "Enforce Detailed Operations Restriction" -msgstr "Eragiketa xehatuen murrizketa aplikatu" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_res_company__batch_summary_restriction_enabled -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_res_config_settings__batch_summary_restriction_enabled -msgid "Enforce Product Summary Restriction" -msgstr "Produktuen laburpenaren murrizketa aplikatu" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_move_line__home_delivery -msgid "Home Delivery" -msgstr "Etxez etxeko entrega" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__id -msgid "ID" -msgstr "ID" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__write_uid -msgid "Last Updated by" -msgstr "Azken eguneratzailea" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__write_date -msgid "Last Updated on" -msgstr "Azken eguneratzea" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields.selection,name:stock_picking_batch_custom.selection__res_company__batch_detailed_restriction_scope__processed -msgid "Only processed lines" -msgstr "Prozesatutako lerroak soilik" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields.selection,name:stock_picking_batch_custom.selection__res_company__batch_summary_restriction_scope__processed -msgid "Only processed products" -msgstr "Prozesatutako produktuak soilik" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__qty_pending -msgid "Pending Quantity" -msgstr "Zain dagoen kantitatea" - -#. module: stock_picking_batch_custom -#. odoo-python -#: code:addons/stock_picking_batch_custom/models/stock_picking_batch.py:0 -msgid "Pending products: %(products)s" -msgstr "Zain dauden produktuak: %(products)s" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__product_id -msgid "Product" -msgstr "Produktua" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__product_categ_id -msgid "Product Category" -msgstr "Produktu-kategoria" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_move_line__product_categ_id -msgid "Product Category (Batch)" -msgstr "Produktu-kategoria (lotea)" - -#. module: stock_picking_batch_custom -#: model:ir.model,name:stock_picking_batch_custom.model_stock_move_line -msgid "Product Moves (Stock Move Line)" -msgstr "Produktuen mugimenduak (stock mugimenduaren lerroa)" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch__summary_line_ids -#: model_terms:ir.ui.view,arch_db:stock_picking_batch_custom.view_stock_picking_batch_form_inherit_summary -msgid "Product Summary" -msgstr "Produktuen laburpena" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_res_company__batch_summary_restriction_scope -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_res_config_settings__batch_summary_restriction_scope -msgid "Product Summary Restriction Scope" -msgstr "Produktuen laburpenaren murrizketaren irismena" - -#. module: stock_picking_batch_custom -#: model:ir.model.constraint,message:stock_picking_batch_custom.constraint_stock_picking_batch_summary_line_product_required -msgid "Product is required for summary lines." -msgstr "Produktua derrigorrezkoa da laburpen-lerroetan." - -#. module: stock_picking_batch_custom -#: model:ir.model,name:stock_picking_batch_custom.model_stock_picking -msgid "Transfer" -msgstr "Transferentzia" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,field_description:stock_picking_batch_custom.field_stock_picking_batch_summary_line__product_uom_id -msgid "Unit of Measure" -msgstr "Neurri-unitatea" - -#. module: stock_picking_batch_custom -#: model:ir.model.fields,help:stock_picking_batch_custom.field_stock_move_line__home_delivery -msgid "Whether this picking includes home delivery (from sale order)" -msgstr "" -"Albaran honek etxez etxeko entrega barne hartzen duen (salmenta-eskaeratik)" - -#. module: stock_picking_batch_custom -#: model_terms:ir.ui.view,arch_db:stock_picking_batch_custom.view_stock_picking_batch_form_inherit_summary -msgid "Basket Assembly" -msgstr "Saskien Prestaketa" diff --git a/stock_picking_batch_custom/readme/CONFIGURE.rst b/stock_picking_batch_custom/readme/CONFIGURE.rst deleted file mode 100644 index 2213143..0000000 --- a/stock_picking_batch_custom/readme/CONFIGURE.rst +++ /dev/null @@ -1,8 +0,0 @@ -Configuración -============= - -No requiere configuración adicional. Para usar las columnas: - -- Abrir un **Lote de picking**. -- Ir a la pestaña **Detailed Operations**. -- Abrir el **selector de columnas** y activar *Partner* y *Product Category* según necesidad. diff --git a/stock_picking_batch_custom/readme/DESCRIPTION.rst b/stock_picking_batch_custom/readme/DESCRIPTION.rst deleted file mode 100644 index da6edad..0000000 --- a/stock_picking_batch_custom/readme/DESCRIPTION.rst +++ /dev/null @@ -1,14 +0,0 @@ -Este módulo amplía las operaciones detalladas y añade un resumen por producto -en los lotes de picking: - -- ``picking_partner_id`` (Partner del albarán) para que el personal de almacén - identifique rápido el cliente/proveedor. -- ``product_categ_id`` (Categoría de producto) para ordenar y agrupar. -- ``is_collected`` (Recogido) como check manual en cada línea para marcar si se - ha recolectado. -- Nueva pestaña **Product Summary** con totales por producto (demandado, hecho, - pendiente), categoría y el check de recogido consolidado. - -Las columnas se añaden como ``optional="hide"`` en la vista de líneas del lote, -de modo que el usuario puede activarlas desde el selector de columnas sin -recargar la vista por defecto. diff --git a/website_sale_aplicoop/README_DEV.md b/website_sale_aplicoop/README_DEV.md index 32c5c62..efbb2dc 100644 --- a/website_sale_aplicoop/README_DEV.md +++ b/website_sale_aplicoop/README_DEV.md @@ -135,22 +135,36 @@ La página inicial renderiza la primera página server-side. El botón "Cargar m | Cron | Frecuencia | Acción | | ---- | ---------- | ------ | -| `_cron_confirm_group_orders` | Diario (medianoche) | Confirma sale.orders pasado el cutoff; crea lotes de picking agrupados por consumer_group + pickup_date | +| `_cron_confirm_group_orders` | Diario (medianoche) | Confirma sale.orders pasado el cutoff; crea lotes de picking por pedido de grupo, uno por tipo de operación (`_create_picking_batches`) | | `_cron_update_dates` | Diario | Recalcula `delivery_date` y `pickup_date` en órdenes activas | ## Dependencias +Según `__manifest__.py`: + ```text website_sale_aplicoop ├── website_sale (Odoo core) + ├── website_sale_stock (Odoo core) + ├── payment (Odoo core) + ├── product (Odoo core) ├── sale (Odoo core) - ├── product_main_seller (OCA) - ├── product_sale_price_from_pricelist (custom) - │ └── product_pricelist_total_margin (custom) - │ └── product_price_category (OCA) - └── stock_picking_batch_custom (custom) + ├── stock (Odoo core) + ├── account (Odoo core) + ├── stock_picking_batch (Odoo core) + ├── stock_picking_batch_collect (custom) + │ ├── stock_move_manual_quantity (custom) + │ └── stock_picking_batch (Odoo core) + ├── product_get_price_helper (OCA) + └── l10n_es_partner (OCA) ``` +La dependencia sobre `stock_picking_batch_collect` es deliberada y va en este +sentido: ese addon es genérico de almacén y no sabe nada de grupos de consumo. +Es `website_sale_aplicoop` quien inyecta en sus vistas las columnas +**Consumer Group** y **Home Delivery** (ver `views/stock_picking_batch_views.xml` +y `models/stock_move_line_extension.py`). + ## Instalación y actualización ```bash diff --git a/website_sale_aplicoop/__manifest__.py b/website_sale_aplicoop/__manifest__.py index e908de8..51ab842 100644 --- a/website_sale_aplicoop/__manifest__.py +++ b/website_sale_aplicoop/__manifest__.py @@ -3,7 +3,7 @@ { # noqa: B018 "name": "Website Sale - Aplicoop", - "version": "18.0.1.16.0", + "version": "18.0.1.17.0", "category": "Website/Sale", "summary": "Modern replacement of legacy Aplicoop - Collaborative consumption group orders", "author": "Odoo Community Association (OCA), Criptomart", @@ -18,6 +18,9 @@ "sale", "stock", "stock_picking_batch", + # Owns the batch collect views into which we inject the consumer group + # columns (home_delivery, consumer_group_id). + "stock_picking_batch_collect", "account", "product_get_price_helper", "l10n_es_partner", @@ -43,6 +46,7 @@ "views/product_template_views.xml", "views/sale_order_views.xml", "views/stock_picking_views.xml", + "views/stock_picking_batch_views.xml", "views/portal_templates.xml", "views/load_from_history_templates.xml", ], diff --git a/website_sale_aplicoop/models/__init__.py b/website_sale_aplicoop/models/__init__.py index 23d4133..37fdb5c 100644 --- a/website_sale_aplicoop/models/__init__.py +++ b/website_sale_aplicoop/models/__init__.py @@ -1,11 +1,12 @@ from . import group_order # noqa: F401 from . import group_order_slot # noqa: F401 +from . import js_translations # noqa: F401 from . import payment_transaction # noqa: F401 from . import product_category_extension # noqa: F401 from . import product_extension # noqa: F401 from . import res_config_settings # noqa: F401 from . import res_partner_extension # noqa: F401 from . import sale_order_extension # noqa: F401 +from . import stock_move_line_extension # noqa: F401 from . import stock_picking_extension # noqa: F401 from . import website # noqa: F401 -from . import js_translations # noqa: F401 diff --git a/website_sale_aplicoop/models/stock_move_line_extension.py b/website_sale_aplicoop/models/stock_move_line_extension.py new file mode 100644 index 0000000..17ac67a --- /dev/null +++ b/website_sale_aplicoop/models/stock_move_line_extension.py @@ -0,0 +1,28 @@ +# Copyright 2026 Criptomart +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) + +from odoo import fields +from odoo import models + + +class StockMoveLine(models.Model): + """Surface the consumer group data on the batch operation lines. + + The picking already carries these values as stored related fields, so the + move line only has to hop one step further. Chaining off ``picking_id`` + instead of re-deriving from ``sale_id`` keeps a single source of truth. + """ + + _inherit = "stock.move.line" + + home_delivery = fields.Boolean( + related="picking_id.home_delivery", + string="Home Delivery", + readonly=True, + ) + + consumer_group_id = fields.Many2one( + related="picking_id.consumer_group_id", + string="Consumer Group", + readonly=True, + ) diff --git a/website_sale_aplicoop/tests/test_multi_company.py b/website_sale_aplicoop/tests/test_multi_company.py index a1f9d68..bffd074 100644 --- a/website_sale_aplicoop/tests/test_multi_company.py +++ b/website_sale_aplicoop/tests/test_multi_company.py @@ -14,39 +14,16 @@ class TestMultiCompanyGroupOrder(TransactionCase): def setUp(self): super().setUp() - # Crear dos compañías + # Crear dos compañías. `stock_picking_batch_collect` es dependencia del + # módulo, así que los campos de restricción de lote siempre existen. company_model = self.env["res.company"] - # Compatibilidad con esquemas legacy: columna NOT NULL presente sin campo ORM. - self.env.cr.execute(""" - SELECT column_name - FROM information_schema.columns - WHERE table_name = 'res_company' - AND column_name IN ('batch_summary_restriction_scope', 'batch_detailed_restriction_scope') - """) - existing_columns = {row[0] for row in self.env.cr.fetchall()} - if ( - "batch_summary_restriction_scope" in existing_columns - and "batch_summary_restriction_scope" not in company_model._fields - ): - self.env.cr.execute( - "ALTER TABLE res_company ALTER COLUMN batch_summary_restriction_scope SET DEFAULT 'processed'" - ) - if ( - "batch_detailed_restriction_scope" in existing_columns - and "batch_detailed_restriction_scope" not in company_model._fields - ): - self.env.cr.execute( - "ALTER TABLE res_company ALTER COLUMN batch_detailed_restriction_scope SET DEFAULT 'processed'" - ) - def _company_vals(name): - vals = {"name": name} - if "batch_summary_restriction_scope" in company_model._fields: - vals["batch_summary_restriction_scope"] = "processed" - if "batch_detailed_restriction_scope" in company_model._fields: - vals["batch_detailed_restriction_scope"] = "processed" - return vals + return { + "name": name, + "batch_summary_restriction_scope": "processed", + "batch_detailed_restriction_scope": "processed", + } self.company1 = company_model.create(_company_vals("Company 1")) self.company2 = company_model.create(_company_vals("Company 2")) diff --git a/website_sale_aplicoop/tests/test_record_rules.py b/website_sale_aplicoop/tests/test_record_rules.py index 99604ee..55bef5c 100644 --- a/website_sale_aplicoop/tests/test_record_rules.py +++ b/website_sale_aplicoop/tests/test_record_rules.py @@ -14,39 +14,16 @@ class TestGroupOrderRecordRules(TransactionCase): def setUp(self): super().setUp() - # Crear dos compañías + # Crear dos compañías. `stock_picking_batch_collect` es dependencia del + # módulo, así que los campos de restricción de lote siempre existen. company_model = self.env["res.company"] - # Compatibilidad con esquemas legacy: columna NOT NULL presente sin campo ORM. - self.env.cr.execute(""" - SELECT column_name - FROM information_schema.columns - WHERE table_name = 'res_company' - AND column_name IN ('batch_summary_restriction_scope', 'batch_detailed_restriction_scope') - """) - existing_columns = {row[0] for row in self.env.cr.fetchall()} - if ( - "batch_summary_restriction_scope" in existing_columns - and "batch_summary_restriction_scope" not in company_model._fields - ): - self.env.cr.execute( - "ALTER TABLE res_company ALTER COLUMN batch_summary_restriction_scope SET DEFAULT 'processed'" - ) - if ( - "batch_detailed_restriction_scope" in existing_columns - and "batch_detailed_restriction_scope" not in company_model._fields - ): - self.env.cr.execute( - "ALTER TABLE res_company ALTER COLUMN batch_detailed_restriction_scope SET DEFAULT 'processed'" - ) - def _company_vals(name): - vals = {"name": name} - if "batch_summary_restriction_scope" in company_model._fields: - vals["batch_summary_restriction_scope"] = "processed" - if "batch_detailed_restriction_scope" in company_model._fields: - vals["batch_detailed_restriction_scope"] = "processed" - return vals + return { + "name": name, + "batch_summary_restriction_scope": "processed", + "batch_detailed_restriction_scope": "processed", + } self.company1 = company_model.create(_company_vals("Company 1")) self.company2 = company_model.create(_company_vals("Company 2")) diff --git a/website_sale_aplicoop/views/stock_picking_batch_views.xml b/website_sale_aplicoop/views/stock_picking_batch_views.xml new file mode 100644 index 0000000..d5f2a7f --- /dev/null +++ b/website_sale_aplicoop/views/stock_picking_batch_views.xml @@ -0,0 +1,40 @@ + + + + + stock.move.line.batch.operator.consumer.group + stock.move.line + + + + + + + + + + + + stock.move.line.list.batch.consumer.group + stock.move.line + + + + + + + + + + + + stock.picking.batch.picking.tree.consumer.group + stock.picking + + + + + + + +