From 58583adf55a1cbbaae39dfe6eba31286596b214f Mon Sep 17 00:00:00 2001 From: FrankC013 Date: Thu, 25 Jan 2024 18:02:48 +0100 Subject: [PATCH] [IMP] mrp_production_batch: new improvements and implementations. --- mrp_production_batch/README.rst | 5 +- mrp_production_batch/__manifest__.py | 5 +- mrp_production_batch/i18n/es.po | 298 +++++++++++++++--- mrp_production_batch/models/__init__.py | 6 +- mrp_production_batch/models/mrp_bom_line.py | 18 ++ mrp_production_batch/models/mrp_production.py | 179 +++++++++-- .../models/mrp_production_batch.py | 132 +++++--- mrp_production_batch/models/res_company.py | 13 + .../models/res_config_settings.py | 14 + .../models/stock_picking_type.py | 6 +- .../models/stock_production_lot.py | 16 + mrp_production_batch/readme/CONTRIBUTORS.rst | 1 + mrp_production_batch/readme/DESCRIPTION.rst | 2 +- .../security/mrp_production_batch.xml | 12 + .../static/description/index.html | 5 +- mrp_production_batch/views/mrp_bom_line.xml | 22 ++ .../views/mrp_production_batch_views.xml | 56 ++-- .../views/mrp_production_views.xml | 10 +- .../views/res_config_settings_views.xml | 50 +++ .../views/stock_picking_views.xml | 2 +- .../wizard/mrp_production_batch_wizard.py | 5 +- .../wizard/mrp_production_batch_wizard.xml | 2 +- 22 files changed, 701 insertions(+), 158 deletions(-) create mode 100644 mrp_production_batch/models/mrp_bom_line.py create mode 100644 mrp_production_batch/models/res_company.py create mode 100644 mrp_production_batch/models/res_config_settings.py create mode 100644 mrp_production_batch/models/stock_production_lot.py create mode 100644 mrp_production_batch/security/mrp_production_batch.xml create mode 100644 mrp_production_batch/views/mrp_bom_line.xml create mode 100644 mrp_production_batch/views/res_config_settings_views.xml diff --git a/mrp_production_batch/README.rst b/mrp_production_batch/README.rst index ddece05fb..76776cf9c 100644 --- a/mrp_production_batch/README.rst +++ b/mrp_production_batch/README.rst @@ -7,7 +7,7 @@ MRP Production Batch !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:700bba545c72b4ff4d40b265cfbea8d46b2552a01a76ce668c2f6e033444f228 + !! source digest: sha256:61fb5987a03dd433cc41146fb2b0a02cde67896a7c73de4607fda46f2e1dbf4a !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png @@ -22,7 +22,7 @@ MRP Production Batch |badge1| |badge2| |badge3| -* Added +* This module manages production batches. **Table of contents** @@ -54,6 +54,7 @@ Contributors * Kilian Niubo * Frank Cespedes + * Eric Antones Maintainers ~~~~~~~~~~~ diff --git a/mrp_production_batch/__manifest__.py b/mrp_production_batch/__manifest__.py index 1bb155405..815dc941c 100644 --- a/mrp_production_batch/__manifest__.py +++ b/mrp_production_batch/__manifest__.py @@ -3,7 +3,7 @@ { "name": "MRP Production Batch", - "summary": "Customizations for Oxigen in MRP Production", + "summary": "This module manages production batches.", "version": "14.0.1.0.0", "author": "NuoBiT Solutions", "website": "https://github.com/nuobit/odoo-addons", @@ -12,9 +12,12 @@ "license": "AGPL-3", "data": [ "security/ir.model.access.csv", + "security/mrp_production_batch.xml", "views/mrp_production_batch_views.xml", "views/mrp_production_views.xml", "views/stock_picking_views.xml", + "views/res_config_settings_views.xml", + "views/mrp_bom_line.xml", "wizard/mrp_production_batch_wizard.xml", ], } diff --git a/mrp_production_batch/i18n/es.po b/mrp_production_batch/i18n/es.po index 37e050c38..79c28a83d 100644 --- a/mrp_production_batch/i18n/es.po +++ b/mrp_production_batch/i18n/es.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-12-22 14:37+0000\n" -"PO-Revision-Date: 2023-12-22 14:37+0000\n" +"POT-Creation-Date: 2024-01-26 12:52+0000\n" +"PO-Revision-Date: 2024-01-26 12:52+0000\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -16,9 +16,29 @@ msgstr "" "Plural-Forms: \n" #. module: mrp_production_batch -#: model_terms:ir.ui.view,arch_db:mrp_production_batch.stock_production_type_kanban2 +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.stock_production_type_view_kanban_inherit msgid "" +msgstr "" + +#. module: mrp_production_batch +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_batch_view_form +msgid "" +"Draft" +msgstr "" +"Borrador" + +#. module: mrp_production_batch +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.res_config_settings_view_form_inherit +msgid "" +"" msgstr "" +"" #. module: mrp_production_batch #: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_form_view @@ -26,17 +46,41 @@ msgid "Production Batch" msgstr "Lote de Producción" #. module: mrp_production_batch -#: model_terms:ir.ui.view,arch_db:mrp_production_batch.stock_production_type_kanban2 +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.stock_production_type_view_kanban_inherit msgid "New" msgstr "Nuevo" #. module: mrp_production_batch -#: model_terms:ir.ui.view,arch_db:mrp_production_batch.stock_production_type_kanban2 +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.stock_production_type_view_kanban_inherit msgid "Orders" msgstr "Pedidos" #. module: mrp_production_batch -#: model_terms:ir.ui.view,arch_db:mrp_production_batch.stock_production_type_kanban2 +#: code:addons/mrp_production_batch/models/mrp_production.py:0 +#, python-format +msgid "" +"A problem has been detected in production %s. Make sure you have added all " +"the necessary components from the materials list. Please check this and, " +"once corrected, try again." +msgstr "" +"Se ha detectado un problema en la producción %s. Asegúrate de haber añadido " +"todos los componentes necesarios de la lista de materiales. Por favor " +"verifica esto y, una vez corregido, intenta nuevamente." + +#. module: mrp_production_batch +#: code:addons/mrp_production_batch/models/mrp_production.py:0 +#, python-format +msgid "" +"A problem has been detected in production %s. Verify that the quantities to " +"be consumed are indicated correctly. Please check this and, once corrected, " +"try again." +msgstr "" +"Se ha detectado un problema en la producción %s. Verifica que las cantidades" +" a consumir estén indicadas correctamente. Por favor verifica esto y, una " +"vez corregido, intenta nuevamente." + +#. module: mrp_production_batch +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.stock_production_type_view_kanban_inherit msgid "All" msgstr "Todo" @@ -55,7 +99,22 @@ msgstr "" "producción." #. module: mrp_production_batch -#: model_terms:ir.ui.view,arch_db:mrp_production_batch.wizard_mrp_production_batch_view_form +#: model:ir.model,name:mrp_production_batch.model_mrp_bom_line +msgid "Bill of Material Line" +msgstr "Línea de Lista de Materiales" + +#. module: mrp_production_batch +#: code:addons/mrp_production_batch/models/mrp_production.py:0 +#, python-format +msgid "" +"Bill of Materials is required for the production. Please unbind the batch " +"production." +msgstr "" +"La Lista de Materiales es necesaria para la producción. Por favor, desvincule " +"la producción por lotes." + +#. module: mrp_production_batch +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_batch_wizard_view_form msgid "Cancel" msgstr "Cancelar" @@ -65,27 +124,47 @@ msgid "Check Production" msgstr "Validar Producción" #. module: mrp_production_batch -#: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_batch_form_view +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_batch_view_form msgid "Check Productions" msgstr "Validar Producciones" #. module: mrp_production_batch -#: model_terms:ir.ui.view,arch_db:mrp_production_batch.stock_production_type_kanban2 +#: model:ir.model,name:mrp_production_batch.model_res_company +msgid "Companies" +msgstr "Compañías" + +#. module: mrp_production_batch +#: model:ir.model,name:mrp_production_batch.model_res_config_settings +msgid "Config Settings" +msgstr "Opciones de configuración" + +#. module: mrp_production_batch +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.stock_production_type_view_kanban_inherit msgid "Configuration" msgstr "Configuración" #. module: mrp_production_batch -#: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_batch_form_view +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_batch_view_form msgid "Confirm Production" msgstr "Producción Confirmada" #. module: mrp_production_batch -#: model_terms:ir.ui.view,arch_db:mrp_production_batch.wizard_mrp_production_batch_view_form +#: model:ir.model.fields,field_description:mrp_production_batch.field_stock_picking_type__count_pb_todo +msgid "Count Pb Todo" +msgstr "Contar Lp Por Hacer" + +#. module: mrp_production_batch +#: model:ir.model.fields,field_description:mrp_production_batch.field_stock_picking_type__count_pb_waiting +msgid "Count Pb Waiting" +msgstr "Contar Lp en Espera" + +#. module: mrp_production_batch +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_batch_wizard_view_form msgid "Create Batch" msgstr "Crear Lote" #. module: mrp_production_batch -#: model_terms:ir.ui.view,arch_db:mrp_production_batch.wizard_mrp_production_batch_view_form +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_batch_wizard_view_form msgid "Create and View Batch" msgstr "Crear y Ver Lote" @@ -109,28 +188,42 @@ msgid "Creation Date" msgstr "Fecha de Creación" #. module: mrp_production_batch +#: code:addons/mrp_production_batch/models/mrp_production.py:0 +#: code:addons/mrp_production_batch/models/mrp_production_batch.py:0 +#, python-format +msgid "Detailed Operations" +msgstr "Operaciones Detalladas" + +#. module: mrp_production_batch +#: model:ir.model.fields,field_description:mrp_production_batch.field_mrp_bom_line__display_name #: model:ir.model.fields,field_description:mrp_production_batch.field_mrp_production__display_name #: model:ir.model.fields,field_description:mrp_production_batch.field_mrp_production_batch__display_name #: model:ir.model.fields,field_description:mrp_production_batch.field_mrp_production_batch_line_wizard__display_name #: model:ir.model.fields,field_description:mrp_production_batch.field_mrp_production_batch_wizard__display_name +#: model:ir.model.fields,field_description:mrp_production_batch.field_res_company__display_name +#: model:ir.model.fields,field_description:mrp_production_batch.field_res_config_settings__display_name #: model:ir.model.fields,field_description:mrp_production_batch.field_stock_picking_type__display_name +#: model:ir.model.fields,field_description:mrp_production_batch.field_stock_production_lot__display_name msgid "Display Name" msgstr "Nombre mostrado" #. module: mrp_production_batch #: model:ir.model.fields.selection,name:mrp_production_batch.selection__mrp_production_batch__state__done +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_batch_view_search msgid "Done" msgstr "Hecho" #. module: mrp_production_batch +#: code:addons/mrp_production_batch/models/mrp_production_batch.py:0 #: model:ir.model.fields.selection,name:mrp_production_batch.selection__mrp_production_batch__state__draft +#, python-format msgid "Draft" msgstr "Borrador" #. module: mrp_production_batch -#: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_batch_form_view -msgid "Generate Serial Numbers" -msgstr "Generar Números de Serie" +#: model:ir.model.fields,field_description:mrp_production_batch.field_mrp_production__error_message +msgid "Error Message" +msgstr "Mensaje de Error" #. module: mrp_production_batch #: model:ir.actions.act_window,name:mrp_production_batch.mrp_production_batch_wizard_action @@ -139,8 +232,8 @@ msgstr "Importar socios" #. module: mrp_production_batch #: model:ir.model.fields.selection,name:mrp_production_batch.selection__mrp_production_batch__state__in_progress -#: model_terms:ir.ui.view,arch_db:mrp_production_batch.stock_production_type_kanban2 -#: model_terms:ir.ui.view,arch_db:mrp_production_batch.view_mrp_production_batch_filter +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_batch_view_search +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.stock_production_type_view_kanban_inherit msgid "In Progress" msgstr "En Progreso" @@ -155,11 +248,15 @@ msgid "Is Ready To Produce" msgstr "Está listo para producir" #. module: mrp_production_batch +#: model:ir.model.fields,field_description:mrp_production_batch.field_mrp_bom_line____last_update #: model:ir.model.fields,field_description:mrp_production_batch.field_mrp_production____last_update #: model:ir.model.fields,field_description:mrp_production_batch.field_mrp_production_batch____last_update #: model:ir.model.fields,field_description:mrp_production_batch.field_mrp_production_batch_line_wizard____last_update #: model:ir.model.fields,field_description:mrp_production_batch.field_mrp_production_batch_wizard____last_update +#: model:ir.model.fields,field_description:mrp_production_batch.field_res_company____last_update +#: model:ir.model.fields,field_description:mrp_production_batch.field_res_config_settings____last_update #: model:ir.model.fields,field_description:mrp_production_batch.field_stock_picking_type____last_update +#: model:ir.model.fields,field_description:mrp_production_batch.field_stock_production_lot____last_update msgid "Last Modified on" msgstr "Última modificación el" @@ -177,6 +274,16 @@ msgstr "Última actualización por" msgid "Last Updated on" msgstr "Última actualización el" +#. module: mrp_production_batch +#: model:ir.model,name:mrp_production_batch.model_stock_production_lot +msgid "Lot/Serial" +msgstr "Lote/Número de serie" + +#. module: mrp_production_batch +#: model:ir.model,name:mrp_production_batch.model_mrp_production_batch +msgid "MRP Production Batch" +msgstr "MRP Lote de Producción" + #. module: mrp_production_batch #: model:ir.model,name:mrp_production_batch.model_mrp_production_batch_wizard msgid "MRP Production Batch wizard" @@ -193,6 +300,11 @@ msgstr "Asistente de Lote de Producción MRP" msgid "MRP production Batch" msgstr "Lote de Producción MRP" +#. module: mrp_production_batch +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.res_config_settings_view_form_inherit +msgid "Manage production batch" +msgstr "Gestionar lote de producción" + #. module: mrp_production_batch #: model:ir.model.fields.selection,name:mrp_production_batch.selection__stock_picking_type__code__mrp_operation_batch msgid "Manufacturing Batch" @@ -224,6 +336,16 @@ msgstr "Nombre" msgid "No Batch Production order found" msgstr "Lote de Producción de Pedido no encontrado" +#. module: mrp_production_batch +#: code:addons/mrp_production_batch/models/mrp_production.py:0 +#, python-format +msgid "" +"No compatible batch product found in the material list. Ensure a product " +"marked for batch use is included." +msgstr "" +"No se encontró un producto de lote compatible en la lista de materiales. " +"Asegúrese de que se incluya un producto marcado para uso en lotes." + #. module: mrp_production_batch #: code:addons/mrp_production_batch/models/mrp_production.py:0 #, python-format @@ -232,8 +354,8 @@ msgstr "Producciones no seleccionadas" #. module: mrp_production_batch #: model:ir.model.fields,field_description:mrp_production_batch.field_stock_picking_type__count_mo_todo_wo_batch -msgid "Number of Manufacturing Orders to Process" -msgstr "Número de Pedidos de Fabricación a Procesar" +msgid "Number of Manufacturing Orders to Process without Batch" +msgstr "Número de Pedidos de Fabricación a Procesar sin Lote" #. module: mrp_production_batch #: model:ir.model.fields,field_description:mrp_production_batch.field_mrp_production_batch__operation_type @@ -247,9 +369,10 @@ msgid "Picking Type" msgstr "Tipo de operación" #. module: mrp_production_batch -#: model:ir.model.fields,field_description:mrp_production_batch.field_mrp_production_batch__product_qty -msgid "Product Qty" -msgstr "Qty del Producto" +#: code:addons/mrp_production_batch/models/mrp_production.py:0 +#, python-format +msgid "Please assign a batch compatible product in the Bill of Materials" +msgstr "Por favor, asigne un producto compatible con lotes en la Lista de Materiales" #. module: mrp_production_batch #: model:ir.model.fields,field_description:mrp_production_batch.field_mrp_production_batch_line_wizard__production_id @@ -257,19 +380,18 @@ msgstr "Qty del Producto" msgid "Production" msgstr "Producción" -#. module: mrp_production_batch -#: code:addons/mrp_production_batch/models/mrp_production.py:0 -#: code:addons/mrp_production_batch/models/mrp_production.py:0 -#, python-format -msgid "Production %s have not recorded produced quantities yet." -msgstr "Producción %s no ha registrado cantidades producidas todavía." - #. module: mrp_production_batch #: model:ir.model.fields,field_description:mrp_production_batch.field_mrp_production__production_batch_id -#: model_terms:ir.ui.view,arch_db:mrp_production_batch.stock_production_type_kanban2 +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.stock_production_type_view_kanban_inherit msgid "Production Batch" msgstr "Lote de Producción" +#. module: mrp_production_batch +#: model:ir.model.fields,field_description:mrp_production_batch.field_res_company__sequence_production_batch_id +#: model:ir.model.fields,field_description:mrp_production_batch.field_res_config_settings__sequence_production_batch_id +msgid "Production Batch Sequence" +msgstr "Secuencia de Lote de Producción" + #. module: mrp_production_batch #: model:ir.model.fields,field_description:mrp_production_batch.field_mrp_production_batch_line_wizard__production_batch_wizard_id msgid "Production Batch Wizard" @@ -277,7 +399,7 @@ msgstr "Asistente de Lote de Producción" #. module: mrp_production_batch #: model:ir.ui.menu,name:mrp_production_batch.menu_mrp_production_batch -#: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_batch_form_view +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_batch_view_form msgid "Production Batches" msgstr "Lotes de Producción" @@ -287,9 +409,9 @@ msgid "Production Order" msgstr "Orden de producción" #. module: mrp_production_batch -#: model:ir.model.fields,field_description:mrp_production_batch.field_mrp_production_batch__production_wo_lot_producing_id -msgid "Production Wo Lot Producing" -msgstr "Produciento Lote de Producción" +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.res_config_settings_view_form_inherit +msgid "Production batch configuration" +msgstr "Configuración de lote de producción" #. module: mrp_production_batch #: model:ir.model.fields,field_description:mrp_production_batch.field_mrp_production_batch__product_ids @@ -298,7 +420,19 @@ msgid "Products" msgstr "Productos" #. module: mrp_production_batch -#: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_batch_form_view +#: code:addons/mrp_production_batch/models/mrp_production.py:0 +#, python-format +msgid "" +"Products are missing to be added to the production %s, which belong to the " +"bill of materials. Make sure to add all the necessary products to complete " +"the bill of materials." +msgstr "" +"Faltan productos para agregar a la producción %s, que pertenecen a la lista " +"de materiales. Asegúrese de agregar todos los productos necesarios para " +"completar la lista de materiales." + +#. module: mrp_production_batch +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_batch_view_form msgid "Ready" msgstr "Listo" @@ -313,10 +447,15 @@ msgid "Ready Production Count" msgstr "Contador de Producción Lista" #. module: mrp_production_batch -#: model_terms:ir.ui.view,arch_db:mrp_production_batch.view_mrp_production_batch_filter +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_batch_view_search msgid "Search Production Batch" msgstr "Buscar Lote de Producción" +#. module: mrp_production_batch +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.res_config_settings_view_form_inherit +msgid "Sequence" +msgstr "Secuencia" + #. module: mrp_production_batch #: code:addons/mrp_production_batch/models/mrp_production.py:0 #, python-format @@ -357,18 +496,39 @@ msgstr "Algunas de las producciones seleccionadas tienen diferentes almacenes" msgid "State" msgstr "Estado" +#. module: mrp_production_batch +#: code:addons/mrp_production_batch/models/mrp_production_batch.py:0 +#, python-format +msgid "The following productions could not be marked as 'done':" +msgstr "Las siguientes producciones no se pudieron marcar como 'hechas':" + #. module: mrp_production_batch #: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_form_view -msgid "The location is ready to produce in batch." -msgstr "La ubicación está lista para producir en lote." +msgid "The production is ready to produce in batch." +msgstr "La producción está lista para producir en lote." + +#. module: mrp_production_batch +#: code:addons/mrp_production_batch/models/mrp_production.py:0 +#, python-format +msgid "" +"The warehouse of the batch must be the same as the warehouse of the " +"productions." +msgstr "" +"El almacén del lote debe ser el mismo que el almacén de las producciones." #. module: mrp_production_batch -#: model_terms:ir.ui.view,arch_db:mrp_production_batch.view_mrp_production_batch_filter +#: code:addons/mrp_production_batch/models/stock_production_lot.py:0 +#, python-format +msgid "This name is reseved for internal use." +msgstr "Este nombre está reservado para uso interno." + +#. module: mrp_production_batch +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_batch_view_search msgid "To Do" -msgstr "A Hacer" +msgstr "Por Hacer" #. module: mrp_production_batch -#: model_terms:ir.ui.view,arch_db:mrp_production_batch.stock_production_type_kanban2 +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.stock_production_type_view_kanban_inherit msgid "To Process" msgstr "A Procesar" @@ -383,10 +543,15 @@ msgid "To Review Production Count" msgstr "Conteo de Producción a Revisar" #. module: mrp_production_batch -#: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_batch_form_view +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_batch_view_form msgid "To review" msgstr "A revisar" +#. module: mrp_production_batch +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.mrp_production_batch_view_form +msgid "Total" +msgstr "Total" + #. module: mrp_production_batch #: model:ir.model.fields,field_description:mrp_production_batch.field_mrp_production_batch__total_production_count msgid "Total Production Count" @@ -398,7 +563,12 @@ msgid "Type of Operation" msgstr "Tipo de operación" #. module: mrp_production_batch -#: model_terms:ir.ui.view,arch_db:mrp_production_batch.stock_production_type_kanban2 +#: model:ir.model.fields,field_description:mrp_production_batch.field_mrp_bom_line__use_in_batch +msgid "Use In Batch" +msgstr "Usar en Lote" + +#. module: mrp_production_batch +#: model_terms:ir.ui.view,arch_db:mrp_production_batch.stock_production_type_view_kanban_inherit msgid "Waiting" msgstr "Esperando" @@ -407,12 +577,6 @@ msgstr "Esperando" msgid "Warehouse" msgstr "Almacén" -#. module: mrp_production_batch -#: code:addons/mrp_production_batch/models/mrp_production_batch.py:0 -#, python-format -msgid "The following productions could not be marked as 'done':" -msgstr "Las siguientes producciones no se pudieron marcar como 'hechas':" - #. module: mrp_production_batch #: code:addons/mrp_production_batch/models/mrp_production.py:0 #, python-format @@ -432,3 +596,39 @@ msgid "" msgstr "" "No puedes cambiar el estado de una producción %s porque pertenece a un lote: %s. \n" "Debe procesarse desde el lote." + +#. module: mrp_production_batch +#: code:addons/mrp_production_batch/models/mrp_production.py:0 +#, python-format +msgid "" +"You can't set a lot producing for a production %s that belongs to a batch: %s.\n" +"It must be processed from the batch." +msgstr "" +"No puedes establecer un lote de producción para una producción %s que pertenece a un lote: %s. \n" +"Debe procesarse desde el lote." + +#. module: mrp_production_batch +#: code:addons/mrp_production_batch/models/mrp_production.py:0 +#, python-format +msgid "" +"You can't set a production batch for a production %s because it has a " +"lot/serial number." +msgstr "" +"No puedes establecer un lote de producción para una producción %s porque" +" tiene un número de lote / serie." + +#. module: mrp_production_batch +#: code:addons/mrp_production_batch/models/mrp_bom_line.py:0 +#, python-format +msgid "You can't set more than one component to be used in a batch." +msgstr "No puedes establecer más de un componente para ser usado en un lote." + +#. module: mrp_production_batch +#: code:addons/mrp_production_batch/models/mrp_production_batch.py:0 +#, python-format +msgid "" +"The following productions are using the same serial number in some of their " +"components: %s" +msgstr "" +"Las siguientes producciones están usando el mismo número de serie en " +"alguno de sus componentes: %s" diff --git a/mrp_production_batch/models/__init__.py b/mrp_production_batch/models/__init__.py index 42b39e3b4..8e732d3e5 100644 --- a/mrp_production_batch/models/__init__.py +++ b/mrp_production_batch/models/__init__.py @@ -1,5 +1,7 @@ from . import mrp_production from . import mrp_production_batch - -# from . import stock_move from . import stock_picking_type +from . import res_config_settings +from . import mrp_bom_line +from . import stock_production_lot +from . import res_company diff --git a/mrp_production_batch/models/mrp_bom_line.py b/mrp_production_batch/models/mrp_bom_line.py new file mode 100644 index 000000000..e82f13b3a --- /dev/null +++ b/mrp_production_batch/models/mrp_bom_line.py @@ -0,0 +1,18 @@ +# Copyright NuoBiT Solutions - Frank Cespedes +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + + +class MrpBomLine(models.Model): + _inherit = "mrp.bom.line" + + use_in_batch = fields.Boolean() + + @api.constrains("use_in_batch") + def _check_use_in_batch(self): + for rec in self: + if len(rec.bom_id.bom_line_ids.filtered(lambda x: x.use_in_batch)) > 1: + raise ValidationError( + _("You can't set more than one component to be used in a batch.") + ) diff --git a/mrp_production_batch/models/mrp_production.py b/mrp_production_batch/models/mrp_production.py index c3b12761f..b7d99c8e4 100644 --- a/mrp_production_batch/models/mrp_production.py +++ b/mrp_production_batch/models/mrp_production.py @@ -1,8 +1,9 @@ # Copyright NuoBiT Solutions - Kilian Niubo # Copyright NuoBiT Solutions - Frank Cespedes # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + from odoo import _, api, fields, models -from odoo.exceptions import ValidationError +from odoo.exceptions import UserError, ValidationError class FakeException(ValidationError): @@ -12,15 +13,42 @@ class FakeException(ValidationError): class MrpProduction(models.Model): _inherit = "mrp.production" - is_ready_to_produce = fields.Boolean() - error_message = fields.Char() + is_ready_to_produce = fields.Boolean(copy=False) + error_message = fields.Char(copy=False) production_batch_id = fields.Many2one( comodel_name="mrp.production.batch", string="Production Batch", + copy=False, ondelete="restrict", domain="[('state', '!=', 'done')]", ) + @api.constrains("lot_producing_id") + def _check_lot_producing_by_batch(self): + for rec in self: + if not self.env.context.get("mrp_production_batch_create"): + if rec.lot_producing_id and rec.production_batch_id: + raise ValidationError( + _( + "You can't set a lot producing for a production %s " + "that belongs to a batch: %s.\n" + "It must be processed from the batch." + ) + % (rec.name, rec.production_batch_id.name) + ) + + @api.constrains("production_batch_id") + def _check_production_batch(self): + for rec in self: + if rec.lot_producing_id: + raise ValidationError( + _( + "You can't set a production batch for a production %s " + "because it has a lot/serial number." + ) + % rec.name + ) + @api.constrains("state") def _check_state_batch_creation(self): for rec in self: @@ -34,7 +62,10 @@ def _check_state_batch_creation(self): % rec.production_batch_id.name ) elif rec.state == "done": - if not self.env.context.get("mrp_production_batch_create", False): + if ( + not self.env.context.get("mrp_production_batch_create", False) + and not rec.scrap_ids + ): raise ValidationError( _( "You can't change the state of a production %s " @@ -44,6 +75,20 @@ def _check_state_batch_creation(self): % (rec.name, rec.production_batch_id.name) ) + @api.constrains("production_batch_id") + def _check_operation_type(self): + for rec in self: + if ( + rec.picking_type_id.warehouse_id + != rec.production_batch_id.operation_type.warehouse_id + ): + raise ValidationError( + _( + "The warehouse of the batch must be the same" + " as the warehouse of the productions." + ) + ) + def _check_production_to_batch_consistency(self, mrp_productions): if not mrp_productions: raise ValidationError(_("No productions selected")) @@ -63,29 +108,37 @@ def _check_production_to_batch_consistency(self, mrp_productions): raise ValidationError( _("Some of the selected productions have different warehouses") ) - picking_type_ids = mrp_productions.picking_type_id - if len(picking_type_ids) > 1: + if len(mrp_productions.picking_type_id) > 1: raise ValidationError( _( "Some of the selected productions have different picking types:%s" - % picking_type_ids.mapped("name") + % mrp_productions.picking_type_id.mapped("name") ) ) def mrp_production_batch_create_wizard_action(self): - model = self.env.context.get("active_model") - mrp_production_ids = self.env[model].browse(self.env.context.get("active_ids")) + if ( + "active_model" not in self.env.context + or "active_ids" not in self.env.context + ): + raise ValidationError( + _( + "An unexpected error has occurred. There's no `active_model` or " + "`active_ids` in the context. This is a technical error, please " + "contact technical support." + ) + ) + model, active_ids = [ + self.env.context.get(x) for x in ["active_model", "active_ids"] + ] + mrp_production_ids = self.env[model].browse(active_ids) self._check_production_to_batch_consistency(mrp_production_ids) - ctx = dict(self.env.context, active_ids=self.ids) - view_form = self.env.ref( - "mrp_production_batch.wizard_mrp_production_batch_view_form" + "mrp_production_batch.mrp_production_batch_wizard_view_form" ) res_id = self.env["mrp.production.batch.wizard"].create( { - "warehouse_id": mrp_production_ids.mapped("picking_type_id") - .mapped("warehouse_id") - .id, + "warehouse_id": mrp_production_ids.picking_type_id.warehouse_id.id, } ) res = { @@ -97,36 +150,46 @@ def mrp_production_batch_create_wizard_action(self): "views": [(view_form.id, "form")], "view_id": view_form.id, "type": "ir.actions.act_window", - "context": ctx, + "context": dict(self.env.context, active_ids=self.ids), } return res def _action_generate_consumption_wizard(self, consumption_issues): if not self.env.context.get("mrp_production_batch_create"): return super()._action_generate_consumption_wizard(consumption_issues) + if self.bom_id.bom_line_ids.product_id.ids != self.move_raw_ids.product_id.ids: + raise ValidationError( + _( + "A problem has been detected in production %s. Make sure you " + "have added all the necessary components from the materials " + "list. Please check this and, once corrected, try again." + ) + % self.mapped("name") + ) else: raise ValidationError( _( - "Production %s have not recorded produced quantities yet." - % self.mapped("name") + "A problem has been detected in production %s. Verify that the" + " quantities to be consumed are indicated correctly. Please " + "check this and, once corrected, try again." ) + % self.mapped("name") ) def _action_generate_immediate_wizard(self): if not self.env.context.get("mrp_production_batch_create"): return super()._action_generate_immediate_wizard() - else: - raise ValidationError( - _( - "Production %s have not recorded produced quantities yet." - % self.mapped("name") - ) + raise ValidationError( + _( + "Production %s have not recorded produced quantities yet." + % self.mapped("name") ) + ) # TODO: xml action def action_view_production_batch(self): self.ensure_one() - view = self.env.ref("mrp_production_batch.mrp_production_batch_form_view") + view = self.env.ref("mrp_production_batch.mrp_production_batch_view_form") return { "name": _("Detailed Operations"), "type": "ir.actions.act_window", @@ -137,15 +200,77 @@ def action_view_production_batch(self): "res_id": self.production_batch_id.id, } + # TODO: Refactor translation management and raise of "You need to supply..." def action_check_with_batch(self): self.ensure_one() try: with self.env.cr.savepoint(): - self.with_context(mrp_production_batch_create=True).button_mark_done() + self_wc = self.with_context(mrp_production_batch_create=True) + lot = self_wc.env["stock.production.lot"].create( + { + "name": "", + "product_id": self.product_id.id, + "company_id": self.company_id.id, + } + ) + self_wc.lot_producing_id = lot.id + self_wc.button_mark_done() raise FakeException("") except FakeException: self.is_ready_to_produce = True self.error_message = False - except Exception as e: + except (UserError, ValidationError) as e: self.is_ready_to_produce = False self.error_message = e.name + + def create_batch_lot_by_bom(self): + self.ensure_one() + if not self.bom_id: + raise ValidationError( + _( + "Bill of Materials is required for the production. " + "Please unbind the batch production." + ) + ) + + batch_component = self.bom_id.bom_line_ids.filtered( + lambda x: x.use_in_batch + ).product_id + if not batch_component: + raise ValidationError( + _("Please assign a batch compatible product in the Bill of Materials") + ) + component_lot = False + for line in self.move_raw_ids.move_line_ids: + if line.product_id == batch_component: + component_lot = line.lot_id + if not component_lot: + raise ValidationError( + _( + "No compatible batch product found in the material list." + " Ensure a product marked for batch use is included." + ) + ) + batch_sequence = ( + self.env["res.company"] + .browse(self.company_id.id) + .sequence_production_batch_id.next_by_id() + ) + return component_lot.name + batch_sequence + + def action_generate_batch_serial(self): + self.ensure_one() + seq_name = self.create_batch_lot_by_bom() + self.lot_producing_id = self.env["stock.production.lot"].create( + { + "name": seq_name, + "product_id": self.product_id.id, + "company_id": self.company_id.id, + } + ) + + def write(self, values): + if "production_batch_id" in values and not values["production_batch_id"]: + values["is_ready_to_produce"] = False + values["error_message"] = False + return super().write(values) diff --git a/mrp_production_batch/models/mrp_production_batch.py b/mrp_production_batch/models/mrp_production_batch.py index 069db555b..0f0f1e36b 100644 --- a/mrp_production_batch/models/mrp_production_batch.py +++ b/mrp_production_batch/models/mrp_production_batch.py @@ -4,35 +4,37 @@ import logging from odoo import _, api, fields, models -from odoo.exceptions import UserError +from odoo.exceptions import UserError, ValidationError _logger = logging.getLogger(__name__) class MrpProductionBatch(models.Model): _name = "mrp.production.batch" + _description = "MRP Production Batch" - name = fields.Char( - readonly=True, + name = fields.Char(compute="_compute_name", store=True) + + @api.depends("state") + def _compute_name(self): + for rec in self: + if rec.name == "/" and rec.state != "draft": + rec.name = rec.operation_type.sequence_id._next() + if not rec.name: + rec.name = "/" + + company_id = fields.Many2one( + comodel_name="res.company", + default=lambda self: self.env.company, + index=True, required=True, ) + production_ids = fields.One2many( comodel_name="mrp.production", inverse_name="production_batch_id", string="Manufacturing Orders", ) - production_wo_lot_producing_id = fields.One2many( - comodel_name="mrp.production", - inverse_name="production_batch_id", - compute="_compute_production_wo_lot_producing_id", - ) - - @api.depends("production_ids.lot_producing_id") - def _compute_production_wo_lot_producing_id(self): - for rec in self: - rec.production_wo_lot_producing_id = rec.production_ids.filtered( - lambda x: not x.lot_producing_id - ) total_production_count = fields.Integer( compute="_compute_total_production_count", @@ -67,18 +69,15 @@ def _compute_production_wo_batch_count(self): ("in_progress", "In Progress"), ("done", "Done"), ], - default="draft", compute="_compute_state", store=True, ) - @api.depends("production_ids.state", "production_wo_lot_producing_id") + @api.depends("production_ids.is_ready_to_produce", "production_ids.state") def _compute_state(self): for rec in self: - if not rec.production_wo_lot_producing_id: - if rec.production_ids.filtered( - lambda r: r.state not in ["done", "cancel"] - ): + if rec.ready_production_count > 0: + if rec.production_ids.filtered(lambda r: r.state != "done"): rec.state = "in_progress" else: rec.state = "done" @@ -88,16 +87,7 @@ def _compute_state(self): operation_type = fields.Many2one( comodel_name="stock.picking.type", required=True, - readonly=True, ) - product_qty = fields.Float( - compute="_compute_product_qty", - ) - - @api.depends("production_ids") - def _compute_product_qty(self): - for rec in self: - rec.product_qty = sum(rec.production_ids.mapped("product_qty")) product_ids = fields.Many2many( comodel_name="product.product", @@ -131,11 +121,6 @@ def _compute_production_to_review_ids(self): lambda x: not x.is_ready_to_produce ) - def action_generate_serial(self): - for rec in self: - for production in rec.production_wo_lot_producing_id: - production.action_generate_serial() - def action_check(self): self.ensure_one() productions = self.production_ids.filtered(lambda r: not r.is_ready_to_produce) @@ -145,22 +130,54 @@ def action_check(self): final_production_count = len( self.production_ids.filtered(lambda r: not r.is_ready_to_produce) ) - if init_production_count == final_production_count: + if final_production_count and init_production_count == final_production_count: message = [ _("The following productions could not be marked as 'done':"), "\n".join(productions.mapped("display_name")), ] raise UserError("\n".join(message)) + def _check_unique_serial_lot_in_batch(self): + for rec in self: + serial_lots = [] + for production in rec.production_ids: + serial_move_line = production.move_raw_ids.filtered( + lambda x: x.product_id.tracking == "serial" + ).move_line_ids + serial_lot_ids = serial_move_line.mapped("lot_id").ids + serial_lots.extend(serial_lot_ids) + for lot in serial_lots: + if serial_lots.count(lot) > 1: + move = ( + self.env["stock.move.line"] + .search([("lot_id", "=", lot)]) + .filtered( + lambda x: x.move_id.raw_material_production_id + in rec.production_ids + ) + .move_id + ) + raise ValidationError( + _( + "The following productions are using the same serial number in" + " some of their components: %s" + % move.mapped("raw_material_production_id.display_name") + ) + ) + def action_done(self): self.ensure_one() self.action_check() - for production in self.production_ids: - production.with_context(mrp_production_batch_create=True).button_mark_done() + self._check_unique_serial_lot_in_batch() + for production in self.with_context( + mrp_production_batch_create=True + ).production_ids: + production.action_generate_batch_serial() + production.button_mark_done() def _get_common_action_view_production(self): - tree_view = self.env.ref("mrp.mrp_production_tree_view") - form_view = self.env.ref("mrp.mrp_production_form_view") + tree_view = self.env.ref("mrp_production_batch.mrp_production_tree_view") + form_view = self.env.ref("mrp_production_batch.mrp_production_form_view") return { "name": _("Detailed Operations"), "type": "ir.actions.act_window", @@ -187,3 +204,38 @@ def action_view_production_ready(self): action = self._get_common_action_view_production() action["domain"] = [("id", "in", self.ready_production_ids.ids)] return action + + def get_user_timezone_datetime(self): + self.ensure_one() + lang = self.env["res.lang"].search([("code", "=", self.env.user.lang)]) + datetime_format = " ".join( + filter( + None, + map( + lambda x: x and x.strip() or None, + [lang.time_format, lang.date_format], + ), + ) + ) + timezone = self._context.get("tz") or self.env.user.partner_id.tz or "UTC" + self_tz = self.with_context(tz=timezone) + return fields.Datetime.context_timestamp( + self_tz, fields.Datetime.from_string(self.create_date) + ).strftime(datetime_format) + + @api.depends("name", "state") + def name_get(self): + result = [] + for rec in self: + if rec.state == "draft": + state = _("Draft") + user_datetime = rec.get_user_timezone_datetime() + name = "%s [%s] %s" % ( + state, + user_datetime, + rec.operation_type.display_name, + ) + else: + name = rec.name + result.append((rec.id, name)) + return result diff --git a/mrp_production_batch/models/res_company.py b/mrp_production_batch/models/res_company.py new file mode 100644 index 000000000..aafcb4ad9 --- /dev/null +++ b/mrp_production_batch/models/res_company.py @@ -0,0 +1,13 @@ +# Copyright NuoBiT Solutions - Frank Cespedes +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo import fields, models + + +class Company(models.Model): + _inherit = "res.company" + + sequence_production_batch_id = fields.Many2one( + comodel_name="ir.sequence", + string="Production Batch Sequence", + ) diff --git a/mrp_production_batch/models/res_config_settings.py b/mrp_production_batch/models/res_config_settings.py new file mode 100644 index 000000000..1c5bdd848 --- /dev/null +++ b/mrp_production_batch/models/res_config_settings.py @@ -0,0 +1,14 @@ +# Copyright NuoBiT Solutions - Frank Cespedes +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + sequence_production_batch_id = fields.Many2one( + comodel_name="ir.sequence", + string="Production Batch Sequence", + related="company_id.sequence_production_batch_id", + readonly=False, + ) diff --git a/mrp_production_batch/models/stock_picking_type.py b/mrp_production_batch/models/stock_picking_type.py index e7b289a2d..0cc1ef99d 100644 --- a/mrp_production_batch/models/stock_picking_type.py +++ b/mrp_production_batch/models/stock_picking_type.py @@ -14,7 +14,7 @@ class StockPickingType(models.Model): ) count_mo_todo_wo_batch = fields.Integer( - string="Number of Manufacturing Orders to Process", + string="Number of Manufacturing Orders to Process without Batch", compute="_compute_mo_count", ) @@ -93,9 +93,9 @@ def _compute_mo_batch_count(self): rec.mo_batch_count = len(rec.mo_batches) or False def get_mrp_production_batch_stock_picking_action_picking_type(self): + self.ensure_one() action = self.env["ir.actions.actions"]._for_xml_id( "mrp_production_batch.mrp_production_batch_action_picking_dashboard" ) - if self: - action["display_name"] = self.display_name + action["display_name"] = self.display_name return action diff --git a/mrp_production_batch/models/stock_production_lot.py b/mrp_production_batch/models/stock_production_lot.py new file mode 100644 index 000000000..e0b7d2958 --- /dev/null +++ b/mrp_production_batch/models/stock_production_lot.py @@ -0,0 +1,16 @@ +# Copyright NuoBiT Solutions - Frank Cespedes +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) +from odoo import _, api, models +from odoo.exceptions import ValidationError + + +class ProductionLot(models.Model): + _inherit = "stock.production.lot" + + @api.constrains("name") + def _check_name(self): + for rec in self: + if rec.name == "" and not self.env.context.get( + "mrp_production_batch_create" + ): + raise ValidationError(_("This name is reseved for internal use.")) diff --git a/mrp_production_batch/readme/CONTRIBUTORS.rst b/mrp_production_batch/readme/CONTRIBUTORS.rst index 5c0d390af..16d23efee 100644 --- a/mrp_production_batch/readme/CONTRIBUTORS.rst +++ b/mrp_production_batch/readme/CONTRIBUTORS.rst @@ -2,3 +2,4 @@ * Kilian Niubo * Frank Cespedes + * Eric Antones diff --git a/mrp_production_batch/readme/DESCRIPTION.rst b/mrp_production_batch/readme/DESCRIPTION.rst index f0f0f3969..95446c54d 100644 --- a/mrp_production_batch/readme/DESCRIPTION.rst +++ b/mrp_production_batch/readme/DESCRIPTION.rst @@ -1 +1 @@ -* Added +* This module manages production batches. diff --git a/mrp_production_batch/security/mrp_production_batch.xml b/mrp_production_batch/security/mrp_production_batch.xml new file mode 100644 index 000000000..88a955b9d --- /dev/null +++ b/mrp_production_batch/security/mrp_production_batch.xml @@ -0,0 +1,12 @@ + + + + + MRP Production Batch + + ['|', ('company_id', '=', False), ('company_id', 'in', company_ids)] + + diff --git a/mrp_production_batch/static/description/index.html b/mrp_production_batch/static/description/index.html index fa13813ba..e4784b361 100644 --- a/mrp_production_batch/static/description/index.html +++ b/mrp_production_batch/static/description/index.html @@ -367,11 +367,11 @@

