diff --git a/mrp_bom_wizard_production/__manifest__.py b/mrp_bom_wizard_production/__manifest__.py index ae5e7c73..49026739 100644 --- a/mrp_bom_wizard_production/__manifest__.py +++ b/mrp_bom_wizard_production/__manifest__.py @@ -5,12 +5,14 @@ { "name": "MRP BoM Wizard production", "summary": "Wizard linked to Bill of Materials to help your production.", - "version": "16.0.1.1.1", - "category": "GRAP - Custom", + "version": "16.0.1.2.0", + "category": "Manufacturing", "author": "GRAP", "website": "https://github.com/grap/grap-odoo-custom", "license": "AGPL-3", "depends": [ + # OCA modules + "mrp_bom_simple_packaging_description", "mrp_bom_product_price_margin", "mrp_bom_simple_report", "mrp_bom_simple_packaging_description", @@ -18,9 +20,9 @@ "data": [ "security/ir.model.access.csv", "data/report_paperformat.xml", - "report/report_bom_purchase_list.xml", + "report/report_bom_wizard_production.xml", "report/ir_actions_report.xml", - "wizard/view_bom_print_purchase_list_wizard.xml", + "wizard/view_bom_wizard_production.xml", "views/action.xml", "views/menu.xml", ], diff --git a/mrp_bom_wizard_production/data/report_paperformat.xml b/mrp_bom_wizard_production/data/report_paperformat.xml index dad09eaa..7662ba30 100644 --- a/mrp_bom_wizard_production/data/report_paperformat.xml +++ b/mrp_bom_wizard_production/data/report_paperformat.xml @@ -6,8 +6,8 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). --> - - BoM Purchase Print Format + + BoM Wizard Production Format A4 0 0 @@ -16,7 +16,7 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). 10 5 5 - 90 + 75 diff --git a/mrp_bom_wizard_production/i18n/fr.po b/mrp_bom_wizard_production/i18n/fr.po index 9524b597..886271e9 100644 --- a/mrp_bom_wizard_production/i18n/fr.po +++ b/mrp_bom_wizard_production/i18n/fr.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-06-19 11:05+0000\n" -"PO-Revision-Date: 2024-06-19 11:05+0000\n" +"POT-Creation-Date: 2025-01-20 15:08+0000\n" +"PO-Revision-Date: 2025-01-20 15:08+0000\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -16,273 +16,253 @@ msgstr "" "Plural-Forms: \n" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_purchase_list +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_wizard_production msgid "(for" msgstr "(pour" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_purchase_list -msgid "Quantity: " -msgstr "Quantité : " - -#. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_purchase_list +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_wizard_production msgid "Total based on BoMs cost:" msgstr "Total basé sur le coût des fiches techniques :" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_purchase_list +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_wizard_production msgid "Total based on Products cost:" msgstr "Total basé sur le coût des produits :" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_purchase_list -msgid "Bill of Material" -msgstr "Fiche technique" - -#. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard_line__bom_id +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production_line__bom_id msgid "Bill Of Material" msgstr "Fiche technique" #. module: mrp_bom_wizard_production #: model:ir.model,name:mrp_bom_wizard_production.model_mrp_bom -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_purchase_list +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_wizard_production msgid "Bill of Material" -msgstr "Nomenclature" - -#. module: mrp_bom_wizard_production -#: model:ir.actions.report,name:mrp_bom_wizard_production.bom_purchase_list -msgid "BoM Purchase List" -msgstr "" +msgstr "Fiche technique" #. module: mrp_bom_wizard_production -#: model:ir.model,name:mrp_bom_wizard_production.model_report_mrp_bom_wizard_production_report_bom_purchase_list -msgid "BoM Purchase list" -msgstr "" +#: model:ir.actions.report,name:mrp_bom_wizard_production.bom_wizard_production +#: model:ir.model,name:mrp_bom_wizard_production.model_report_mrp_bom_wizard_production_report_bom_wizard_production +msgid "BoM Wizard Production" +msgstr "Assistant de production des Fiches Techniques" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard_line__bom_product_qty +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production_line__bom_product_qty msgid "BoM Qty" msgstr "Qté de la FT" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.view_bom_print_purchase_list_wizard_form +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.view_bom_wizard_production_form msgid "Cancel" msgstr "Annuler" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.view_bom_print_purchase_list_wizard_form +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.view_bom_wizard_production_form msgid "Choose the quantity of each BoMs 🖨️" -msgstr "" +msgstr "Choisir la quantité pour chaque Fiche Technique 🖨️" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_purchase_list -msgid "Component" -msgstr "Matière Première" - -#. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_purchase_list +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_wizard_production msgid "Components requirements" msgstr "Matières premières nécessaires" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard_line__wizard_line_subtotal +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production_line__wizard_line_subtotal msgid "Cost" msgstr "Coût" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard__create_uid -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard_line__create_uid +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production__create_uid +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production_line__create_uid msgid "Created by" -msgstr "" +msgstr "Crée par" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard__create_date -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard_line__create_date +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production__create_date +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production_line__create_date msgid "Created on" -msgstr "" +msgstr "Crée le" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard_line__currency_id +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production_line__currency_id #: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_mrp_bom__currency_id msgid "Currency" msgstr "Devise" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard_line__quantity +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production_line__quantity msgid "Desired Quantity" msgstr "Qté voulue" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard__display_name -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard_line__display_name +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production__display_name +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production_line__display_name msgid "Display Name" msgstr "Nom affiché" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_purchase_list +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_wizard_production msgid "Free comment" msgstr "Commentaire libre" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard__option_group_by_product_category +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production__option_group_by_product_category msgid "Group product by product category" msgstr "Grouper les produits par leur catégorie" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard__option_display_cost +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production__option_display_cost msgid "Handle products standard prices" msgstr "Gérer le prix des produits" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard__id -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard_line__id +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production__id +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production_line__id msgid "ID" msgstr "" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.view_bom_print_purchase_list_wizard_form +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.view_bom_wizard_production_form msgid "Informations on PDF" -msgstr "" +msgstr "Informations sur le PDF" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_purchase_list +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_wizard_production msgid "Intermediate products to produce" msgstr "Produits intermédiaires à produire" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard____last_update -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard_line____last_update +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production____last_update +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production_line____last_update msgid "Last Modified on" msgstr "Dernière modification le" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard__write_uid -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard_line__write_uid +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production__write_uid +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production_line__write_uid msgid "Last Updated by" msgstr "Dernière mise à jour le" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard__write_date -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard_line__write_date +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production__write_date +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production_line__write_date msgid "Last Updated on" msgstr "Dernière mise à jour le" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard__line_ids +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production__line_ids msgid "Lines" msgstr "Lignes" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard__no_origin +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production__no_origin msgid "No Origin" msgstr "Pas d'origine" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.view_bom_print_purchase_list_wizard_form +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.view_bom_wizard_production_form msgid "Notes" msgstr "" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard__notes_for_pdf +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production__notes_for_pdf msgid "Notes For Pdf" msgstr "Notes sur le PDF" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.view_bom_print_purchase_list_wizard_form +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.view_bom_wizard_production_form msgid "Options for PDF" msgstr "Options du PDF" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.view_bom_print_purchase_list_wizard_form +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.view_bom_wizard_production_form msgid "Order of March 18, 1871 for customer Louise Michel" msgstr "Commande du 18 mars 1871 de Louise Michel" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard_line__bom_origin +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production_line__bom_origin msgid "Origin" msgstr "Origine" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard_line__bom_description -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_mrp_bom__description_packaging +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_wizard_production +msgid "Packaging" +msgstr "Conditionnement" + +#. module: mrp_bom_wizard_production +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production_line__bom_description msgid "Packaging description" msgstr "Description de conditionnement" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_purchase_list +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_wizard_production msgid "Price Unit" msgstr "Prix unitaire" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.view_bom_print_purchase_list_wizard_form +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.view_bom_wizard_production_form msgid "Print Production Report" -msgstr "Prix unitaire" +msgstr "Imprimer le récap de production" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.view_bom_print_purchase_list_wizard_form +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.view_bom_wizard_production_form msgid "Print Production Report and BoMs" msgstr "Imprimer le récap de production et les fiches techniques" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.view_bom_print_purchase_list_wizard_form -msgid "Print Purchase list" -msgstr "Imprimer la liste d'achats" - -#. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard__option_print_bom +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production__option_print_bom msgid "Print bill of materials" msgstr "Imprimer les fiches techniques" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_purchase_list +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_wizard_production msgid "Printed on:" msgstr "Imprimé le :" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_purchase_list +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_wizard_production msgid "Product" msgstr "Article" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard__option_production_date +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production__option_production_date msgid "Production Date" msgstr "Date de production" #. module: mrp_bom_wizard_production -#: model:ir.actions.act_window,name:mrp_bom_wizard_production.action_mrp_bom_wizard_production_list_print_wizard -#: model:ir.ui.menu,name:mrp_bom_wizard_production.menu_mrp_bom_wizard_production_list_print -msgid "Production assistant" -msgstr "Assistant de production" - -#. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_purchase_list +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_wizard_production msgid "Production date:" msgstr "Date de production :" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_purchase_list +#: model:ir.actions.act_window,name:mrp_bom_wizard_production.action_mrp_bom_wizard_production +#: model:ir.ui.menu,name:mrp_bom_wizard_production.menu_mrp_bom_wizard_production +msgid "Production wizard" +msgstr "Assistant de production" + +#. module: mrp_bom_wizard_production +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_wizard_production msgid "Quantities to be prepared" msgstr "Quantités à préparer" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_purchase_list +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_wizard_production msgid "Quantity" msgstr "Quantité" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_purchase_list +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_wizard_production msgid "Subtotal" msgstr "Sous-total" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_purchase_list +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_wizard_production msgid "Sum um quantities per bills of materials" msgstr "Résumé des quantités par fiche technique" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,help:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard_line__bom_product_qty +#: model:ir.model.fields,help:mrp_bom_wizard_production.field_bom_wizard_production_line__bom_product_qty msgid "" "This should be the smallest quantity that this product can be produced in. " "If the BOM contains operations, make sure the work center capacity is " @@ -290,50 +270,50 @@ msgid "" msgstr "" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.view_bom_print_purchase_list_wizard_form +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.view_bom_wizard_production_form msgid "Title" msgstr "Titre" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard__title_for_pdf +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production__title_for_pdf msgid "Title For Pdf" msgstr "Titre pour le PDF" #. module: mrp_bom_wizard_production -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.view_bom_print_purchase_list_wizard_form +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.view_bom_wizard_production_form msgid "Total Cost" msgstr "Coût total" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,help:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard_line__bom_uom_id +#: model:ir.model.fields,help:mrp_bom_wizard_production.field_bom_wizard_production_line__bom_uom_id msgid "" "Unit of Measure (Unit of Measure) is the unit of measurement for the " "inventory control" -msgstr "L'unité de mesure est l'unité utilisée dans la gestion du stock" +msgstr "" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard_line__bom_uom_id -#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_purchase_list +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production_line__bom_uom_id +#: model_terms:ir.ui.view,arch_db:mrp_bom_wizard_production.report_bom_wizard_production msgid "UoM" msgstr "UdM" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard_line__wizard_id +#: model:ir.model.fields,field_description:mrp_bom_wizard_production.field_bom_wizard_production_line__wizard_id msgid "Wizard" msgstr "Assistant" #. module: mrp_bom_wizard_production -#: model:ir.model,name:mrp_bom_wizard_production.model_bom_print_purchase_list_wizard +#: model:ir.model,name:mrp_bom_wizard_production.model_bom_wizard_production msgid "Wizard for printing bill of materials" msgstr "" #. module: mrp_bom_wizard_production -#: model:ir.model,name:mrp_bom_wizard_production.model_bom_print_purchase_list_wizard_line +#: model:ir.model,name:mrp_bom_wizard_production.model_bom_wizard_production_line msgid "Wizard line for printing purchase list from selected bill of materials" msgstr "" #. module: mrp_bom_wizard_production -#: model:ir.model.fields,help:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard__notes_for_pdf -#: model:ir.model.fields,help:mrp_bom_wizard_production.field_bom_print_purchase_list_wizard__title_for_pdf +#: model:ir.model.fields,help:mrp_bom_wizard_production.field_bom_wizard_production__notes_for_pdf +#: model:ir.model.fields,help:mrp_bom_wizard_production.field_bom_wizard_production__title_for_pdf msgid "Write whatever you want to be written in PDF headers" -msgstr "Ecrivez ce que vous voulez qui apparaisse en entête du PDF" +msgstr "Ecrivez ce que vous voulez qui apparaisse en entête du PDF" \ No newline at end of file diff --git a/mrp_bom_wizard_production/report/__init__.py b/mrp_bom_wizard_production/report/__init__.py index eb5cd982..1c49813f 100644 --- a/mrp_bom_wizard_production/report/__init__.py +++ b/mrp_bom_wizard_production/report/__init__.py @@ -1 +1 @@ -from . import report_bom_purchase_list +from . import report_bom_wizard_production diff --git a/mrp_bom_wizard_production/report/ir_actions_report.xml b/mrp_bom_wizard_production/report/ir_actions_report.xml index 2017659c..9ce94a1f 100644 --- a/mrp_bom_wizard_production/report/ir_actions_report.xml +++ b/mrp_bom_wizard_production/report/ir_actions_report.xml @@ -6,13 +6,13 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). --> - - report.bom.purchase.list - BoM Purchase List + + report.bom.wizard.production + BoM Wizard Production qweb-pdf - mrp_bom_wizard_production.report_bom_purchase_list + mrp_bom_wizard_production.report_bom_wizard_production False - + diff --git a/mrp_bom_wizard_production/report/report_bom_purchase_list.py b/mrp_bom_wizard_production/report/report_bom_purchase_list.py deleted file mode 100644 index 9742662c..00000000 --- a/mrp_bom_wizard_production/report/report_bom_purchase_list.py +++ /dev/null @@ -1,433 +0,0 @@ -import copy -from operator import itemgetter - -from odoo import api, models - - -class ReportBomPurchaseList(models.AbstractModel): - _name = "report.mrp_bom_wizard_production.report_bom_purchase_list" - _description = "BoM Purchase list" - - @api.model - def _get_report_values(self, docids, data=None): - ( - data_purchase, - data_produce, - data_all_bom, - data_list_matrix_product_bom, - data_produce_bom_qty, - ) = self._prepare_data_to_purchase_and_produce(data) - purchase_total_cost = round(sum(map(lambda x: x[5], data_purchase)), 2) - manufacture_bom_list = self._prepare_data_to_manufacture(data) - docargs = { - "manufacture_bom_list": manufacture_bom_list, - "purchase_list": data_purchase, - "produce_list": data_produce, - "manufacture_total_cost": self._prepare_manufacture_total_cost(data), - "purchase_total_cost": purchase_total_cost, - "data_all_bom": data_all_bom, - "data_list_matrix_product_bom": data_list_matrix_product_bom, - "currency_symbol": self._prepare_currency(data), - "wizard_lines": self._get_wizard_lines(data), - "data_produce_bom_qty": data_produce_bom_qty, - } - return docargs - - @api.model - def calculate_qty_for_one_product( - self, bom_line_product_qty, bom_qty, desired_qty, digits - ): - _bom_qty = max(1, bom_qty) - return round(bom_line_product_qty * desired_qty / _bom_qty, digits) - - # Used in _prepare_data_to_purchase_and_produce - @api.model - def _get_wizard_lines(self, data): - return self.env["bom.print.purchase.list.wizard.line"].browse(data["line_data"]) - - # Used in _prepare_data_to_purchase_and_produce - @api.model - def create_data_purchase_and_data_product_bom_qty( - self, - line_template, - bom_lines_with_factor, - purchase_list, - data_product_bom_qty, - wiz_bom_line, - bom_qty, - ): - # Go through concatenation of nested BoMs Lines and Boms Lines - for bom_lines_with_quantity in bom_lines_with_factor: - parent_bom_factor_qty = bom_lines_with_quantity[1] - for bom_line in bom_lines_with_quantity[0]: - product = bom_line.product_id - product_id = product.id - product_qty = self.calculate_qty_for_one_product( - bom_line.product_qty, - bom_qty, - wiz_bom_line.quantity * parent_bom_factor_qty, - 3, - ) - bom_line_subtotal = round(product_qty * bom_line.standard_price_unit, 3) - # Add quantity if product is already there - if product_id in purchase_list: - purchase_list[product_id]["quantity"] = round( - purchase_list[product_id]["quantity"] + product_qty, 3 - ) - purchase_list[product_id]["subtotal"] = round( - purchase_list[product_id]["subtotal"] + bom_line_subtotal, - 3, - ) - else: - purchase_list[product_id] = { - "category": bom_line.product_id.categ_id.complete_name, - "product_name": bom_line.product_id.name.capitalize(), - "quantity": round(product_qty, 3), - "uom": bom_line.product_uom_id.name, - "price_unit": round(bom_line.standard_price_unit, 3), - "subtotal": round(bom_line_subtotal, 3), - } - - if bom_lines_with_quantity[2] is not False: - # nested bom_line → choose nested_bom - bom_id_concerned = bom_lines_with_quantity[2].id - else: - bom_id_concerned = wiz_bom_line.bom_id.id - if product_id not in data_product_bom_qty: - # add template : set 0 for each futur BoM column - data_product_bom_qty[product_id] = copy.deepcopy(line_template) - data_product_bom_qty[product_id][bom_id_concerned][1] = round( - product_qty, 3 - ) - data_product_bom_qty[product_id]["product_name"] = product.name - data_product_bom_qty[product_id]["uom"] = str( - bom_line.product_uom_id.name - ) - else: - rounded_sum = round( - data_product_bom_qty[product_id][bom_id_concerned][1] - + product_qty, - 3, - ) - data_product_bom_qty[product_id][bom_id_concerned][1] = rounded_sum - - return purchase_list, data_product_bom_qty - - # Used in _prepare_data_to_purchase_and_produce - @api.model - def create_data_produce(self, data_produce, wiz_bom_line, bom_lines, bom_qty): - bom_lines_with_factor = [] - data_produce_bom_qty = [] - - for bom_line in bom_lines: - product = bom_line.product_id - product_id = product.id - # /!\ Limitation : only get the first nested BoM - # Each nested BoM (intermediate product) is a product to produce - if product.bom_ids: - nested_bom = product.bom_ids[0] - - # Search bom_lines - nested_bom_lines = self.env["mrp.bom.line"].search( - [("bom_id", "=", nested_bom.id), ("product_id", "!=", False)] - ) - - # DATA_PURCHASE : - # - fill bom_lines_with_factor - # - filter bom_lines to remove INTERMEDIATE product - # Add nested bom lines with factor which is - # bom_line parent quantity divided by nested bom quantity - parent_bom_factor_qty = ( - bom_line.product_qty / nested_bom.product_qty - if nested_bom.product_qty != 0 - else 1 - ) - # Create this list that will be used for other data* - bom_lines_with_factor.append( - [nested_bom_lines, parent_bom_factor_qty, nested_bom] - ) - - # DATA_PRODUCE - # Add intermediate product and calculate values of this line - produce_product_qty = self.calculate_qty_for_one_product( - bom_line.product_qty, bom_qty, wiz_bom_line.quantity, 3 - ) - produce_subtotal = round( - produce_product_qty * bom_line.standard_price_unit, 3 - ) - - to_produce_product_bom_name = ( - wiz_bom_line.bom_id.display_name + " x" + str(produce_product_qty) - ) - # Add product or just quantity if product is already there - if product_id in data_produce: - data_produce[product_id]["to_produce_product_bom_name"] += str( - ", " + to_produce_product_bom_name - ) - data_produce[product_id]["to_produce_quantity"] = round( - data_produce[product_id]["to_produce_quantity"] - + produce_product_qty, - 4, - ) - data_produce[product_id]["to_produce_subtotal"] = round( - data_produce[product_id]["to_produce_subtotal"] - + produce_subtotal, - 3, - ) - else: - _product_name = bom_line.product_id.name.capitalize() - data_produce[product_id] = { - "to_produce_product_name": _product_name, - "to_produce_product_bom_name": to_produce_product_bom_name, - "to_produce_quantity": round(produce_product_qty, 3), - "to_produce_uom": bom_line.product_uom_id.name, - "to_produce_price_unit": bom_line.standard_price_unit, - "to_produce_subtotal": round(produce_subtotal, 3), - } - - # Create this list used in PDF for data_produce - data_produce_bom_qty.append( - [nested_bom, produce_product_qty, to_produce_product_bom_name] - ) - - return data_produce, bom_lines_with_factor, data_produce_bom_qty - - # Returns five lists : - # 1. DATA_PURCHASE : component products that we'll be purchased - # → [['category', 'product_name', quantity, uom, price_unit, subtotal], ... ] - # 2. DATA_PRODUCE : intermediates products that we'll be produced [bom_id1, bom_id2] - # 3. DATA_ALL_BOM : all boms : - # → [['Tomato pie', 0.1, 'kg'], ['Wood Panel', 1.0, 'Unit(s)']] - # 4. DATA_LIST_MATRIX_PRODUCT_BOM - # → [['Pie', 1.0, ' '], ['Tomatoes', 0.5, ' '], ..] - # 5. DATA_PRODUCE_BOM_QTY - # → [[mrp.bom(1), 2.0, 'Intermediate product for Tomatoes'], ..] - @api.model - def _prepare_data_to_purchase_and_produce(self, data): - mrp_bom_line_obj = self.env["mrp.bom.line"] - # Get the selected BoMs and their associated lines - wiz_boms_lines = self._get_wizard_lines(data) - wiz_boms_lines.mapped("bom_id") - - # ==== LINE_TEMPLATE and DATA_ALL_BOM - # Create template with as many zero as BoM - # to prepare data_list_matrix_product_bom - # Look like : {10: [BomName1, 0], 5: [BomName2, 0]} - # Need to go through nested boms one first time - line_template = {} - pre_data_all_bom = {} - for wiz_bom_line in wiz_boms_lines: - bom = wiz_bom_line.bom_id - bom_id = bom.id - - # Add bom to line_template - line_template[bom_id] = [bom.display_name, 0] - - # ==== DATA_ALL_BOM - if not pre_data_all_bom.get(bom.id): - pre_data_all_bom[bom_id] = [ - bom.display_name, - round(wiz_bom_line.quantity, 3), - wiz_bom_line.bom_uom_id.name, - ] - else: - rounded_sum = round( - pre_data_all_bom[bom_id][1] + wiz_bom_line.quantity, 3 - ) - pre_data_all_bom[bom_id][1] = rounded_sum - - # /!\ Limitation : Search its bomlines and get the FIRST nested BoM - bom_lines = mrp_bom_line_obj.search( - [("bom_id", "=", bom_id), ("product_id", "!=", False)] - ) - for bom_line in bom_lines: - if bom_line.product_id.bom_ids: - nested_bom = bom_line.product_id.bom_ids[0] - nested_bom_id = nested_bom.id - - # Add nested bom to line_template - line_template[nested_bom_id] = [nested_bom.display_name, 0] - # DATA_ALL_BOM - quantity_with_factor = bom_line.product_qty * wiz_bom_line.quantity - if not pre_data_all_bom.get(nested_bom_id): - pre_data_all_bom[nested_bom_id] = [ - "↳ " + nested_bom.display_name, - round(quantity_with_factor, 3), - bom_line.product_uom_id.name, - ] - else: - rounded_sum = round( - pre_data_all_bom[nested_bom_id][1] + quantity_with_factor, 3 - ) - pre_data_all_bom[nested_bom_id][1] = rounded_sum - - # ==== DATA_ALL_BOM : formate for PDF - data_all_bom = [] - for value in pre_data_all_bom.values(): - data_all_bom.append(value[0] + " - " + str(value[1]) + " " + value[2]) - - # ==== Init variables - pre_data_produce = {} - pre_data_purchase = {} - data_product_bom_qty = {} - - # ==== Create pre_DATA_PRODUCE, pre_DATA_PURCHASE - # and pre_DATA_LIST_MATRIX_PRODUCT_BOM - for wiz_bom_line in wiz_boms_lines: - bom = wiz_bom_line.bom_id - bom_qty = bom.product_qty - # Search bomlines without bomlines of notes or sections - bom_lines = mrp_bom_line_obj.search( - [("bom_id", "=", bom.id), ("product_id", "!=", False)] - ) - # ==== DATA_PROCUCE and DATA_PRODUCE_BOM_QTY (coming from nested boms) - # Also add their bom lines in bom_lines_with_factor to create DATA_PURCHASE - ( - pre_data_produce, - bom_lines_with_factor, - data_produce_bom_qty, - ) = self.create_data_produce( - pre_data_produce, wiz_bom_line, bom_lines, bom_qty - ) - # bom_lines_with_factor = [[bom_lines1, factor1, nested_bom_lines1], ..] - - # ==== DATA_PURCHASE (components products) - # ==== and DATA_LIST_MATRIX_PRODUCT_BOM - # Formate bom_lines to be add with nested bom lines, factor is 1 - bom_lines_with_factor.append([bom_lines, 1, False]) - - # # Go through concatenation of nested BoMs Lines and Boms Lines - ( - pre_data_purchase, - data_product_bom_qty, - ) = self.create_data_purchase_and_data_product_bom_qty( - line_template, - bom_lines_with_factor, - pre_data_purchase, - data_product_bom_qty, - wiz_bom_line, - bom_qty, - ) - - # ==== Precreate DATA_LIST_MATRIX_PRODUCT_BOM - data_list_matrix_product_bom = [] - for value in data_product_bom_qty.values(): - row = [value["product_name"] + " (" + value["uom"] + ")"] - for _key, _value in value.items(): - if _key not in ("product_name", "uom"): - row.append(_value[1]) - data_list_matrix_product_bom.append(row) - - data_list_matrix_product_bom = [ - [val if val != 0 else " " for val in sublist] - for sublist in data_list_matrix_product_bom - ] - - # Formate purchase_list dict in list the way we want - data_purchase = [] - for bom_line in pre_data_purchase.values(): - data_purchase.append( - [ - bom_line[field] - for field in [ - "category", - "product_name", - "quantity", - "uom", - "price_unit", - "subtotal", - ] - ] - ) - # Sort the PURCHASE_LIST by product name and, optionally, category - data_purchase.sort( - key=itemgetter(0, 1) - if data["option_group_by_product_category"] - else itemgetter(1) - ) - - # ==== DATA_PRODUCE : formate dict in list the way we want - data_produce = [] - for bom in pre_data_produce.values(): - data_produce.append( - [ - bom[field] - for field in [ - "to_produce_product_name", - "to_produce_product_bom_name", - "to_produce_quantity", - "to_produce_uom", - "to_produce_price_unit", - "to_produce_subtotal", - ] - ] - ) - - return ( - data_purchase, - data_produce, - data_all_bom, - data_list_matrix_product_bom, - data_produce_bom_qty, - ) - - @api.model - def _prepare_data_to_manufacture(self, data): - line_obj = self.env["bom.print.purchase.list.wizard.line"] - bom_line_obj = self.env["mrp.bom.line"] - wiz_boms = line_obj.browse([int(x) for x in data["line_data"]]) - - # Get all BOM lines without bomlines of notes or sections - bom_lines = bom_line_obj.search( - [ - ("bom_id", "in", wiz_boms.mapped("bom_id").ids), - ("product_id", "!=", False), - ] - ) - - manufacture_bom_list = [] - for wiz_bom in wiz_boms: - bom = wiz_bom.bom_id - bom_qty = bom.product_qty - desired_bom_qty = wiz_bom.quantity - - tmp_bom_lines = [] - for bom_line in bom_lines: - product_qty = self.calculate_qty_for_one_product( - bom_line.product_qty, bom_qty, desired_bom_qty, 3 - ) - tmp_bom_lines.append( - [ - bom_line.product_id.display_name, - product_qty, - bom_line.product_uom_id.name, - ] - ) - - manufacture_bom_list.append( - [ - bom.display_name, - desired_bom_qty, - wiz_bom.bom_uom_id.name, - round(wiz_bom.bom_id.standard_price, 3), - round(wiz_bom.wizard_line_subtotal, 3), - tmp_bom_lines, - bom.description_packaging, - # bom.notes, - ] - ) - # manufacture_bom_list = [['SEITAN_BOM', 2.0, 'Unit(s)', 55.0, 110.0, - # [['Carrots', 10.0, 'kg'], ['Onions', 4.0, 'Unit(s)']]] , bom2] - return manufacture_bom_list - - @api.model - def _prepare_manufacture_total_cost(self, data): - line_obj = self.env["bom.print.purchase.list.wizard.line"] - wiz_boms_lines = line_obj.browse([int(x) for x in data["line_data"]]) - return round(sum(wiz_boms_lines.mapped("wizard_line_subtotal")), 3) - - @api.model - def _prepare_currency(self, data): - line_obj = self.env["bom.print.purchase.list.wizard.line"] - wiz_boms_lines = line_obj.browse([int(x) for x in data["line_data"]]) - return wiz_boms_lines[0].currency_id.symbol if wiz_boms_lines else "" diff --git a/mrp_bom_wizard_production/report/report_bom_wizard_production.py b/mrp_bom_wizard_production/report/report_bom_wizard_production.py new file mode 100644 index 00000000..09f391c2 --- /dev/null +++ b/mrp_bom_wizard_production/report/report_bom_wizard_production.py @@ -0,0 +1,445 @@ +import copy + +from odoo import api, models + + +class ReportBomWizardProduction(models.AbstractModel): + _name = "report.mrp_bom_wizard_production.report_bom_wizard_production" + _description = "BoM Wizard Production" + + # data are given by bom_wizard_production.py + @api.model + def _get_report_values(self, docids, data=None): + ( + data_manufacture_list, + data_manufacture_total_cost, + data_purchase_list, + data_intermediate_product_list, + data_intermediate_product_bom_qty, + data_matrix_boms, + data_matrix_product_bom, + ) = self._prepare_data_to_purchase_and_produce(data) + purchase_total_cost = round(sum(map(lambda x: x[5], data_purchase_list)), 2) + docargs = { + "manufacture_bom_list": data_manufacture_list, + "manufacture_total_cost": data_manufacture_total_cost, + "intermediate_product_list": data_intermediate_product_list, + "data_intermediate_product_bom_qty": data_intermediate_product_bom_qty, + "purchase_list": data_purchase_list, + "purchase_total_cost": purchase_total_cost, + "data_matrix_boms": data_matrix_boms, + "data_matrix_product_bom": data_matrix_product_bom, + "currency_symbol": data["currency_symbol"], + "wizard_lines": self._get_wizard_lines(data), + } + return docargs + + @api.model + def calculate_qty_for_one_product( + self, bom_line_product_qty, bom_qty, desired_qty, digits + ): + _bom_qty = max(1, bom_qty) + return round(bom_line_product_qty * desired_qty / _bom_qty, digits) + + @api.model + def _get_wizard_lines(self, data): + return self.env["bom.wizard.production.line"].browse(data["line_data"]) + + # Used in _prepare_data_to_purchase_and_produce + @api.model + def create_data_purchase_list_and_pre_data_matrix_product_bom( + self, + line_template, + bom_lines_with_factor, + pre_data_purchase_list, + pre_data_matrix_product_bom, + wiz_line, + intermediate_product_ids, + ): + """ + This function is called through a loop of Wizard Line (Bom, Desired Qty..) + It goes through concatenation of the BoM lines and its nested BoMs Lines + in order to set datas + + :param: line_template: adjust template if new product + :param: bom_lines_with_factor: go through this array + :param: pre_data_purchase_list: + :param: pre_data_matrix_product_bom: + :param: wiz_line: + :param: intermediate_product_ids: used to filter products not be purchased + :return: purchase_list: + :return: pre_data_matrix_product_bom: + """ + _bom_qty = wiz_line.bom_id.product_qty + # Go through all BoM Lines linked to their parents + for bom_lines_with_quantity in bom_lines_with_factor: + parent_bom_factor_qty = bom_lines_with_quantity[1] + for bom_line in bom_lines_with_quantity[0]: + product = bom_line.product_id + product_id = product.id + product_qty = self.calculate_qty_for_one_product( + bom_line.product_qty, + _bom_qty, + wiz_line.quantity * parent_bom_factor_qty, + 3, + ) + bom_line_subtotal = round(product_qty * bom_line.standard_price_unit, 3) + # FILTER intermediate products that will not be purchased + if product_id not in intermediate_product_ids: + # Add quantity if product is already there + if product_id in pre_data_purchase_list: + pre_data_purchase_list[product_id]["quantity"] = round( + pre_data_purchase_list[product_id]["quantity"] + + product_qty, + 3, + ) + pre_data_purchase_list[product_id]["subtotal"] = round( + pre_data_purchase_list[product_id]["subtotal"] + + bom_line_subtotal, + 3, + ) + else: + pre_data_purchase_list[product_id] = { + "category": bom_line.product_id.categ_id.complete_name, + "product_name": bom_line.product_id.name.capitalize(), + "quantity": round(product_qty, 3), + "uom": bom_line.product_uom_id.name, + "price_unit": round(bom_line.standard_price_unit, 3), + "subtotal": round(bom_line_subtotal, 3), + } + + if bom_lines_with_quantity[2] is not False: + # nested bom_line → choose nested_bom + bom_id_concerned = bom_lines_with_quantity[2].id + else: + bom_id_concerned = wiz_line.bom_id.id + + if product_id not in pre_data_matrix_product_bom: + # new product, we add a line_template + pre_data_matrix_product_bom[product_id] = copy.deepcopy( + line_template + ) + pre_data_matrix_product_bom[product_id][bom_id_concerned][ + 1 + ] = round(product_qty, 3) + pre_data_matrix_product_bom[product_id][ + "product_name" + ] = product.name + pre_data_matrix_product_bom[product_id]["uom"] = str( + bom_line.product_uom_id.name + ) + else: + rounded_sum = round( + pre_data_matrix_product_bom[product_id][bom_id_concerned][1] + + product_qty, + 3, + ) + pre_data_matrix_product_bom[product_id][bom_id_concerned][ + 1 + ] = rounded_sum + + return pre_data_purchase_list, pre_data_matrix_product_bom + + @api.model + def create_datas_from_nested_boms(self, data_intermediate_product_list, wiz_line): + """ + This function is called in a loop with all BoMs of Wizard + - It gradually fills pre_data_intermediate_product_list with quantities + - It gets all bom_lines_with_factor* that will be used for other datas + *factor indicate qty from parent BoM that will by apply to children + *factor should not to be confused with product_qty of mrp.bom.lin + Example : + [[mrp.bom.line(8,), 1, False], [mrp.bom.line(10, 11), 2.0, mrp.bom(5,)]] + mrp_bom_line id8 has a BoM with two mrp_bom_line id10 and id11 + + :param data_intermediate_product_list: array being filled gradually + :param wiz_line: bom.wizard.production.line with Bom, Bom Qty, Desired Qty + :return: data_intermediate_product_list + :return: bom_lines_with_factor + """ + bom_lines_with_factor = [] + data_intermediate_product_bom_qty = [] + + # Loop in every bom_line of the BoM that has a BoM + for bom_line in wiz_line.bom_id.bom_line_ids.filtered( + lambda x: x.product_id.bom_ids + ): + product = bom_line.product_id + product_id = product.id + # Arbitrarily get the first nested BoM and search its bom_lines + nested_bom = product.bom_ids[0] + nested_bom_lines = self.env["mrp.bom.line"].search( + [("bom_id", "=", nested_bom.id), ("product_id", "!=", False)] + ) + + # Add nested bom lines with factor which is + # bom_line parent quantity divided by nested bom quantity + parent_bom_factor_qty = ( + bom_line.product_qty / nested_bom.product_qty + if nested_bom.product_qty != 0 + else 1 + ) + # Will be used for data_purchase_list & data_matrix_product_bom + bom_lines_with_factor.append( + [nested_bom_lines, parent_bom_factor_qty, nested_bom, True] + ) + + # Add intermediate product and calculate values of this line + produce_product_qty = self.calculate_qty_for_one_product( + bom_line.product_qty, + wiz_line.bom_id.product_qty, + wiz_line.quantity, + 3, + ) + produce_subtotal = round( + produce_product_qty * bom_line.standard_price_unit, 3 + ) + + to_produce_product_bom_name = ( + wiz_line.bom_id.display_name + " x" + str(produce_product_qty) + ) + # Add product or just quantity if product is already there + if product_id in data_intermediate_product_list: + data_intermediate_product_list[product_id][ + "to_produce_product_bom_name" + ] += str(", " + to_produce_product_bom_name) + data_intermediate_product_list[product_id][ + "to_produce_quantity" + ] = round( + data_intermediate_product_list[product_id]["to_produce_quantity"] + + produce_product_qty, + 4, + ) + data_intermediate_product_list[product_id][ + "to_produce_subtotal" + ] = round( + data_intermediate_product_list[product_id]["to_produce_subtotal"] + + produce_subtotal, + 3, + ) + else: + _product_name = bom_line.product_id.name.capitalize() + data_intermediate_product_list[product_id] = { + "to_produce_product_name": _product_name, + "to_produce_product_bom_name": to_produce_product_bom_name, + "to_produce_quantity": round(produce_product_qty, 3), + "to_produce_uom": bom_line.product_uom_id.name, + "to_produce_price_unit": bom_line.standard_price_unit, + "to_produce_subtotal": round(produce_subtotal, 3), + } + + # Create this list used in PDF for printing Intermediate products BoMs + data_intermediate_product_bom_qty.append( + [nested_bom, produce_product_qty, to_produce_product_bom_name] + ) + + return ( + data_intermediate_product_list, + bom_lines_with_factor, + data_intermediate_product_bom_qty, + ) + + @api.model + def _prepare_data_to_purchase_and_produce(self, data): + """ + This function formate datas for the production report + It has two main loops on wizard lines (BoM) + FIRST LOOP : get all BoMs and nested BoMs and create line_template + SECOND LOOP : set datas, using - for a part - line_template + + :param: data: datas from wizard + :return: lists and data for report + - data_manufacture_list + - data_manufacture_total_cost + - data_purchase_list + - data_intermediate_product_list + - data_intermediate_product_bom_qty + - data_matrix_boms : used in matrix head table + - data_matrix_product_bom + """ + + # Init obj and variables + mrp_bom_line_obj = self.env["mrp.bom.line"] + wiz_lines = self._get_wizard_lines(data) + line_template = {} + data_manufacture_list = [] + pre_data_intermediate_product_list = {} + pre_data_purchase_list = {} + pre_data_matrix_product_bom = {} + pre_data_matrix_boms = {} + + # ==== SET data_manufacture_total_cost + data_manufacture_total_cost = round( + sum(wiz_lines.mapped("wizard_line_subtotal")), 3 + ) + + # FIRST LOOP + # - create line_template* with BoM and nested BoM for data_matrix_product_bom + # - set data_manufacture_list + # *line_template has as many idBoM key as BoM. 0 will by replaced by quantity + # { idBoM1: [BomName1, 0], idBoM2: [BomName2, 0] } + for wiz_line in wiz_lines: + bom = wiz_line.bom_id + bom_id = bom.id + desired_bom_qty = wiz_line.quantity + + # Add bom to line_template + line_template[bom_id] = [bom.display_name, 0] + + # ==== SET data_manufacture_list + data_manufacture_list.append( + [ + bom.display_name, + bom.description_packaging, + desired_bom_qty, + wiz_line.bom_uom_id.name, + round(wiz_line.bom_id.standard_price, 3), + round(wiz_line.wizard_line_subtotal, 3), + ] + ) + + # First step for data_matrix_boms + # Array of BoM and their quantities being added iteratively + if not pre_data_matrix_boms.get(bom.id): + pre_data_matrix_boms[bom_id] = [ + bom.display_name, + round(wiz_line.quantity, 3), + wiz_line.bom_uom_id.name, + ] + else: + rounded_sum = round( + pre_data_matrix_boms[bom_id][1] + wiz_line.quantity, 3 + ) + pre_data_matrix_boms[bom_id][1] = rounded_sum + + bom_lines = mrp_bom_line_obj.search( + [("bom_id", "=", bom_id), ("product_id", "!=", False)] + ) + # Second step for data_matrix_boms : adding nested BoMs + for bom_line in bom_lines: + if bom_line.product_id.bom_ids: + # /!\ Limitation : Search its bomlines and get the FIRST nested BoM + nested_bom = bom_line.product_id.bom_ids[0] + nested_bom_id = nested_bom.id + + # Add nested bom to line_template and pre_data_matrix_boms + line_template[nested_bom_id] = [nested_bom.display_name, 0] + quantity_with_factor = bom_line.product_qty * wiz_line.quantity + if not pre_data_matrix_boms.get(nested_bom_id): + pre_data_matrix_boms[nested_bom_id] = [ + "↳ " + nested_bom.display_name, + round(quantity_with_factor, 3), + bom_line.product_uom_id.name, + ] + else: + rounded_sum = round( + pre_data_matrix_boms[nested_bom_id][1] + + quantity_with_factor, + 3, + ) + pre_data_matrix_boms[nested_bom_id][1] = rounded_sum + + # ==== SET data_matrix_boms + data_matrix_boms = [] + for value in pre_data_matrix_boms.values(): + data_matrix_boms.append(value[0] + " - " + str(value[1]) + " " + value[2]) + + # SECOND LOOP + # Loop on each Wizard line (BoM, Desired Qty) and apply two functions + # - create_datas_from_nested_boms, then + # - create_data_purchase_list_and_pre_data_matrix_product_bom + for wiz_line in wiz_lines: + _bom = wiz_line.bom_id + _bom_qty = _bom.product_qty + + ( + pre_data_intermediate_product_list, + bom_lines_with_factor, + data_intermediate_product_bom_qty, + ) = self.create_datas_from_nested_boms( + pre_data_intermediate_product_list, wiz_line + ) + + # Get ids of intermediate products that will not be products to purchased + intermediate_product_ids = [*pre_data_intermediate_product_list.keys()] + + # Add bomlines of the BoM except notes and sections + _bom_lines = mrp_bom_line_obj.search( + [("bom_id", "=", _bom.id), ("product_id", "!=", False)] + ) + bom_lines_with_factor.append([_bom_lines, 1, False]) + + ( + pre_data_purchase_list, + pre_data_matrix_product_bom, + ) = self.create_data_purchase_list_and_pre_data_matrix_product_bom( + line_template, + bom_lines_with_factor, + pre_data_purchase_list, + pre_data_matrix_product_bom, + wiz_line, + intermediate_product_ids, + ) + + # ==== SET data_matrix_product_bom + data_matrix_product_bom = [] + for value in pre_data_matrix_product_bom.values(): + row = [value["product_name"] + " (" + value["uom"] + ")"] + for _key, _value in value.items(): + if _key not in ("product_name", "uom"): + row.append(_value[1]) + data_matrix_product_bom.append(row) + + data_matrix_product_bom = [ + [val if val != 0 else " " for val in sublist] + for sublist in data_matrix_product_bom + ] + + # ==== SET data_purchase_list + data_purchase_list = [] + for bom_line in pre_data_purchase_list.values(): + data_purchase_list.append( + [ + bom_line[field] + for field in [ + "category", + "product_name", + "quantity", + "uom", + "price_unit", + "subtotal", + ] + ] + ) + # Sort the purchase_list by product name and optionally category + if data["option_group_by_product_category"]: + data_purchase_list.sort(key=lambda x: (x[0], x[1])) + else: + data_purchase_list.sort(key=lambda x: x[1]) + + # ==== SET data_intermediate_product_list + data_intermediate_product_list = [] + for bom in pre_data_intermediate_product_list.values(): + data_intermediate_product_list.append( + [ + bom[field] + for field in [ + "to_produce_product_name", + "to_produce_product_bom_name", + "to_produce_quantity", + "to_produce_uom", + "to_produce_price_unit", + "to_produce_subtotal", + ] + ] + ) + + return ( + data_manufacture_list, + data_manufacture_total_cost, + data_purchase_list, + data_intermediate_product_list, + data_intermediate_product_bom_qty, + data_matrix_boms, + data_matrix_product_bom, + ) diff --git a/mrp_bom_wizard_production/report/report_bom_purchase_list.xml b/mrp_bom_wizard_production/report/report_bom_wizard_production.xml similarity index 87% rename from mrp_bom_wizard_production/report/report_bom_purchase_list.xml rename to mrp_bom_wizard_production/report/report_bom_wizard_production.xml index 7ae92b45..722df704 100644 --- a/mrp_bom_wizard_production/report/report_bom_purchase_list.xml +++ b/mrp_bom_wizard_production/report/report_bom_wizard_production.xml @@ -6,7 +6,7 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). --> -