diff --git a/.circleci/config.yml b/.circleci/config.yml index b82dd47..979a982 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,3 +1,9 @@ +version: 2.0 + +quay_io_login: &quay_io_login + name: Login to Quay.io register + command: docker login quay.io -u "${QUAY_USER}" -p "${QUAY_TOKEN}" + jobs: tests: machine: true @@ -12,43 +18,41 @@ jobs: name: Setup Log Folder For Reports command: sudo mkdir -p .log && sudo chmod 777 .log - - run: - name: Run Test - command: docker-compose run --rm odoo run_pytest.sh - - - run: - name: Codacy Coverage - command: bash <(curl -Ls https://coverage.codacy.com/get.sh) report -l python -r .log/coverage.xml + # - run: + # name: Run Test + # command: docker-compose run --rm odoo run_pytest.sh - - store_test_results: - path: .log + # - store_test_results: + # path: .log # job that find the next tag for the current branch/repo and push the tag to github. # it will trigger the publish of a new docker image. - auto-tag: - machine: true - steps: - - checkout - - run: - name: Get nws - command: | - curl -L $NWS_BIN_LOCATION > ./nws - chmod +x ./nws - - run: - name: Set tag - command: | - ./nws circleci create-tag -t odoo-base + # auto-tag: + # machine: true + # steps: + # - checkout + # - run: + # name: Get nws + # command: | + # curl -L $NWS_BIN_LOCATION > ./nws + # chmod +x ./nws + # - run: + # name: Set tag + # command: | + # ./nws circleci create-tag -t odoo-base workflows: version: 2 odoo: jobs: - - tests - - auto-tag: - context: nws - requires: - - tests - filters: - branches: - only: /^1\d\.0/ + - tests: + context: quay.io + + # - auto-tag: + # context: nws + # requires: + # - tests + # filters: + # branches: + # only: /^1\d\.0/ diff --git a/.docker_files/main/__init__.py b/.docker_files/main/__init__.py index d2ac44f..aa680fd 100644 --- a/.docker_files/main/__init__.py +++ b/.docker_files/main/__init__.py @@ -1,2 +1,2 @@ -# © 2019 Numigi +# © 2024 Numigi # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). diff --git a/.docker_files/main/__manifest__.py b/.docker_files/main/__manifest__.py index c411c3d..cd1d39a 100644 --- a/.docker_files/main/__manifest__.py +++ b/.docker_files/main/__manifest__.py @@ -1,4 +1,4 @@ -# © 2019 Numigi +# © 2024 Numigi # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). { @@ -11,9 +11,7 @@ "category": "Other", "summary": "Install all addons required for testing.", "depends": [ - "mrp_production_split", - "product_configurator_mrp_component_ext", - "product_configurator_mrp_enhanced", + "mrp", ], "installable": True, } diff --git a/.docker_files/odoo.conf b/.docker_files/odoo.conf index 846e062..973acdb 100644 --- a/.docker_files/odoo.conf +++ b/.docker_files/odoo.conf @@ -49,7 +49,7 @@ test_report_directory = False translate_modules = ['all'] unaccent = False without_demo = False -workers = 4 +workers = 0 xmlrpc = True xmlrpc_interface = xmlrpc_port = 8069 diff --git a/.docker_files/test-requirements.txt b/.docker_files/test-requirements.txt index c70b72a..e69de29 100644 --- a/.docker_files/test-requirements.txt +++ b/.docker_files/test-requirements.txt @@ -1,2 +0,0 @@ -freezegun==0.2.0 -ddt==1.2.1 diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 2894822..68a06bc 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -3,10 +3,10 @@ name: pre-commit on: pull_request: branches: - - "14.0*" + - "16.0*" push: branches: - - "14.0" + - "16.0" jobs: pre-commit: diff --git a/.gitignore b/.gitignore index d2999a0..54f157a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ /.idea/ venv -extra-addons log /.idea __pycache__/ @@ -9,7 +8,6 @@ __pycache__/ Pipfile docker-compose.override.yml .DS_STORE -.third-party-addons .pytest_cache .vscode/ .log \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index cbe7ff1..fdda630 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM quay.io/numigi/odoo-public:14.latest +FROM quay.io/numigi/odoo-public:16.latest LABEL maintainer="contact@numigi.com" USER root @@ -6,9 +6,6 @@ USER root COPY .docker_files/test-requirements.txt . RUN pip3 install -r test-requirements.txt -# Variable used for fetching private git repositories. -ARG GIT_TOKEN - ENV THIRD_PARTY_ADDONS /mnt/third-party-addons RUN mkdir -p "${THIRD_PARTY_ADDONS}" && chown -R odoo "${THIRD_PARTY_ADDONS}" COPY ./gitoo.yml /gitoo.yml @@ -16,9 +13,5 @@ RUN gitoo install-all --conf_file /gitoo.yml --destination "${THIRD_PARTY_ADDONS USER odoo -COPY mrp_production_split /mnt/extra-addons/mrp_production_split -COPY product_configurator_mrp_component_ext /mnt/extra-addons/product_configurator_mrp_component_ext -COPY product_configurator_mrp_enhanced /mnt/extra-addons/product_configurator_mrp_enhanced - COPY .docker_files/main /mnt/extra-addons/main COPY .docker_files/odoo.conf /etc/odoo diff --git a/docker-compose.yml b/docker-compose.yml index 63ab570..a61165e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,10 +4,8 @@ services: build: context: . dockerfile: Dockerfile - args: - - GIT_TOKEN=${GIT_TOKEN} volumes: - - odoo-web-data:/var/lib/odoo + - odoo16-web-data:/var/lib/odoo - ./.log:/var/log/odoo ports: - "8069:8069" @@ -18,16 +16,16 @@ services: environment: - LOG_ODOO=/var/log/odoo db: - image: postgres:13.12 + image: postgres:16.0 environment: - POSTGRES_PASSWORD=odoo - POSTGRES_USER=odoo - PGDATA=/var/lib/postgresql/data/pgdata volumes: - - odoo-db-data:/var/lib/postgresql/data/pgdata + - odoo16-db-data:/var/lib/postgresql/data/pgdata expose: - 5432 volumes: - odoo-web-data: - odoo-db-data: + odoo16-web-data: + odoo16-db-data: diff --git a/gitoo.yml b/gitoo.yml index f54595c..69259b3 100644 --- a/gitoo.yml +++ b/gitoo.yml @@ -1,11 +1,4 @@ -#- url: https://github.com/oca/queue -# branch: "14.0" -# includes: -# - queue_job - - url: https://github.com/OCA/product-configurator - branch: "14.0" + branch: "16.0" includes: - product_configurator - - product_configurator_mrp_component - - product_configurator_mrp diff --git a/mrp_production_split/README.rst b/mrp_production_split/README.rst deleted file mode 100644 index 368dc66..0000000 --- a/mrp_production_split/README.rst +++ /dev/null @@ -1,105 +0,0 @@ -==================== -MRP Production Split -==================== - -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png - :target: https://odoo-community.org/page/development-status - :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png - :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html - :alt: License: AGPL-3 -.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fmanufacture-lightgray.png?logo=github - :target: https://github.com/OCA/manufacture/tree/15.0/mrp_production_split - :alt: OCA/manufacture -.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/manufacture-15-0/manufacture-15-0-mrp_production_split - :alt: Translate me on Weblate -.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/129/15.0 - :alt: Try me on Runbot - -|badge1| |badge2| |badge3| |badge4| |badge5| - -This module adds a "Split" button to Manufacturing Orders. - -Manufacturing Orders can be split as long as they haven't been completed yet. - -For products tracked by "Serial Number", it allows to choose the Quantity to extract -from the original MO, and it'll create one MO per single unit. - -For other products, more options are available, that will let you do things like: - -* Extract 10 units from a MO into 5 MOs of 2 units each. -* Extract 10 units from a MO into a single new MOs. -* Extract 10 units from a MO into multiple MOs of different quantities. - -**Table of contents** - -.. contents:: - :local: - -Usage -===== - -#. Create a Manufacturing Order. -#. Confirm it. -#. Click on the "Split" button. -#. Choose the desired split options. -#. Confirm. - -Bug Tracker -=========== - -Bugs are tracked on `GitHub Issues `_. -In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* Camptocamp - -Contributors -~~~~~~~~~~~~ - -* `Camptocamp `_ - - * Iván Todorovich - -* `Numigi (tm) and all its contributors ()`_ - -Maintainers -~~~~~~~~~~~ - -This module is maintained by the OCA. - -.. image:: https://odoo-community.org/logo.png - :alt: Odoo Community Association - :target: https://odoo-community.org - -OCA, or the Odoo Community Association, is a nonprofit organization whose -mission is to support the collaborative development of Odoo features and -promote its widespread use. - -.. |maintainer-ivantodorovich| image:: https://github.com/ivantodorovich.png?size=40px - :target: https://github.com/ivantodorovich - :alt: ivantodorovich - -Current `maintainer `__: - -|maintainer-ivantodorovich| - -This module is part of the `OCA/manufacture `_ project on GitHub. - -You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mrp_production_split/__init__.py b/mrp_production_split/__init__.py deleted file mode 100644 index aee8895..0000000 --- a/mrp_production_split/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from . import models -from . import wizards diff --git a/mrp_production_split/__manifest__.py b/mrp_production_split/__manifest__.py deleted file mode 100644 index a7d26e7..0000000 --- a/mrp_production_split/__manifest__.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright 2023 Camptocamp SA (https://www.camptocamp.com). -# @author Iván Todorovich -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). - -{ - "name": "MRP Production Split", - "summary": "Split Manufacturing Orders into smaller ones", - "version": "14.0.1.0.0", - "author": "Camptocamp, Odoo Community Association (OCA)", - "maintainers": ["ivantodorovich"], - "website": "https://github.com/OCA/manufacture", - "license": "AGPL-3", - "category": "Manufacturing", - "depends": ["mrp"], - "data": [ - "security/ir.model.access.csv", - "templates/messages.xml", - "views/mrp_production.xml", - "wizards/mrp_production_split_wizard.xml", - ], -} diff --git a/mrp_production_split/i18n/fr.po b/mrp_production_split/i18n/fr.po deleted file mode 100644 index 49ee942..0000000 --- a/mrp_production_split/i18n/fr.po +++ /dev/null @@ -1,234 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * mrp_production_split -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 14.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-26 15:00+0000\n" -"PO-Revision-Date: 2023-06-26 15:00+0000\n" -"Last-Translator: \n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: \n" - -#. module: mrp_production_split -#: code:addons/mrp_production_split/wizards/mrp_production_split_wizard.py:0 -#, python-format -msgid "%s is not a number." -msgstr "%s n'est pas un nombre." - -#. module: mrp_production_split -#: model_terms:ir.ui.view,arch_db:mrp_production_split.message_order_split -msgid "" -"(s)\n" -" have been created as a result of a split operation:" -msgstr "" -"(s)\n" -" ont été créés à la suite d'une opération de split:" - -#. module: mrp_production_split -#: model_terms:ir.ui.view,arch_db:mrp_production_split.view_mrp_production_split_wizard_form -msgid "Apply" -msgstr "Appliquer" - -#. module: mrp_production_split -#: model_terms:ir.ui.view,arch_db:mrp_production_split.view_mrp_production_split_wizard_form -msgid "Cancel" -msgstr "Annuler" - -#. module: mrp_production_split -#: code:addons/mrp_production_split/models/mrp_production.py:0 -#, python-format -msgid "Cannot split a manufacturing order that is in '%s' state." -msgstr "Impossible de diviser un ordre de fabrication qui est à l'état '%s'." - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__create_uid -msgid "Created by" -msgstr "Créé par" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__create_date -msgid "Created on" -msgstr "Créé le" - -#. module: mrp_production_split -#: model:ir.model.fields.selection,name:mrp_production_split.selection__mrp_production_split_wizard__split_mode__custom -msgid "Custom" -msgstr "Personnalisé" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production__display_name -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__display_name -#: model:ir.model.fields,field_description:mrp_production_split.field_stock_move__display_name -msgid "Display Name" -msgstr "Nom affiché" - -#. module: mrp_production_split -#: model:ir.model.fields,help:mrp_production_split.field_mrp_production_split_wizard__product_tracking -msgid "Ensure the traceability of a storable product in your warehouse." -msgstr "Assurez la traçabilité d'un produit stockable dans votre entrepôt." - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__split_equal_qty -msgid "Equal Quantity" -msgstr "Quantité égale" - -#. module: mrp_production_split -#: model:ir.model.fields.selection,name:mrp_production_split.selection__mrp_production_split_wizard__split_mode__simple -msgid "Extract a quantity from the original MO" -msgstr "Extraire une quantité du MO d'origine" - -#. module: mrp_production_split -#: model:ir.model.fields.selection,name:mrp_production_split.selection__mrp_production_split_wizard__split_mode__equal -msgid "Extract a quantity into several MOs with equal quantities" -msgstr "Extraire une quantité en plusieurs MO de quantités égales" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production__id -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__id -#: model:ir.model.fields,field_description:mrp_production_split.field_stock_move__id -msgid "ID" -msgstr "ID" - -#. module: mrp_production_split -#: model_terms:ir.ui.view,arch_db:mrp_production_split.view_mrp_production_split_wizard_form -msgid "In orders of" -msgstr "Dans les commandes de" - -#. module: mrp_production_split -#: code:addons/mrp_production_split/wizards/mrp_production_split_wizard.py:0 -#, python-format -msgid "Invalid Split Mode: '%s'" -msgstr "Mode divisé non valide: '%s'" - -#. module: mrp_production_split -#: code:addons/mrp_production_split/wizards/mrp_production_split_wizard.py:0 -#, python-format -msgid "Invalid quantities" -msgstr "Quantités invalides" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production____last_update -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard____last_update -#: model:ir.model.fields,field_description:mrp_production_split.field_stock_move____last_update -msgid "Last Modified on" -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__write_uid -msgid "Last Updated by" -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__write_date -msgid "Last Updated on" -msgstr "" - -#. module: mrp_production_split -#: code:addons/mrp_production_split/wizards/mrp_production_split_wizard.py:0 -#, python-format -msgid "Nothing to split." -msgstr "Rien à diviser." - -#. module: mrp_production_split -#: code:addons/mrp_production_split/wizards/mrp_production_split_wizard.py:0 -#, python-format -msgid "Please enter a space separated list of numbers." -msgstr "Veuillez saisir une liste de chiffres séparés par des espaces." - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__product_uom_id -msgid "Product Unit of Measure" -msgstr "Unité de mesure du produit" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__production_id -msgid "Production" -msgstr "Production" - -#. module: mrp_production_split -#: model:ir.model,name:mrp_production_split.model_mrp_production -msgid "Production Order" -msgstr "Ordre de production" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__split_qty -msgid "Quantity" -msgstr "Quantité" - -#. module: mrp_production_split -#: model:ir.model.fields,help:mrp_production_split.field_mrp_production_split_wizard__custom_quantities -msgid "" -"Space separated list of quantities to split:\n" -"e.g. '3 2 5' will result in 3 MOs with 3, 2 and 5 units respectively.\n" -"If the sum of the quantities is less than the original MO's quantity, the remaining quantity will remain in the original MO." -msgstr "Liste des quantités séparées par des espaces à diviser:\n" -"par exemple. '3 2 5' donnera 3 mois avec respectivement 3, 2 et 5 unités.\n" -"Si la somme des quantités est inférieure à la quantité du MO d'origine, la quantité restante restera dans le MO d'origine." - -#. module: mrp_production_split -#: model_terms:ir.ui.view,arch_db:mrp_production_split.mrp_production_form_view -msgid "Split" -msgstr "Diviser" - -#. module: mrp_production_split -#: model:ir.actions.act_window,name:mrp_production_split.action_mrp_production_split_wizard -msgid "Split Manufacturing Order" -msgstr "Ordre de fabrication divisé" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__split_mode -msgid "Split Mode" -msgstr "Mode divisé" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__custom_quantities -msgid "Split Quantities" -msgstr "Quantités divisée" - -#. module: mrp_production_split -#: model:ir.model,name:mrp_production_split.model_stock_move -msgid "Stock Move" -msgstr "Mouvement de stock" - -#. module: mrp_production_split -#: model_terms:ir.ui.view,arch_db:mrp_production_split.message_order_split -msgid "The following" -msgstr "Ce qui suit" - -#. module: mrp_production_split -#: model:ir.model.fields,help:mrp_production_split.field_mrp_production_split_wizard__split_qty -msgid "Total quantity to extract from the original MO." -msgstr "Quantité totale à extraire du MO d'origine." - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__product_tracking -msgid "Tracking" -msgstr "Suivie" - -#. module: mrp_production_split -#: code:addons/mrp_production_split/models/mrp_production.py:0 -#, python-format -msgid "Unable to split with more than the quantity to produce." -msgstr "Impossible de diviser avec plus que la quantité à produire." - -#. module: mrp_production_split -#: model:ir.model.fields,help:mrp_production_split.field_mrp_production_split_wizard__split_equal_qty -msgid "Used to split the MO into several MOs with equal quantities." -msgstr "Utilisé pour diviser le MO en plusieurs MO avec des quantités égales." - -#. module: mrp_production_split -#: code:addons/mrp_production_split/wizards/mrp_production_split_wizard.py:0 -#, python-format -msgid "You can't split quantities already in production." -msgstr "Vous ne pouvez pas diviser des quantités déjà en production." - -#. module: mrp_production_split -#: model:ir.model,name:mrp_production_split.model_mrp_production_split_wizard -msgid "mrp.production.split.wizard" -msgstr "" diff --git a/mrp_production_split/i18n/it.po b/mrp_production_split/i18n/it.po deleted file mode 100644 index 332a1c8..0000000 --- a/mrp_production_split/i18n/it.po +++ /dev/null @@ -1,222 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * mrp_production_split -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 15.0\n" -"Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2023-05-09 13:37+0000\n" -"Last-Translator: mymage \n" -"Language-Team: none\n" -"Language: it\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.14.1\n" - -#. module: mrp_production_split -#: code:addons/mrp_production_split/wizards/mrp_production_split_wizard.py:0 -#, python-format -msgid "%s is not a number." -msgstr "%s non è un numero." - -#. module: mrp_production_split -#: model_terms:ir.ui.view,arch_db:mrp_production_split.message_order_split -msgid "" -"(s)\n" -" have been created as a result of a split operation:" -msgstr "" -"(s)\n" -" è stata creata come risultato di una operazione di " -"divisione:" - -#. module: mrp_production_split -#: model_terms:ir.ui.view,arch_db:mrp_production_split.view_mrp_production_split_wizard_form -msgid "Apply" -msgstr "Applica" - -#. module: mrp_production_split -#: model_terms:ir.ui.view,arch_db:mrp_production_split.view_mrp_production_split_wizard_form -msgid "Cancel" -msgstr "Annulla" - -#. module: mrp_production_split -#: code:addons/mrp_production_split/models/mrp_production.py:0 -#, python-format -msgid "Cannot split a manufacturing order that is in '%s' state." -msgstr "" -"Non si può dividere un ordine di produzione che si trova nello stato '%s'." - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__create_uid -msgid "Created by" -msgstr "Creato da" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__create_date -msgid "Created on" -msgstr "Creato il" - -#. module: mrp_production_split -#: model:ir.model.fields.selection,name:mrp_production_split.selection__mrp_production_split_wizard__split_mode__custom -msgid "Custom" -msgstr "Personalizzato" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__display_name -msgid "Display Name" -msgstr "Nome visualizzato" - -#. module: mrp_production_split -#: model:ir.model.fields,help:mrp_production_split.field_mrp_production_split_wizard__product_tracking -msgid "Ensure the traceability of a storable product in your warehouse." -msgstr "Assicura la tracciabilità di un prodotto stoccabile nel magazzino." - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__split_equal_qty -msgid "Equal Quantity" -msgstr "Quantità uguale" - -#. module: mrp_production_split -#: model:ir.model.fields.selection,name:mrp_production_split.selection__mrp_production_split_wizard__split_mode__simple -msgid "Extract a quantity from the original MO" -msgstr "Estrae una quantità dall'OP originale" - -#. module: mrp_production_split -#: model:ir.model.fields.selection,name:mrp_production_split.selection__mrp_production_split_wizard__split_mode__equal -msgid "Extract a quantity into several MOs with equal quantities" -msgstr "Estrae una quantità in diversi OP con quantità uguali" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__id -msgid "ID" -msgstr "ID" - -#. module: mrp_production_split -#: model_terms:ir.ui.view,arch_db:mrp_production_split.view_mrp_production_split_wizard_form -msgid "In orders of" -msgstr "In ordine di" - -#. module: mrp_production_split -#: code:addons/mrp_production_split/wizards/mrp_production_split_wizard.py:0 -#, python-format -msgid "Invalid Split Mode: '%s'" -msgstr "Metodo divisione non valido: '%s'" - -#. module: mrp_production_split -#: code:addons/mrp_production_split/wizards/mrp_production_split_wizard.py:0 -#, python-format -msgid "Invalid quantities" -msgstr "Quantità non valide" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard____last_update -msgid "Last Modified on" -msgstr "Ultima modifica il" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__write_uid -msgid "Last Updated by" -msgstr "Ultimo aggiornamento di" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__write_date -msgid "Last Updated on" -msgstr "Ultimo aggiornamento il" - -#. module: mrp_production_split -#: code:addons/mrp_production_split/wizards/mrp_production_split_wizard.py:0 -#, python-format -msgid "Nothing to split." -msgstr "Niente da dividere." - -#. module: mrp_production_split -#: code:addons/mrp_production_split/wizards/mrp_production_split_wizard.py:0 -#, python-format -msgid "Please enter a space separated list of numbers." -msgstr "Inserire un elenco di numeri separati da spazio." - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__product_uom_id -msgid "Product Unit of Measure" -msgstr "Unità di misura del prodotto" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__production_id -msgid "Production" -msgstr "Produzione" - -#. module: mrp_production_split -#: model:ir.model,name:mrp_production_split.model_mrp_production -msgid "Production Order" -msgstr "Ordine di produzione" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__split_qty -msgid "Quantity" -msgstr "Quantità" - -#. module: mrp_production_split -#: model:ir.model.fields,help:mrp_production_split.field_mrp_production_split_wizard__custom_quantities -msgid "" -"Space separated list of quantities to split:\n" -"e.g. '3 2 5' will result in 3 MOs with 3, 2 and 5 units respectively.\n" -"If the sum of the quantities is less than the original MO's quantity, the remaining quantity will remain in the original MO." -msgstr "" -"Elenco di quantità da separare separate da spazio:\n" -"es. '3 2 5' genererà 3 OP con 3, 2 e 5 unità rispettivamente.\n" -"Se la somme delle quantità è inferiore alla quantità dell'OP originale, la " -"quantità residua rimarrà nell'OP originale." - -#. module: mrp_production_split -#: model_terms:ir.ui.view,arch_db:mrp_production_split.mrp_production_form_view -msgid "Split" -msgstr "Dividi" - -#. module: mrp_production_split -#: model:ir.actions.act_window,name:mrp_production_split.action_mrp_production_split_wizard -msgid "Split Manufacturing Order" -msgstr "Dividi ordine di produzione" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__split_mode -msgid "Split Mode" -msgstr "Metodo di divisione" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__custom_quantities -msgid "Split Quantities" -msgstr "Dividi quantità" - -#. module: mrp_production_split -#: model_terms:ir.ui.view,arch_db:mrp_production_split.message_order_split -msgid "The following" -msgstr "Il seguente" - -#. module: mrp_production_split -#: model:ir.model.fields,help:mrp_production_split.field_mrp_production_split_wizard__split_qty -msgid "Total quantity to extract from the original MO." -msgstr "Quantità totale da estrarre dall'OP originale." - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__product_tracking -msgid "Tracking" -msgstr "Tracciamento" - -#. module: mrp_production_split -#: model:ir.model.fields,help:mrp_production_split.field_mrp_production_split_wizard__split_equal_qty -msgid "Used to split the MO into several MOs with equal quantities." -msgstr "Utilizzato per dividere l'OP in diversi OP con quantità uguali." - -#. module: mrp_production_split -#: code:addons/mrp_production_split/wizards/mrp_production_split_wizard.py:0 -#, python-format -msgid "You can't split quantities already in production." -msgstr "Non si può dividere una quantità già in produzione." - -#. module: mrp_production_split -#: model:ir.model,name:mrp_production_split.model_mrp_production_split_wizard -msgid "mrp.production.split.wizard" -msgstr "mrp.production.split.wizard" diff --git a/mrp_production_split/i18n/mrp_production_split.pot b/mrp_production_split/i18n/mrp_production_split.pot deleted file mode 100644 index ede660b..0000000 --- a/mrp_production_split/i18n/mrp_production_split.pot +++ /dev/null @@ -1,211 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * mrp_production_split -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 15.0\n" -"Report-Msgid-Bugs-To: \n" -"Last-Translator: \n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: \n" - -#. module: mrp_production_split -#: code:addons/mrp_production_split/wizards/mrp_production_split_wizard.py:0 -#, python-format -msgid "%s is not a number." -msgstr "" - -#. module: mrp_production_split -#: model_terms:ir.ui.view,arch_db:mrp_production_split.message_order_split -msgid "" -"(s)\n" -" have been created as a result of a split operation:" -msgstr "" - -#. module: mrp_production_split -#: model_terms:ir.ui.view,arch_db:mrp_production_split.view_mrp_production_split_wizard_form -msgid "Apply" -msgstr "" - -#. module: mrp_production_split -#: model_terms:ir.ui.view,arch_db:mrp_production_split.view_mrp_production_split_wizard_form -msgid "Cancel" -msgstr "" - -#. module: mrp_production_split -#: code:addons/mrp_production_split/models/mrp_production.py:0 -#, python-format -msgid "Cannot split a manufacturing order that is in '%s' state." -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__create_uid -msgid "Created by" -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__create_date -msgid "Created on" -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields.selection,name:mrp_production_split.selection__mrp_production_split_wizard__split_mode__custom -msgid "Custom" -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__display_name -msgid "Display Name" -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields,help:mrp_production_split.field_mrp_production_split_wizard__product_tracking -msgid "Ensure the traceability of a storable product in your warehouse." -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__split_equal_qty -msgid "Equal Quantity" -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields.selection,name:mrp_production_split.selection__mrp_production_split_wizard__split_mode__simple -msgid "Extract a quantity from the original MO" -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields.selection,name:mrp_production_split.selection__mrp_production_split_wizard__split_mode__equal -msgid "Extract a quantity into several MOs with equal quantities" -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__id -msgid "ID" -msgstr "" - -#. module: mrp_production_split -#: model_terms:ir.ui.view,arch_db:mrp_production_split.view_mrp_production_split_wizard_form -msgid "In orders of" -msgstr "" - -#. module: mrp_production_split -#: code:addons/mrp_production_split/wizards/mrp_production_split_wizard.py:0 -#, python-format -msgid "Invalid Split Mode: '%s'" -msgstr "" - -#. module: mrp_production_split -#: code:addons/mrp_production_split/wizards/mrp_production_split_wizard.py:0 -#, python-format -msgid "Invalid quantities" -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard____last_update -msgid "Last Modified on" -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__write_uid -msgid "Last Updated by" -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__write_date -msgid "Last Updated on" -msgstr "" - -#. module: mrp_production_split -#: code:addons/mrp_production_split/wizards/mrp_production_split_wizard.py:0 -#, python-format -msgid "Nothing to split." -msgstr "" - -#. module: mrp_production_split -#: code:addons/mrp_production_split/wizards/mrp_production_split_wizard.py:0 -#, python-format -msgid "Please enter a space separated list of numbers." -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__product_uom_id -msgid "Product Unit of Measure" -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__production_id -msgid "Production" -msgstr "" - -#. module: mrp_production_split -#: model:ir.model,name:mrp_production_split.model_mrp_production -msgid "Production Order" -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__split_qty -msgid "Quantity" -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields,help:mrp_production_split.field_mrp_production_split_wizard__custom_quantities -msgid "" -"Space separated list of quantities to split:\n" -"e.g. '3 2 5' will result in 3 MOs with 3, 2 and 5 units respectively.\n" -"If the sum of the quantities is less than the original MO's quantity, the remaining quantity will remain in the original MO." -msgstr "" - -#. module: mrp_production_split -#: model_terms:ir.ui.view,arch_db:mrp_production_split.mrp_production_form_view -msgid "Split" -msgstr "" - -#. module: mrp_production_split -#: model:ir.actions.act_window,name:mrp_production_split.action_mrp_production_split_wizard -msgid "Split Manufacturing Order" -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__split_mode -msgid "Split Mode" -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__custom_quantities -msgid "Split Quantities" -msgstr "" - -#. module: mrp_production_split -#: model_terms:ir.ui.view,arch_db:mrp_production_split.message_order_split -msgid "The following" -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields,help:mrp_production_split.field_mrp_production_split_wizard__split_qty -msgid "Total quantity to extract from the original MO." -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields,field_description:mrp_production_split.field_mrp_production_split_wizard__product_tracking -msgid "Tracking" -msgstr "" - -#. module: mrp_production_split -#: model:ir.model.fields,help:mrp_production_split.field_mrp_production_split_wizard__split_equal_qty -msgid "Used to split the MO into several MOs with equal quantities." -msgstr "" - -#. module: mrp_production_split -#: code:addons/mrp_production_split/wizards/mrp_production_split_wizard.py:0 -#, python-format -msgid "You can't split quantities already in production." -msgstr "" - -#. module: mrp_production_split -#: model:ir.model,name:mrp_production_split.model_mrp_production_split_wizard -msgid "mrp.production.split.wizard" -msgstr "" diff --git a/mrp_production_split/models/__init__.py b/mrp_production_split/models/__init__.py deleted file mode 100644 index 0dbd346..0000000 --- a/mrp_production_split/models/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from . import mrp_production -from . import stock_move diff --git a/mrp_production_split/models/mrp_production.py b/mrp_production_split/models/mrp_production.py deleted file mode 100644 index cc0a2f6..0000000 --- a/mrp_production_split/models/mrp_production.py +++ /dev/null @@ -1,407 +0,0 @@ -# Copyright 2023 Camptocamp SA (https://www.camptocamp.com). -# @author Iván Todorovich -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). - -from collections import defaultdict -from odoo import _, models -from odoo.exceptions import UserError -from odoo.tools.misc import OrderedSet -from odoo.tools.float_utils import float_compare, float_is_zero - - -class MrpProduction(models.Model): - _inherit = "mrp.production" - - def copy_data(self, default=None): - # OVERRIDE copy the date_planned_start and date_planned_end when splitting - # productions, as they are not copied by default (copy=False). - [data] = super().copy_data(default=default) - data.setdefault("date_planned_start", self.date_planned_start) - data.setdefault("date_planned_finished", self.date_planned_finished) - return [data] - - def action_split(self): - self.ensure_one() - self._check_company() - if self.state in ("draft", "done", "to_close", "cancel"): - raise UserError( - _( - "Cannot split a manufacturing order that is in '%s' state.", - self._fields["state"].convert_to_export(self.state, self), - ) - ) - action = self.env["ir.actions.actions"]._for_xml_id( - "mrp_production_split.action_mrp_production_split_wizard" - ) - action["context"] = {"default_production_id": self.id} - return action - - def _create_backorder( - self, initial_qty_by_production, amounts, backorder_vals_list - ): - for production in self: - initial_qty_by_production[production] = production.product_qty - if production.backorder_sequence == 0: # Activate backorder naming - production.backorder_sequence = 1 - production.name = self._get_name_backorder( - production.name, production.backorder_sequence - ) - production.product_qty = amounts[production][0] - backorder_vals = production.copy_data( - default=production._get_backorder_mo_vals() - )[0] - backorder_qtys = amounts[production][1:] - - next_seq = max( - production.procurement_group_id.mrp_production_ids.mapped( - "backorder_sequence" - ), - default=1, - ) - - for qty_to_backorder in backorder_qtys: - next_seq += 1 - backorder_vals_list.append( - dict( - backorder_vals, - product_qty=qty_to_backorder, - name=production._get_name_backorder(production.name, next_seq), - backorder_sequence=next_seq, - state="confirmed", - ) - ) - return initial_qty_by_production, backorder_vals_list - - def _handle_production_amount(self, amounts, _default_amounts, cancel_remaning_qty): - for production in self: - mo_amounts = amounts.get(production) - if not mo_amounts: - amounts[production] = _default_amounts(production) - continue - total_amount = sum(mo_amounts) - diff = float_compare( - production.product_qty, - total_amount, - precision_rounding=production.product_uom_id.rounding, - ) - if diff > 0 and not cancel_remaning_qty: - amounts[production].append(production.product_qty - total_amount) - elif diff < 0 or production.state in ["done", "cancel"]: - raise UserError( - _("Unable to split with more than the quantity to produce.") - ) - return amounts - - def _handle_production_to_backorders( - self, - amounts, - _default_amounts, - backorders, - index, - production_to_backorders, - production_ids, - ): - for production in self: - number_of_backorder_created = ( - len(amounts.get(production, _default_amounts(production))) - 1 - ) - production_backorders = backorders[ - index : index + number_of_backorder_created - ] - production_to_backorders[production] = production_backorders - production_ids.add(production.id) # previously update - for production_backorder in production_backorders: - production_ids.add(production_backorder.id) # previously update - index += number_of_backorder_created - return index, production_to_backorders, production_ids - - def _process_stock_moves( - self, - new_moves_vals, - moves, - production_to_backorders, - initial_qty_by_production, - ): - for production in self: - for move in production.move_raw_ids | production.move_finished_ids: - if move.additional: - continue - unit_factor = ( - move.product_uom_qty / initial_qty_by_production[production] - ) - initial_move_vals = move.copy_data(move._get_backorder_move_vals())[0] - move.with_context(do_not_unreserve=True).product_uom_qty = ( - production.product_qty * unit_factor - ) - - for backorder in production_to_backorders[production]: - move_vals = dict( - initial_move_vals, - product_uom_qty=backorder.product_qty * unit_factor, - ) - if move.raw_material_production_id: - move_vals["raw_material_production_id"] = backorder.id - else: - move_vals["production_id"] = backorder.id - new_moves_vals.append(move_vals) - moves.append(move) - return new_moves_vals, moves - - def _process_backorder_move_lines( - self, - move_lines_vals, - set_consumed_qty, - move_to_backorder_moves, - assigned_moves, - partially_assigned_moves, - move_lines_to_unlink, - ): - for initial_move, backorder_moves in move_to_backorder_moves.items(): - ml_by_move = [] - product_uom = initial_move.product_id.uom_id - for move_line in initial_move.move_line_ids: - available_qty = move_line.product_uom_id._compute_quantity( - move_line.product_uom_qty, product_uom - ) - if ( - float_compare( - available_qty, - 0, - precision_rounding=move_line.product_uom_id.rounding, - ) - <= 0 - ): - continue - ml_by_move.append((available_qty, move_line, move_line.copy_data()[0])) - - initial_move.move_line_ids.with_context( - bypass_reservation_update=True - ).write({"product_uom_qty": 0}) - moves = list(initial_move | backorder_moves) - - move = moves and moves.pop(0) - move_qty_to_reserve = move.product_qty - for quantity, move_line, ml_vals in ml_by_move: - while ( - float_compare(quantity, 0, precision_rounding=product_uom.rounding) - > 0 - and move - ): - # Do not create `stock.move.line` if there is no initial demand - # on `stock.move` - taken_qty = min(move_qty_to_reserve, quantity) - taken_qty_uom = product_uom._compute_quantity( - taken_qty, move_line.product_uom_id - ) - if move == initial_move: - move_line.with_context( - bypass_reservation_update=True - ).product_uom_qty = taken_qty_uom - if set_consumed_qty: - move_line.qty_done = taken_qty_uom - elif not float_is_zero( - taken_qty_uom, - precision_rounding=move_line.product_uom_id.rounding, - ): - new_ml_vals = dict( - ml_vals, product_uom_qty=taken_qty_uom, move_id=move.id - ) - if set_consumed_qty: - new_ml_vals["qty_done"] = taken_qty_uom - move_lines_vals.append(new_ml_vals) - quantity -= taken_qty - move_qty_to_reserve -= taken_qty - - if ( - float_compare( - move_qty_to_reserve, - 0, - precision_rounding=move.product_uom.rounding, - ) - <= 0 - ): - assigned_moves.add(move.id) - move = moves and moves.pop(0) - move_qty_to_reserve = move and move.product_qty or 0 - - # Unreserve the quantity removed from initial `stock.move.line` and - # not assigned to a move anymore. In case of a split smaller than - # initial quantity and fully reserved - if quantity: - self.env["stock.quant"]._update_reserved_quantity( - move_line.product_id, - move_line.location_id, - -quantity, - lot_id=move_line.lot_id, - package_id=move_line.package_id, - owner_id=move_line.owner_id, - strict=True, - ) - - if move and move_qty_to_reserve != move.product_qty: - partially_assigned_moves.add(move.id) - - move_lines_to_unlink.update( - initial_move.move_line_ids.filtered( - lambda ml: not ml.product_uom_qty and not ml.qty_done - ).ids - ) - return ( - move_lines_vals, - move_lines_to_unlink, - assigned_moves, - partially_assigned_moves, - ) - - def _process_adaptation_of_workorders( - self, initial_qty_by_production, production_to_backorders - ): - for production in self: - initial_qty = initial_qty_by_production[production] - initial_workorder_remaining_qty = [] - bo = production_to_backorders[production] - - # Adapt duration - for workorder in (production | bo).workorder_ids: - workorder.duration_expected = ( - workorder.duration_expected - * workorder.production_id.product_qty - / initial_qty - ) - - # Adapt quantities produced - for workorder in production.workorder_ids: - initial_workorder_remaining_qty.append( - max(workorder.qty_produced - workorder.qty_production, 0) - ) - workorder.qty_produced = min( - workorder.qty_produced, workorder.qty_production - ) - workorders_len = len(bo.workorder_ids) - for index, workorder in enumerate(bo.workorder_ids): - remaining_qty = initial_workorder_remaining_qty[index // workorders_len] - if remaining_qty: - workorder.qty_produced = max( - workorder.qty_production, remaining_qty - ) - initial_workorder_remaining_qty[index % workorders_len] = max( - remaining_qty - workorder.qty_produced, 0 - ) - - def _split_productions( - self, amounts=False, cancel_remaning_qty=False, set_consumed_qty=False - ): - """Splits productions into productions smaller quantities to produce, i.e. - creates its backorders. - :param dict amounts: a dict with a production as key and a list value containing - the amounts each production split should produce including the original - production, - e.g. {mrp.production(1,): [3, 2]} will result in mrp.production(1,) - having a product_qty=3 and a new backorder with product_qty=2. - :return: mrp.production records in order of [orig_prod_1, backorder_prod_1, - backorder_prod_2, orig_prod_2, backorder_prod_2, etc.] - """ - - def _default_amounts(production): - return [production.qty_producing, production._get_quantity_to_backorder()] - - if not amounts: - amounts = {} - - # Handle production amount computation - amounts = self._handle_production_amount( - amounts, _default_amounts, cancel_remaning_qty - ) - - backorder_vals_list = [] - initial_qty_by_production = {} - - # Create the backorders. - initial_qty_by_production, backorder_vals_list = self._create_backorder( - initial_qty_by_production, amounts, backorder_vals_list - ) - - backorders = ( - self.env["mrp.production"] - .with_context(skip_confirm=True) - .create(backorder_vals_list) - ) - - index = 0 - production_to_backorders = {} - production_ids = OrderedSet() - - # Handling the backorders - index, production_to_backorders, production_ids = ( - self._handle_production_to_backorders( - amounts, - _default_amounts, - backorders, - index, - production_to_backorders, - production_ids, - ) - ) - - # Split the `stock.move` among new backorders. - new_moves_vals = [] - moves = [] - new_moves_vals, moves = self._process_stock_moves( - new_moves_vals, moves, production_to_backorders, initial_qty_by_production - ) - - backorder_moves = self.env["stock.move"].create(new_moves_vals) - # Split `stock.move.line`s. 2 options for this: - # - do_unreserve -> action_assign - # - Split the reserved amounts manually - # The first option would be easier to maintain since it's less code - # However it could be slower (due to `stock.quant` update) and could - # create inconsistencies in mass production if a new lot higher in a - # FIFO strategy arrives between the reservation and the backorder creation - move_to_backorder_moves = defaultdict(lambda: self.env["stock.move"]) - for move, backorder_move in zip(moves, backorder_moves): - move_to_backorder_moves[move] |= backorder_move - - move_lines_vals = [] - assigned_moves = set() - partially_assigned_moves = set() - move_lines_to_unlink = set() - - # Process backorder move lines - ( - move_lines_vals, - move_lines_to_unlink, - assigned_moves, - partially_assigned_moves, - ) = self._process_backorder_move_lines( - move_lines_vals, - set_consumed_qty, - move_to_backorder_moves, - assigned_moves, - partially_assigned_moves, - move_lines_to_unlink, - ) - - self.env["stock.move"].browse(assigned_moves).write({"state": "assigned"}) - self.env["stock.move"].browse(partially_assigned_moves).write( - {"state": "partially_available"} - ) - # Avoid triggering a useless _recompute_state - self.env["stock.move.line"].browse(move_lines_to_unlink).write( - {"move_id": False} - ) - self.env["stock.move.line"].browse(move_lines_to_unlink).unlink() - self.env["stock.move.line"].create(move_lines_vals) - - # We need to adapt `duration_expected` on both the original workorders and their - # backordered workorders. To do that, we use the original `duration_expected` - # and the ratio of the quantity produced and the quantity to produce. - self._process_adaptation_of_workorders( - initial_qty_by_production, production_to_backorders - ) - - backorders._action_confirm_mo_backorders() - return self.env["mrp.production"].browse(production_ids) - - def _action_confirm_mo_backorders(self): - self.workorder_ids._action_confirm() diff --git a/mrp_production_split/models/stock_move.py b/mrp_production_split/models/stock_move.py deleted file mode 100644 index 3f2203b..0000000 --- a/mrp_production_split/models/stock_move.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2023 Camptocamp SA (https://www.camptocamp.com). -# @author Iván Todorovich -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). - -from odoo import models - - -class StockMove(models.Model): - _inherit = "stock.move" - - def _get_backorder_move_vals(self): - self.ensure_one() - return { - 'state': 'confirmed', - # 'reservation_date': self.reservation_date, - 'move_orig_ids': [(4, m.id) for m in self.mapped('move_orig_ids')], - 'move_dest_ids': [(4, m.id) for m in self.mapped('move_dest_ids')] - } diff --git a/mrp_production_split/readme/CONTRIBUTORS.rst b/mrp_production_split/readme/CONTRIBUTORS.rst deleted file mode 100644 index a1e0a83..0000000 --- a/mrp_production_split/readme/CONTRIBUTORS.rst +++ /dev/null @@ -1,3 +0,0 @@ -* `Camptocamp `_ - - * Iván Todorovich diff --git a/mrp_production_split/readme/DESCRIPTION.rst b/mrp_production_split/readme/DESCRIPTION.rst deleted file mode 100644 index 26ff021..0000000 --- a/mrp_production_split/readme/DESCRIPTION.rst +++ /dev/null @@ -1,12 +0,0 @@ -This module adds a "Split" button to Manufacturing Orders. - -Manufacturing Orders can be split as long as they haven't been completed yet. - -For products tracked by "Serial Number", it allows to choose the Quantity to extract -from the original MO, and it'll create one MO per single unit. - -For other products, more options are available, that will let you do things like: - -* Extract 10 units from a MO into 5 MOs of 2 units each. -* Extract 10 units from a MO into a single new MOs. -* Extract 10 units from a MO into multiple MOs of different quantities. diff --git a/mrp_production_split/readme/USAGE.rst b/mrp_production_split/readme/USAGE.rst deleted file mode 100644 index 84ac9e3..0000000 --- a/mrp_production_split/readme/USAGE.rst +++ /dev/null @@ -1,5 +0,0 @@ -#. Create a Manufacturing Order. -#. Confirm it. -#. Click on the "Split" button. -#. Choose the desired split options. -#. Confirm. diff --git a/mrp_production_split/security/ir.model.access.csv b/mrp_production_split/security/ir.model.access.csv deleted file mode 100644 index 21624df..0000000 --- a/mrp_production_split/security/ir.model.access.csv +++ /dev/null @@ -1,2 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_mrp_production_split_wizard,access.mrp.production.split.wizard,model_mrp_production_split_wizard,mrp.group_mrp_user,1,1,1,1 diff --git a/mrp_production_split/static/description/icon.png b/mrp_production_split/static/description/icon.png deleted file mode 100644 index 3a0328b..0000000 Binary files a/mrp_production_split/static/description/icon.png and /dev/null differ diff --git a/mrp_production_split/static/description/index.html b/mrp_production_split/static/description/index.html deleted file mode 100644 index 0eb1a5a..0000000 --- a/mrp_production_split/static/description/index.html +++ /dev/null @@ -1,444 +0,0 @@ - - - - - - -MRP Production Split - - - -
-

MRP Production Split

- - -

Beta License: AGPL-3 OCA/manufacture Translate me on Weblate Try me on Runbot

-

This module adds a “Split” button to Manufacturing Orders.

-

Manufacturing Orders can be split as long as they haven’t been completed yet.

-

For products tracked by “Serial Number”, it allows to choose the Quantity to extract -from the original MO, and it’ll create one MO per single unit.

-

For other products, more options are available, that will let you do things like:

-
    -
  • Extract 10 units from a MO into 5 MOs of 2 units each.
  • -
  • Extract 10 units from a MO into a single new MOs.
  • -
  • Extract 10 units from a MO into multiple MOs of different quantities.
  • -
-

Table of contents

- -
-

Usage

-
    -
  1. Create a Manufacturing Order.
  2. -
  3. Confirm it.
  4. -
  5. Click on the “Split” button.
  6. -
  7. Choose the desired split options.
  8. -
  9. Confirm.
  10. -
-
-
-

Bug Tracker

-

Bugs are tracked on GitHub Issues. -In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed -feedback.

-

Do not contact contributors directly about support or help with technical issues.

-
-
-

Credits

-
-

Authors

-
    -
  • Camptocamp
  • -
-
-
-

Contributors

- -
-
-

Maintainers

-

This module is maintained by the OCA.

-Odoo Community Association -

OCA, or the Odoo Community Association, is a nonprofit organization whose -mission is to support the collaborative development of Odoo features and -promote its widespread use.

-

Current maintainer:

-

ivantodorovich

-

This module is part of the OCA/manufacture project on GitHub.

-

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

-
-
-
- - diff --git a/mrp_production_split/templates/messages.xml b/mrp_production_split/templates/messages.xml deleted file mode 100644 index 5e67a8b..0000000 --- a/mrp_production_split/templates/messages.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - diff --git a/mrp_production_split/tests/__init__.py b/mrp_production_split/tests/__init__.py deleted file mode 100644 index 8770560..0000000 --- a/mrp_production_split/tests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import test_mrp_production_split diff --git a/mrp_production_split/tests/common.py b/mrp_production_split/tests/common.py deleted file mode 100644 index b64edee..0000000 --- a/mrp_production_split/tests/common.py +++ /dev/null @@ -1,90 +0,0 @@ -# Copyright 2023 Camptocamp SA (https://www.camptocamp.com). -# @author Iván Todorovich -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). - -from odoo.tests import Form, SavepointCase - - -class CommonCase(SavepointCase): - @classmethod - def setUpClass(cls): - super().setUpClass() - cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) - # Create bom, product and components - cls.component = cls.env["product.product"].create( - { - "name": "Component", - "type": "product", - } - ) - cls.product = cls.env["product.product"].create( - { - "name": "Product", - "type": "product", - "tracking": "lot", - } - ) - cls.product_bom = cls.env["mrp.bom"].create( - { - "product_tmpl_id": cls.product.product_tmpl_id.id, - "product_qty": 1.0, - "product_uom_id": cls.product.uom_id.id, - "bom_line_ids": [ - (0, 0, { - "product_id": cls.component.id, - "product_qty": 1.0, - "product_uom_id": cls.component.uom_id.id, - }) - ], - } - ) - # Create some initial stocks - cls.location_stock = cls.env.ref("stock.stock_location_stock") - cls.env["stock.quant"].create( - { - "product_id": cls.component.id, - "product_uom_id": cls.component.uom_id.id, - "location_id": cls.location_stock.id, - "quantity": 10.00, - } - ) - # Create the MO - cls.production = cls._create_mrp_production( - product=cls.product, - bom=cls.product_bom, - ) - - @classmethod - def _create_mrp_production( - cls, product=None, bom=None, quantity=5.0, confirm=False - ): - if product is None: # pragma: no cover - product = cls.product - if bom is None: # pragma: no cover - bom = cls.product_bom - mo_form = Form(cls.env["mrp.production"]) - mo_form.product_id = product - mo_form.bom_id = bom - mo_form.product_qty = quantity - mo_form.product_uom_id = product.uom_id - mo = mo_form.save() - if confirm: # pragma: no cover - mo.action_confirm() - return mo - - def _mrp_production_set_quantity_done(self, order): - for line in order.move_raw_ids.move_line_ids: - line.qty_done = line.product_uom_qty - order.move_raw_ids._recompute_state() - order.qty_producing = order.product_qty - - def _mrp_production_split(self, order, **vals): - action = order.action_split() - Wizard = self.env[action["res_model"]] - Wizard = Wizard.with_context( - active_model=order._name, active_id=order.id) - Wizard = Wizard.with_context(**action["context"]) - wizard = Wizard.create(vals) - res = wizard.apply() - records = self.env[res["res_model"]].search(res["domain"]) - return records diff --git a/mrp_production_split/tests/test_mrp_production_split.py b/mrp_production_split/tests/test_mrp_production_split.py deleted file mode 100644 index 9169316..0000000 --- a/mrp_production_split/tests/test_mrp_production_split.py +++ /dev/null @@ -1,178 +0,0 @@ -# Copyright 2023 Camptocamp SA (https://www.camptocamp.com). -# @author Iván Todorovich -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). - -from datetime import datetime, timedelta - -from odoo.exceptions import UserError - -from .common import CommonCase - - -class TestMrpProductionSplit(CommonCase): - def test_mrp_production_split_draft(self): - with self.assertRaisesRegex(UserError, r"Cannot split.*"): - self._mrp_production_split(self.production) - - # def test_mrp_production_split_done(self): - # self.production.action_confirm() - # self.production.action_generate_serial() - # self._mrp_production_set_quantity_done(self.production) - # self.production.button_mark_done() - # with self.assertRaisesRegex(UserError, r"Cannot split.*"): - # self._mrp_production_split(self.production) - - def test_mrp_production_split_cancel(self): - self.production.action_cancel() - with self.assertRaisesRegex(UserError, r"Cannot split.*"): - self._mrp_production_split(self.production) - - def test_mrp_production_split_lot_simple(self): - self.production.action_confirm() - self.production.action_generate_serial() - mos = self._mrp_production_split(self.production, split_qty=2.0) - self.assertRecordValues(mos, [dict(product_qty=3.0), dict(product_qty=2.0)]) - - def test_mrp_production_split_lot_simple_copy_date_planned(self): - dt_start = datetime.now() + timedelta(days=5) - dt_finished = dt_start + timedelta(hours=1) - self.production.date_planned_start = dt_start - self.production.date_planned_finished = dt_finished - self.production.action_confirm() - self.production.action_generate_serial() - mos = self._mrp_production_split(self.production, split_qty=2.0) - self.assertRecordValues( - mos, - [ - dict( - product_qty=3.0, - date_planned_start=dt_start, - date_planned_finished=dt_finished, - ), - dict( - product_qty=2.0, - date_planned_start=dt_start, - date_planned_finished=dt_finished, - ), - ], - ) - - def test_mrp_production_split_lot_simple_zero_qty(self): - self.production.action_confirm() - self.production.action_generate_serial() - with self.assertRaisesRegex(UserError, r"Nothing to split.*"): - self._mrp_production_split(self.production, split_qty=0.0) - - def test_mrp_production_split_lot_simple_with_qty_producing_exceeded(self): - self.production.action_confirm() - self.production.action_generate_serial() - self.production.qty_producing = 3.0 - with self.assertRaisesRegex(UserError, r"You can't split.*"): - self._mrp_production_split(self.production, split_qty=4.0) - - def test_mrp_production_split_lot_equal(self): - self.production.action_confirm() - self.production.action_generate_serial() - mos = self._mrp_production_split( - self.production, - split_mode="equal", - split_qty=4.0, - split_equal_qty=2.0, - ) - self.assertRecordValues( - mos, - [ - dict(product_qty=1.0), - dict(product_qty=2.0), - dict(product_qty=2.0), - ], - ) - - def test_mrp_production_split_lot_custom(self): - self.production.action_confirm() - self.production.action_generate_serial() - mos = self._mrp_production_split( - self.production, - split_mode="custom", - custom_quantities="1 2 1 1", - ) - self.assertRecordValues( - mos, - [ - dict(product_qty=1.0), - dict(product_qty=2.0), - dict(product_qty=1.0), - dict(product_qty=1.0), - ], - ) - - def test_mrp_production_split_lot_custom_incomplete(self): - self.production.action_confirm() - self.production.action_generate_serial() - mos = self._mrp_production_split( - self.production, - split_mode="custom", - custom_quantities="1 2", - ) - self.assertRecordValues( - mos, - [ - dict(product_qty=2.0), - dict(product_qty=1.0), - dict(product_qty=2.0), - ], - ) - - def test_mrp_production_split_lot_custom_float(self): - self.production.action_confirm() - self.production.action_generate_serial() - mos = self._mrp_production_split( - self.production, - split_mode="custom", - custom_quantities="1.0 2.0 1.0 1.0", - ) - self.assertRecordValues( - mos, - [ - dict(product_qty=1.0), - dict(product_qty=2.0), - dict(product_qty=1.0), - dict(product_qty=1.0), - ], - ) - - def test_mrp_production_split_lot_custom_float_locale(self): - lang = self.env["res.lang"]._lang_get(self.env.user.lang) - lang.decimal_point = "," - lang.thousands_sep = "" - self.production.action_confirm() - self.production.action_generate_serial() - mos = self._mrp_production_split( - self.production, - split_mode="custom", - custom_quantities="1,0 2,0 1,0 1,0", - ) - self.assertRecordValues( - mos, - [ - dict(product_qty=1.0), - dict(product_qty=2.0), - dict(product_qty=1.0), - dict(product_qty=1.0), - ], - ) - - def test_mrp_production_split_serial(self): - self.product.tracking = "serial" - self.production.action_confirm() - mos = self._mrp_production_split(self.production) - self.assertRecordValues( - mos, - [ - dict(product_qty=1.0), - dict(product_qty=1.0), - dict(product_qty=1.0), - dict(product_qty=1.0), - dict(product_qty=1.0), - ], - ) diff --git a/mrp_production_split/views/mrp_production.xml b/mrp_production_split/views/mrp_production.xml deleted file mode 100644 index 71d4aca..0000000 --- a/mrp_production_split/views/mrp_production.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - mrp.production - - - - - - - diff --git a/mrp_production_split/wizards/__init__.py b/mrp_production_split/wizards/__init__.py deleted file mode 100644 index c27c5fd..0000000 --- a/mrp_production_split/wizards/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import mrp_production_split_wizard diff --git a/mrp_production_split/wizards/mrp_production_split_wizard.py b/mrp_production_split/wizards/mrp_production_split_wizard.py deleted file mode 100644 index d560ec8..0000000 --- a/mrp_production_split/wizards/mrp_production_split_wizard.py +++ /dev/null @@ -1,165 +0,0 @@ -# Copyright 2023 Camptocamp SA (https://www.camptocamp.com). -# @author Iván Todorovich -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). - -from typing import List, Union - -from odoo import _, api, fields, models -from odoo.exceptions import UserError - - -class MrpProductionSplitWizard(models.TransientModel): - _name = "mrp.production.split.wizard" - - production_id = fields.Many2one( - "mrp.production", - "Production", - required=True, - ondelete="cascade", - ) - split_mode = fields.Selection( - [ - ("simple", "Extract a quantity from the original MO"), - ("equal", "Extract a quantity into several MOs with equal quantities"), - ("custom", "Custom"), - ], - required=True, - default="simple", - ) - split_qty = fields.Float( - string="Quantity", - digits="Product Unit of Measure", - help="Total quantity to extract from the original MO.", - ) - split_equal_qty = fields.Float( - string="Equal Quantity", - digits="Product Unit of Measure", - help="Used to split the MO into several MOs with equal quantities.", - default=1, - ) - custom_quantities = fields.Char( - string="Split Quantities", - help="Space separated list of quantities to split:\n" - "e.g. '3 2 5' will result in 3 MOs with 3, 2 and 5 units respectively.\n" - "If the sum of the quantities is less than the original MO's quantity, the " - "remaining quantity will remain in the original MO.", - ) - product_tracking = fields.Selection(related="production_id.product_id.tracking") - product_uom_id = fields.Many2one(related="production_id.product_uom_id") - - @api.model - def default_get(self, fields_list): - res = super().default_get(fields_list) - active_model = self.env.context.get("active_model") - active_id = self.env.context.get("active_id") - # Auto-complete production_id from context - if "production_id" in fields_list and active_model == "mrp.production": - res["production_id"] = active_id - # Auto-complete split_mode from production_id - if "split_mode" in fields_list and res.get("production_id"): - production = self.env["mrp.production"].browse(res["production_id"]) - if production.product_tracking == "serial": - res["split_mode"] = "equal" - # Auto-complete split_qty from production_id - if "split_qty" in fields_list and res.get("production_id"): - production = self.env["mrp.production"].browse(res["production_id"]) - res["split_qty"] = production._get_quantity_to_backorder() - return res - - @api.model - def _parse_float(self, value: Union[float, int, str]) -> float: - """Parse a float number from a string, with the user's language settings.""" - if isinstance(value, (float, int)): # pragma: no cover - return float(value) - lang = self.env["res.lang"]._lang_get(self.env.user.lang) - try: - return float( - value.replace(lang.thousands_sep, "") - .replace(lang.decimal_point, ".") - .strip() - ) - except ValueError as e: # pragma: no cover - raise UserError(_("%s is not a number.", value)) from e - - @api.model - def _parse_float_list(self, value: str) -> List[float]: - """Parse a list of float numbers from a string.""" - return [self._parse_float(v) for v in value.split()] - - @api.onchange("custom_quantities") - def _onchange_custom_quantities_check(self): - """Check that the custom quantities are valid.""" - if self.custom_quantities: # pragma: no cover - try: - self._parse_float_list(self.custom_quantities) - except UserError: - return { - "warning": { - "title": _("Invalid quantities"), - "message": _("Please enter a space separated list of numbers."), - } - } - - def _get_split_quantities(self) -> List[float]: - """Return the quantities to split, according to the settings.""" - production = self.production_id - rounding = production.product_uom_id.rounding - if self.split_mode == "simple": - if ( - fields.Float.compare( - self.split_qty, production._get_quantity_to_backorder(), rounding - ) - > 0 - ): - raise UserError(_("You can't split quantities already in production.")) - if fields.Float.is_zero(self.split_qty, precision_rounding=rounding): - raise UserError(_("Nothing to split.")) - return [production.product_qty - self.split_qty, self.split_qty] - elif self.split_mode == "equal": - split_total = min(production._get_quantity_to_backorder(), self.split_qty) - split_count = int(split_total // self.split_equal_qty) - split_rest = production.product_qty - split_total - split_rest += split_total % self.split_equal_qty - quantities = [self.split_equal_qty] * split_count - if not fields.Float.is_zero(split_rest, precision_rounding=rounding): - quantities = [split_rest] + quantities - return quantities - elif self.split_mode == "custom": - quantities = self._parse_float_list(self.custom_quantities) - split_total = sum(quantities) - split_rest = production.product_qty - split_total - if not fields.Float.is_zero(split_rest, precision_rounding=rounding): - quantities = [split_rest] + quantities - return quantities - else: # pragma: no cover - raise UserError(_("Invalid Split Mode: '%s'", self.split_mode)) - - def _apply(self): - self.ensure_one() - records = self.production_id.with_context( - copy_date_planned=True - )._split_productions( - amounts={self.production_id: self._get_split_quantities()}, - cancel_remaning_qty=False, - set_consumed_qty=False, - ) - new_records = records - self.production_id - for record in new_records: - record.message_post_with_view( - "mail.message_origin_link", - values=dict(self=record, origin=self.production_id) - ) - if new_records: - self.production_id.message_post_with_view( - "mrp_production_split.message_order_split", - values=dict(self=self.production_id, records=new_records) - ) - return records - - def apply(self): - records = self._apply() - action = self.env["ir.actions.act_window"]._for_xml_id( - "mrp.mrp_production_action" - ) - action["domain"] = [("id", "in", records.ids)] - return action diff --git a/mrp_production_split/wizards/mrp_production_split_wizard.xml b/mrp_production_split/wizards/mrp_production_split_wizard.xml deleted file mode 100644 index d8a3ff9..0000000 --- a/mrp_production_split/wizards/mrp_production_split_wizard.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - mrp.production.split.wizard - -
- - - - - - - - -
-
-
-
-
- - - Split Manufacturing Order - ir.actions.act_window - mrp.production.split.wizard - form - new - - -
diff --git a/product_configurator_mrp_component_ext/README.rst b/product_configurator_mrp_component_ext/README.rst deleted file mode 100644 index 1a07244..0000000 --- a/product_configurator_mrp_component_ext/README.rst +++ /dev/null @@ -1,17 +0,0 @@ -======================================================= -Product Configurator Manufacturing Components Extension -======================================================= - -.. contents:: Table of Contents - -Summary -------- -This module is an extension of the module `product_configurator_mrp_component `_. - -It resolves the issue of granting access to Bills of Material for users. - -The module provides simple users with Read access rights to the Bom Line Configurator. - -Contributors ------------- -* Numigi (tm) and all its contributors (https://bit.ly/numigiens) diff --git a/product_configurator_mrp_component_ext/__init__.py b/product_configurator_mrp_component_ext/__init__.py deleted file mode 100644 index 5bfd052..0000000 --- a/product_configurator_mrp_component_ext/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# © 2023 - Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). diff --git a/product_configurator_mrp_component_ext/__manifest__.py b/product_configurator_mrp_component_ext/__manifest__.py deleted file mode 100644 index 06bea99..0000000 --- a/product_configurator_mrp_component_ext/__manifest__.py +++ /dev/null @@ -1,20 +0,0 @@ -# © 2023 - Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -{ - "name": "Product Configurator Manufacturing Components ext", - "version": "1.0.0", - "category": "Manufacturing", - "summary": """Extended fonctionnalities of BOM - Support for configurable products""", - "author": "Numigi", - "maintainer": "Numigi", - "license": "AGPL-3", - "website": "https://bit.ly/numigi-com", - "depends": ["product_configurator_mrp_component"], - "data": [ - "security/ir.model.access.csv", - ], - "installable": True, - "auto_install": False, -} diff --git a/product_configurator_mrp_component_ext/security/ir.model.access.csv b/product_configurator_mrp_component_ext/security/ir.model.access.csv deleted file mode 100644 index 2a03ddd..0000000 --- a/product_configurator_mrp_component_ext/security/ir.model.access.csv +++ /dev/null @@ -1,2 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_mrp_bom_line_config_user,access_mrp_bom_line_config_user,product_configurator_mrp_component.model_mrp_bom_line_config,,1,0,0,0 diff --git a/product_configurator_mrp_component_ext/static/description/icon.png b/product_configurator_mrp_component_ext/static/description/icon.png deleted file mode 100644 index 92a86b1..0000000 Binary files a/product_configurator_mrp_component_ext/static/description/icon.png and /dev/null differ diff --git a/product_configurator_mrp_component_ext/tests/__init__.py b/product_configurator_mrp_component_ext/tests/__init__.py deleted file mode 100644 index 2679506..0000000 --- a/product_configurator_mrp_component_ext/tests/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# © 2023 - Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from . import test_mrp_bom_line_config diff --git a/product_configurator_mrp_component_ext/tests/test_mrp_bom_line_config.py b/product_configurator_mrp_component_ext/tests/test_mrp_bom_line_config.py deleted file mode 100644 index 7217bae..0000000 --- a/product_configurator_mrp_component_ext/tests/test_mrp_bom_line_config.py +++ /dev/null @@ -1,34 +0,0 @@ -# © 2023 - Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo.tests.common import TransactionCase - - -class MrpBomLineConfig(TransactionCase): - def setUp(self): - super(MrpBomLineConfig, self).setUp() - - self.product_id = self.env.ref("product.product_product_3") - - # create bom - self.bom_id = self.env["mrp.bom"].create( - { - "product_tmpl_id": self.product_id.product_tmpl_id.id, - "product_qty": 1.00, - "type": "normal", - "ready_to_produce": "all_available", - } - ) - - # create MRP Bom Line Conf - self.bom_line_conf_id = self.env["mrp.bom.line.config"].create( - { - "bom_id": self.bom_id.id, - "product_tmpl_id": self.product_id.product_tmpl_id.id, - "product_qty": 1.00, - } - ) - - def test_00_user_access_MrpBomLineConfig(self): - user_id = self.env.ref("base.user_demo") - self.bom_line_conf_id.with_user(user_id) diff --git a/product_configurator_mrp_enhanced/README.rst b/product_configurator_mrp_enhanced/README.rst deleted file mode 100644 index 7b69a7c..0000000 --- a/product_configurator_mrp_enhanced/README.rst +++ /dev/null @@ -1,13 +0,0 @@ -=========================================== -Product Configurator Manufacturing Enhabced -=========================================== - -.. contents:: Table of Contents - -Summary -------- -This module improves the module `product_configurator_mrp `_. - -Contributors ------------- -* Numigi (tm) and all its contributors (https://bit.ly/numigiens) diff --git a/product_configurator_mrp_enhanced/__init__.py b/product_configurator_mrp_enhanced/__init__.py deleted file mode 100644 index 9e9bc01..0000000 --- a/product_configurator_mrp_enhanced/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# © 2022 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -from . import models diff --git a/product_configurator_mrp_enhanced/__manifest__.py b/product_configurator_mrp_enhanced/__manifest__.py deleted file mode 100644 index f235477..0000000 --- a/product_configurator_mrp_enhanced/__manifest__.py +++ /dev/null @@ -1,12 +0,0 @@ -# © 2022 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -{ - "name": "Product Configurator Manufacturing Enhanced", - "version": "1.0.0", - "category": "Manufacturing", - "author": "Numigi", - "depends": ["product_configurator_mrp"], - "license": "AGPL-3", - "installable": True, -} diff --git a/product_configurator_mrp_enhanced/models/__init__.py b/product_configurator_mrp_enhanced/models/__init__.py deleted file mode 100644 index 20f9817..0000000 --- a/product_configurator_mrp_enhanced/models/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# © 2022 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -from . import product_config diff --git a/product_configurator_mrp_enhanced/models/product_config.py b/product_configurator_mrp_enhanced/models/product_config.py deleted file mode 100644 index 4bad7ca..0000000 --- a/product_configurator_mrp_enhanced/models/product_config.py +++ /dev/null @@ -1,124 +0,0 @@ -# © 2022 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -from odoo import models - - -class ProductConfigSession(models.Model): - _inherit = "product.config.session" - - def create_get_bom(self, variant, product_tmpl_id=None, values=None): - - # default_type is set as 'product' when the user navigates - # through menu item "Products". This conflicts - # with the type for mrp.bom when mrpBom.onchange() is executed. - ctx = self.env.context.copy() - if ctx.get("default_type"): - ctx.pop("default_type") - self.env.context = ctx - - if values is None: - values = {} - if product_tmpl_id is None or variant.product_tmpl_id != product_tmpl_id: - product_tmpl_id = variant.product_tmpl_id - - mrpBom = self.env["mrp.bom"] - mrpBomLine = self.env["mrp.bom.line"] - attr_products = variant.product_template_attribute_value_ids.mapped( - "product_attribute_value_id.product_id" - ) - attr_values = variant.product_template_attribute_value_ids.mapped( - "product_attribute_value_id" - ) - existing_bom = self.env["mrp.bom"].search( - [ - ("product_tmpl_id", "=", product_tmpl_id.id), - ("product_id", "=", variant.id), - ] - ) - if existing_bom: - return existing_bom[:1] - - parent_bom = self.env["mrp.bom"].search( - [ - ("product_tmpl_id", "=", product_tmpl_id.id), - ("product_id", "=", False), - ], - order="sequence asc", - limit=1, - ) - bom_lines = [] - if not parent_bom: - # If not Bom, then Cycle through attributes to add their - # related products to the bom lines. - for product in attr_products: - bom_line_vals = {"product_id": product.id} - specs = self.get_onchange_specifications(model="mrp.bom.line") - updates = mrpBomLine.onchange(bom_line_vals, ["product_id"], specs) - values = updates.get("value", {}) - values = self.get_vals_to_write(values=values, model="mrp.bom.line") - values.update(bom_line_vals) - bom_lines.append((0, 0, values)) - else: - # If parent BOM is used, then look through Config Sets - # on parent product's bom to add the products to the bom lines. - for parent_bom_line in parent_bom.bom_line_ids: - if parent_bom_line.config_set_id: - for config in parent_bom_line.config_set_id.configuration_ids: - # Add bom lines if config values are part of attr_values - if set(config.value_ids.ids).issubset(set(attr_values.ids)): - if parent_bom_line.bom_id.id == parent_bom.id: - parent_bom_line_vals = { - "product_id": parent_bom_line.product_id.id, - "product_qty": parent_bom_line.product_qty, - } - specs = self.get_onchange_specifications( - model="mrp.bom.line" - ) - updates = mrpBomLine.onchange( - parent_bom_line_vals, - ["product_id", "product_qty"], - specs, - ) - values = updates.get("value", {}) - values = self.get_vals_to_write( - values=values, model="mrp.bom.line" - ) - values.update(parent_bom_line_vals) - bom_lines.append((0, 0, values)) - else: - parent_bom_line_vals = { - "product_id": parent_bom_line.product_id.id, - "product_qty": parent_bom_line.product_qty, - } - specs = self.get_onchange_specifications(model="mrp.bom.line") - updates = mrpBomLine.onchange( - parent_bom_line_vals, ["product_id", "product_qty"], specs - ) - values2 = updates.get("value", {}) - values2 = self.get_vals_to_write( - values=values, model="mrp.bom.line" - ) - values2.update(parent_bom_line_vals) - bom_lines.append((0, 0, values2)) - if bom_lines: - bom_values = { - "product_tmpl_id": self.product_tmpl_id.id, - "product_id": variant.id, - "bom_line_ids": bom_lines, - } - specs = self.get_onchange_specifications(model="mrp.bom") - updates = mrpBom.onchange( - bom_values, - ["product_id", "product_tmpl_id", "bom_line_ids"], - specs, - ) - values = updates.get("value", {}) - values = self.get_vals_to_write(values=values, model="mrp.bom") - values.update(bom_values) - mrp_bom_id = mrpBom.create(values) - if mrp_bom_id and parent_bom: - for operation_line in parent_bom.operation_ids: - operation_line.copy(default={"bom_id": mrp_bom_id.id}) - return mrp_bom_id - return False diff --git a/product_configurator_mrp_enhanced/static/description/icon.png b/product_configurator_mrp_enhanced/static/description/icon.png deleted file mode 100644 index 92a86b1..0000000 Binary files a/product_configurator_mrp_enhanced/static/description/icon.png and /dev/null differ