MRP Production Batch

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:700bba545c72b4ff4d40b265cfbea8d46b2552a01a76ce668c2f6e033444f228 +!! source digest: sha256:61fb5987a03dd433cc41146fb2b0a02cde67896a7c73de4607fda46f2e1dbf4a !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 NuoBiT/odoo-addons

    -
  • Added
  • +
  • This module manages production batches.

Table of contents

@@ -407,6 +407,7 @@

Contributors

  • NuoBiT:
  • diff --git a/mrp_production_batch/views/mrp_bom_line.xml b/mrp_production_batch/views/mrp_bom_line.xml new file mode 100644 index 000000000..1dc881f45 --- /dev/null +++ b/mrp_production_batch/views/mrp_bom_line.xml @@ -0,0 +1,22 @@ + + + + mrp.bom.line + + + + + + + + + + mrp.bom + + + + + + + + diff --git a/mrp_production_batch/views/mrp_production_batch_views.xml b/mrp_production_batch/views/mrp_production_batch_views.xml index c100bc0c0..e0cf6910f 100644 --- a/mrp_production_batch/views/mrp_production_batch_views.xml +++ b/mrp_production_batch/views/mrp_production_batch_views.xml @@ -1,6 +1,6 @@ - + mrp.production.batch.tree mrp.production.batch @@ -8,33 +8,24 @@ - - + mrp.production.batch.form mrp.production.batch
    -
    @@ -88,34 +79,48 @@ />
    +
    +

    + Draft +

    +

    + +

    +
    - - - - - - - + + + + - - - mrp.production.batch.select + + mrp.production.batch.search mrp.production.batch + + - + @@ -128,7 +133,7 @@ mrp.production.batch tree,kanban,form - + [('operation_type', '=', active_id)] {'default_picking_type_id': active_id} @@ -137,6 +142,7 @@ ir.actions.act_window mrp.production.batch tree,form + {'search_default_todo': 1}

    No Batch Production order found diff --git a/mrp_production_batch/views/mrp_production_views.xml b/mrp_production_batch/views/mrp_production_views.xml index 395b2e8c8..01440a889 100644 --- a/mrp_production_batch/views/mrp_production_views.xml +++ b/mrp_production_batch/views/mrp_production_views.xml @@ -38,7 +38,7 @@ role="alert" attrs="{'invisible': ['|', ('production_batch_id', '=', False), '|', ('is_ready_to_produce', '=', False), ('state', '=', 'done')]}" > - The location is ready to produce in batch. + The production is ready to produce in batch.