diff --git a/project_stock/README.rst b/project_stock/README.rst new file mode 100644 index 0000000000..da804700c3 --- /dev/null +++ b/project_stock/README.rst @@ -0,0 +1,146 @@ +============= +Project Stock +============= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:ad512688e6eb234d7f33624a3edb9af58f1ac8d0f177bc5608aa530daf671f0b + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fproject-lightgray.png?logo=github + :target: https://github.com/OCA/project/tree/17.0/project_stock + :alt: OCA/project +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/project-17-0/project-17-0-project_stock + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/project&target_branch=17.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows to consume products directly from a project task. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +To configure this module, you need to: + +1. Go to *Inventory -> Configuration -> Settings* and check "Storage + Locations" option. + +2. Go to *Inventory -> Configuration -> Operation types*. + +3. Create a new operation type with the following options: + + - \`Operation type\`: Task material + - \`Code\`: TM + - \`Type of operation\`: Delivery + - \`Default Source Location\`: WH/Stock + - \`Default Destination Location\`: WH/Stock/Shelf 1 + +4. Go to *Project -> Configuration -> Projects*. + +5. Create a new project with the following options: + + - \`Name\`: Task material + - \`Operation type\`: Task material + +6. Go to *Project -> Configuration -> Task Stages* and edit some + records. + + - \`In progress\`: Check Use Stock Moves option and add the created + project. + - \`Done\`: Check Use Stock Moves option + Done Stock Moves and add + the created project. + +Usage +===== + +1. Go to *Projects -> Task material (project)* and create a task and + edit it. + +2. *Stock Info* is displayed in the *Extra info* tab with the same + project information, but it can be modified. + +3. Add some product to *Stock Info* tab and set some initial demand (1 + for example). + +4. Click on the button *Confirm material* to confirm all moves. + +5. Change the stage to Done. + +6. *Stock Info* tab is readonly and some buttons show in header: + + - \`Check availability materials\`: Product availability will be + checked. + - \`Transfer Materials\`: Stock moves are confirmed and moved from + one location to another. + - \`Unreserve\`: Remove the reservation stock of the products. + - \`Cancel Materials\`: Set the moves of the products as cancelled. + - \`Scrap\`: Allows the defined products to be scrapped. + +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 to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Tecnativa + +Contributors +------------ + +- `Tecnativa `__: + + - Víctor Martínez + - Pedro M. Baeza + +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-victoralmau| image:: https://github.com/victoralmau.png?size=40px + :target: https://github.com/victoralmau + :alt: victoralmau + +Current `maintainer `__: + +|maintainer-victoralmau| + +This module is part of the `OCA/project `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/project_stock/__init__.py b/project_stock/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/project_stock/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/project_stock/__manifest__.py b/project_stock/__manifest__.py new file mode 100644 index 0000000000..28d00972f9 --- /dev/null +++ b/project_stock/__manifest__.py @@ -0,0 +1,23 @@ +# Copyright 2022 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Project Stock", + "version": "17.0.1.0.0", + "category": "Project Management", + "website": "https://github.com/OCA/project", + "author": "Tecnativa, Odoo Community Association (OCA)", + "license": "AGPL-3", + "depends": ["project", "stock"], + "installable": True, + "data": [ + "views/project_project_view.xml", + "views/project_task_type_view.xml", + "views/stock_move_view.xml", + "views/project_task_view.xml", + ], + "demo": [ + "demo/stock_picking_type_data.xml", + "demo/project_data.xml", + ], + "maintainers": ["victoralmau"], +} diff --git a/project_stock/demo/project_data.xml b/project_stock/demo/project_data.xml new file mode 100644 index 0000000000..a91c8663d6 --- /dev/null +++ b/project_stock/demo/project_data.xml @@ -0,0 +1,25 @@ + + + + Task material + + + + 1990-01-01 + + + + + + + + + + + diff --git a/project_stock/demo/stock_picking_type_data.xml b/project_stock/demo/stock_picking_type_data.xml new file mode 100644 index 0000000000..2bce36dbde --- /dev/null +++ b/project_stock/demo/stock_picking_type_data.xml @@ -0,0 +1,11 @@ + + + + Task material + TM + outgoing + + + + + diff --git a/project_stock/i18n/es.po b/project_stock/i18n/es.po new file mode 100644 index 0000000000..b9ee75afa3 --- /dev/null +++ b/project_stock/i18n/es.po @@ -0,0 +1,344 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * project_stock +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-09-22 11:13+0000\n" +"PO-Revision-Date: 2023-09-22 13:14+0200\n" +"Last-Translator: Ivorra78 \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Poedit 3.0.1\n" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__allow_moves_action_assign +msgid "Allow Moves Action Assign" +msgstr "Permitir movimientos Asignar acción" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__allow_moves_action_confirm +msgid "Allow Moves Action Confirm" +msgstr "Permitir movimientos Confirmar acción" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__unreserve_visible +msgid "Allowed to Unreserve Inventory" +msgstr "Permitir anular reserva de inventario" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__analytic_distribution +msgid "Analytic" +msgstr "Analítico" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_distribution +msgid "Analytic Distribution" +msgstr "Distribución analítica" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__analytic_distribution_search +msgid "Analytic Distribution Search" +msgstr "Búsqueda de Distribución Analítica" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_account_analytic_line +msgid "Analytic Line" +msgstr "Línea Analítica" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_line_ids +msgid "Analytic Lines" +msgstr "Líneas analíticas" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__analytic_precision +msgid "Analytic Precision" +msgstr "Precisión analítica" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__stock_analytic_date +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_date +msgid "Analytic date" +msgstr "Fecha para analítica" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__assigned +msgid "Assigned" +msgstr "Asignado" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__cancel +msgid "Cancel" +msgstr "Cancelar" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Cancel Materials" +msgstr "Cancelar materiales" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Check availability materials" +msgstr "Consultar la disponibilidad de los materiales" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Confirm materials" +msgstr "Confirmar materiales" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__confirmed +msgid "Confirmed" +msgstr "Confirmado" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "Consumed" +msgstr "Consumido" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_project__location_id +msgid "Default location from which materials are consumed." +msgstr "Ubicación predeterminada desde la que se consumen los materiales." + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_project__location_dest_id +msgid "Default location to which materials are consumed." +msgstr "Ubicación predeterminada en la que se consumen los materiales." + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__location_dest_id +#: model:ir.model.fields,field_description:project_stock.field_project_task__location_dest_id +msgid "Destination Location" +msgstr "Ubicación destino" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__done +msgid "Done" +msgstr "Hecho" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__done_stock_moves +#: model:ir.model.fields,field_description:project_stock.field_project_task_type__done_stock_moves +msgid "Done Stock Moves" +msgstr "Realizar movimientos hechos" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "Forecasted Report" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__group_id +msgid "Group" +msgstr "Grupo" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__done_stock_moves +#: model:ir.model.fields,help:project_stock.field_project_task_type__done_stock_moves +msgid "" +"If you check this box, when a task is in this state, you will not be able to " +"add more stock moves but they can be viewed." +msgstr "" +"Si marca esta casilla, cuando una tarea esté en este estado, no se podrán " +"añadir mas movimientos de stock pero se podrán ver." + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__use_stock_moves +#: model:ir.model.fields,help:project_stock.field_project_task_type__use_stock_moves +msgid "" +"If you mark this check, when a task goes to this state, it will use stock " +"moves" +msgstr "" +"Si marca esta casilla, cuando una tarea pasa a este etapa, se podrán " +"utilizar movimientos de stock" + +#. module: project_stock +#: model:ir.actions.act_window,name:project_stock.action_project_task_moves +msgid "Inventory Moves" +msgstr "Movimientos de inventario" + +#. module: project_stock +#. odoo-python +#: code:addons/project_stock/models/project_task.py:0 +#, python-format +msgid "It is not possible to change this with reserved movements in tasks." +msgstr "No es posible cambiar esto con movimientos reservados en tareas." + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Lock" +msgstr "Bloquear" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_account_id +msgid "Move Analytic Account" +msgstr "Movimiento de cuenta analítica" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__stock_analytic_account_id +msgid "Move created will be assigned to this analytic account" +msgstr "El movimiento creado se asignará a esta cuenta analítica" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__picking_type_id +#: model:ir.model.fields,field_description:project_stock.field_project_task__picking_type_id +msgid "Operation Type" +msgstr "Tipo de operación" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__pending +msgid "Pending" +msgstr "Pendiente" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Product Moves" +msgstr "Movimientos de producto" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_stock_move_line +msgid "Product Moves (Stock Move Line)" +msgstr "Movimientos de Producto (Líneas de movimiento)" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_project_project +msgid "Project" +msgstr "Proyecto" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_account_analytic_line__stock_task_id +msgid "Project Task" +msgstr "Tarea" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_stock_move__task_id +msgid "Related Task" +msgstr "Tarea relacionada" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "Reserved" +msgstr "Reservado" + +#. module: project_stock +#. odoo-python +#: code:addons/project_stock/models/project_task.py:0 +#: model:ir.model,name:project_stock.model_stock_scrap +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +#, python-format +msgid "Scrap" +msgstr "Desechar" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__scrap_count +msgid "Scrap Move" +msgstr "Movimiento de desecho" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__scrap_ids +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Scraps" +msgstr "Desechos" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__location_id +#: model:ir.model.fields,field_description:project_stock.field_project_task__location_id +msgid "Source Location" +msgstr "Ubicación de origen" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.edit_project +msgid "Stock" +msgstr "Stock" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Stock Info" +msgstr "Información de stock" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_stock_move +msgid "Stock Move" +msgstr "Movimiento de existencias" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__move_ids +msgid "Stock Moves" +msgstr "Movimientos de albarán" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_moves_is_locked +msgid "Stock Moves Is Locked" +msgstr "Los movimientos de stock están bloqueados" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_state +msgid "Stock State" +msgstr "Estado del stock" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_project_task +#: model:ir.model.fields,field_description:project_stock.field_stock_move_line__task_id +#: model:ir.model.fields,field_description:project_stock.field_stock_scrap__task_id +msgid "Task" +msgstr "Tarea" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_project_task_type +msgid "Task Stage" +msgstr "Etapa de la tarea" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_stock_move__raw_material_task_id +msgid "Task for material" +msgstr "Materiales usados en la tarea" + +#. module: project_stock +#: model:project.project,name:project_stock.project_project_tm_test +#: model:stock.picking.type,name:project_stock.stock_picking_type_tm_test +msgid "Task material" +msgstr "Material de trabajo" + +#. module: project_stock +#: model:project.project,label_tasks:project_stock.project_project_tm_test +msgid "Tasks" +msgstr "Tareas" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__unreserve_visible +msgid "Technical field to check when we can unreserve" +msgstr "Campo técnico para consultar cuando podemos anula la reserva" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "To Consume" +msgstr "A consumir" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Transfer Materials" +msgstr "Transferir materiales" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Unlock" +msgstr "Desbloquear" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Unreserve" +msgstr "Anular reserva" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__use_stock_moves +#: model:ir.model.fields,field_description:project_stock.field_project_task_type__use_stock_moves +msgid "Use Stock Moves" +msgstr "Usar movimientos de stock" diff --git a/project_stock/i18n/fr.po b/project_stock/i18n/fr.po new file mode 100644 index 0000000000..0fd1e53466 --- /dev/null +++ b/project_stock/i18n/fr.po @@ -0,0 +1,337 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * project_stock +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr\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" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__allow_moves_action_assign +msgid "Allow Moves Action Assign" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__allow_moves_action_confirm +msgid "Allow Moves Action Confirm" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__unreserve_visible +msgid "Allowed to Unreserve Inventory" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__analytic_distribution +msgid "Analytic" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_distribution +msgid "Analytic Distribution" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__analytic_distribution_search +msgid "Analytic Distribution Search" +msgstr "" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_account_analytic_line +msgid "Analytic Line" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_line_ids +msgid "Analytic Lines" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__analytic_precision +msgid "Analytic Precision" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__stock_analytic_date +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_date +msgid "Analytic date" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__assigned +msgid "Assigned" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__cancel +msgid "Cancel" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Cancel Materials" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Check availability materials" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Confirm materials" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__confirmed +msgid "Confirmed" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "Consumed" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_project__location_id +msgid "Default location from which materials are consumed." +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_project__location_dest_id +msgid "Default location to which materials are consumed." +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__location_dest_id +#: model:ir.model.fields,field_description:project_stock.field_project_task__location_dest_id +msgid "Destination Location" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__done +msgid "Done" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__done_stock_moves +#: model:ir.model.fields,field_description:project_stock.field_project_task_type__done_stock_moves +msgid "Done Stock Moves" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "Forecasted Report" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__group_id +msgid "Group" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__done_stock_moves +#: model:ir.model.fields,help:project_stock.field_project_task_type__done_stock_moves +msgid "" +"If you check this box, when a task is in this state, you will not be able to " +"add more stock moves but they can be viewed." +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__use_stock_moves +#: model:ir.model.fields,help:project_stock.field_project_task_type__use_stock_moves +msgid "" +"If you mark this check, when a task goes to this state, it will use stock " +"moves" +msgstr "" + +#. module: project_stock +#: model:ir.actions.act_window,name:project_stock.action_project_task_moves +msgid "Inventory Moves" +msgstr "" + +#. module: project_stock +#. odoo-python +#: code:addons/project_stock/models/project_task.py:0 +#, python-format +msgid "It is not possible to change this with reserved movements in tasks." +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Lock" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_account_id +msgid "Move Analytic Account" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__stock_analytic_account_id +msgid "Move created will be assigned to this analytic account" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__picking_type_id +#: model:ir.model.fields,field_description:project_stock.field_project_task__picking_type_id +msgid "Operation Type" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__pending +msgid "Pending" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Product Moves" +msgstr "" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_stock_move_line +msgid "Product Moves (Stock Move Line)" +msgstr "" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_project_project +msgid "Project" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_account_analytic_line__stock_task_id +msgid "Project Task" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_stock_move__task_id +msgid "Related Task" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "Reserved" +msgstr "" + +#. module: project_stock +#. odoo-python +#: code:addons/project_stock/models/project_task.py:0 +#: model:ir.model,name:project_stock.model_stock_scrap +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +#, python-format +msgid "Scrap" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__scrap_count +msgid "Scrap Move" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__scrap_ids +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Scraps" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__location_id +#: model:ir.model.fields,field_description:project_stock.field_project_task__location_id +msgid "Source Location" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.edit_project +msgid "Stock" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Stock Info" +msgstr "" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_stock_move +msgid "Stock Move" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__move_ids +msgid "Stock Moves" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_moves_is_locked +msgid "Stock Moves Is Locked" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_state +msgid "Stock State" +msgstr "" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_project_task +#: model:ir.model.fields,field_description:project_stock.field_stock_move_line__task_id +#: model:ir.model.fields,field_description:project_stock.field_stock_scrap__task_id +msgid "Task" +msgstr "" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_project_task_type +msgid "Task Stage" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_stock_move__raw_material_task_id +msgid "Task for material" +msgstr "" + +#. module: project_stock +#: model:project.project,name:project_stock.project_project_tm_test +#: model:stock.picking.type,name:project_stock.stock_picking_type_tm_test +msgid "Task material" +msgstr "" + +#. module: project_stock +#: model:project.project,label_tasks:project_stock.project_project_tm_test +msgid "Tasks" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__unreserve_visible +msgid "Technical field to check when we can unreserve" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "To Consume" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Transfer Materials" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Unlock" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Unreserve" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__use_stock_moves +#: model:ir.model.fields,field_description:project_stock.field_project_task_type__use_stock_moves +msgid "Use Stock Moves" +msgstr "" diff --git a/project_stock/i18n/hr.po b/project_stock/i18n/hr.po new file mode 100644 index 0000000000..07c3af70d2 --- /dev/null +++ b/project_stock/i18n/hr.po @@ -0,0 +1,357 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * project_stock +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-09-06 12:37+0000\n" +"Last-Translator: vladimiruvid \n" +"Language-Team: none\n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 4.17\n" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__allow_moves_action_assign +msgid "Allow Moves Action Assign" +msgstr "Dozvoli dodjeljivanje skladišnih prenosa" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__allow_moves_action_confirm +msgid "Allow Moves Action Confirm" +msgstr "Dozvoli potvrđivanje skladišnih prenosa" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__unreserve_visible +msgid "Allowed to Unreserve Inventory" +msgstr "Dozvoli odrezervaciju stavaka" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__analytic_distribution +msgid "Analytic" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_distribution +msgid "Analytic Distribution" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__analytic_distribution_search +msgid "Analytic Distribution Search" +msgstr "" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_account_analytic_line +msgid "Analytic Line" +msgstr "Analitička stavka" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_line_ids +msgid "Analytic Lines" +msgstr "Analitičke stavke" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__analytic_precision +msgid "Analytic Precision" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__stock_analytic_date +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_date +msgid "Analytic date" +msgstr "Datum analitike" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__assigned +msgid "Assigned" +msgstr "Dodijeljeno" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__cancel +msgid "Cancel" +msgstr "Otkaži" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Cancel Materials" +msgstr "Otkaži materijale" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Check availability materials" +msgstr "Provjeri dostupnost matrijala" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Confirm materials" +msgstr "Potvrdi materijale" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__confirmed +msgid "Confirmed" +msgstr "Potvrđeno" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "Consumed" +msgstr "Utrošeno" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_project__location_id +msgid "Default location from which materials are consumed." +msgstr "Zadana lokacija sa koje se troše materijali." + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_project__location_dest_id +msgid "Default location to which materials are consumed." +msgstr "Zadana lokacija na kojoj završavaju utrošeni materijali." + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__location_dest_id +#: model:ir.model.fields,field_description:project_stock.field_project_task__location_dest_id +msgid "Destination Location" +msgstr "Odredišna lokacija" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__done +msgid "Done" +msgstr "Završeno" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__done_stock_moves +#: model:ir.model.fields,field_description:project_stock.field_project_task_type__done_stock_moves +msgid "Done Stock Moves" +msgstr "Završena skladišna kretanja" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "Forecasted Report" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__group_id +msgid "Group" +msgstr "Grupa" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__done_stock_moves +#: model:ir.model.fields,help:project_stock.field_project_task_type__done_stock_moves +msgid "" +"If you check this box, when a task is in this state, you will not be able to " +"add more stock moves but they can be viewed." +msgstr "" +"Ako označite ovo, kad zadatak dođe u ovo stanje, nećete više moći dodati " +"skladišna kretanja, ali ona ostaju vidljiva." + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__use_stock_moves +#: model:ir.model.fields,help:project_stock.field_project_task_type__use_stock_moves +msgid "" +"If you mark this check, when a task goes to this state, it will use stock " +"moves" +msgstr "" +"Ako je ovo označeno, kad zadatak dođe u ovo stanje, koriste se skladišna " +"kretanja" + +#. module: project_stock +#: model:ir.actions.act_window,name:project_stock.action_project_task_moves +msgid "Inventory Moves" +msgstr "Kretanja inventure" + +#. module: project_stock +#. odoo-python +#: code:addons/project_stock/models/project_task.py:0 +#, python-format +msgid "It is not possible to change this with reserved movements in tasks." +msgstr "" +"Ovo nije moguće mijenjati na rezerviranim skladišnim kretanjima u zadacima." + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Lock" +msgstr "Zaključaj" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_account_id +msgid "Move Analytic Account" +msgstr "Analitički konto kretanja" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__stock_analytic_account_id +msgid "Move created will be assigned to this analytic account" +msgstr "Kreirano kretanje će biti dodijeljeno ovom analitičkom kontu" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__picking_type_id +#: model:ir.model.fields,field_description:project_stock.field_project_task__picking_type_id +msgid "Operation Type" +msgstr "Tip operacije" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__pending +msgid "Pending" +msgstr "Na čekanju" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Product Moves" +msgstr "Kretanja proizvoda" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_stock_move_line +msgid "Product Moves (Stock Move Line)" +msgstr "Kretanja proizvoda (stavke skladišnog kretanja)" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_project_project +msgid "Project" +msgstr "Projekt" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_account_analytic_line__stock_task_id +msgid "Project Task" +msgstr "Projektni zadatak" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_stock_move__task_id +msgid "Related Task" +msgstr "Povezani zadatak" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "Reserved" +msgstr "Rezervirano" + +#. module: project_stock +#. odoo-python +#: code:addons/project_stock/models/project_task.py:0 +#: model:ir.model,name:project_stock.model_stock_scrap +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +#, python-format +msgid "Scrap" +msgstr "Otpis" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__scrap_count +msgid "Scrap Move" +msgstr "Kretanje otpisa" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__scrap_ids +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Scraps" +msgstr "Otpisi" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__location_id +#: model:ir.model.fields,field_description:project_stock.field_project_task__location_id +msgid "Source Location" +msgstr "Ishodišna lokacija" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.edit_project +msgid "Stock" +msgstr "Skladište" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Stock Info" +msgstr "Informacije o skladištu" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_stock_move +msgid "Stock Move" +msgstr "Skladišno kretanje" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__move_ids +msgid "Stock Moves" +msgstr "Skladišna kretanja" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_moves_is_locked +msgid "Stock Moves Is Locked" +msgstr "Skladišna kretanja su zaključana" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_state +msgid "Stock State" +msgstr "Stanje skladišta" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_project_task +#: model:ir.model.fields,field_description:project_stock.field_stock_move_line__task_id +#: model:ir.model.fields,field_description:project_stock.field_stock_scrap__task_id +msgid "Task" +msgstr "Zadatak" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_project_task_type +msgid "Task Stage" +msgstr "Status zadatka" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_stock_move__raw_material_task_id +msgid "Task for material" +msgstr "Zadatak za materijal" + +#. module: project_stock +#: model:project.project,name:project_stock.project_project_tm_test +#: model:stock.picking.type,name:project_stock.stock_picking_type_tm_test +msgid "Task material" +msgstr "" + +#. module: project_stock +#: model:project.project,label_tasks:project_stock.project_project_tm_test +msgid "Tasks" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__unreserve_visible +msgid "Technical field to check when we can unreserve" +msgstr "Tehničko polje za provjeru kada možemo odrezervirati" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "To Consume" +msgstr "Za utrošiti" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Transfer Materials" +msgstr "Prebaci materijale" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Unlock" +msgstr "Otključaj" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Unreserve" +msgstr "Odrezerviraj" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__use_stock_moves +#: model:ir.model.fields,field_description:project_stock.field_project_task_type__use_stock_moves +msgid "Use Stock Moves" +msgstr "Koristi skladišna kretanja" + +#~ msgid "Move Analytic Tags" +#~ msgstr "Oznake analitike kretanja" + +#~ msgid "Display Name" +#~ msgstr "Prikazani naziv" + +#~ msgid "ID" +#~ msgstr "ID" + +#~ msgid "Last Modified on" +#~ msgstr "Zadnje modificirano" diff --git a/project_stock/i18n/it.po b/project_stock/i18n/it.po new file mode 100644 index 0000000000..2e0a3ebff6 --- /dev/null +++ b/project_stock/i18n/it.po @@ -0,0 +1,356 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * project_stock +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-12-18 10:34+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.17\n" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__allow_moves_action_assign +msgid "Allow Moves Action Assign" +msgstr "Consente assegnazione azione movimenti" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__allow_moves_action_confirm +msgid "Allow Moves Action Confirm" +msgstr "Consente conferma azione movimenti" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__unreserve_visible +msgid "Allowed to Unreserve Inventory" +msgstr "Abilitato a rilasciare giacenze" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__analytic_distribution +msgid "Analytic" +msgstr "Analitico" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_distribution +msgid "Analytic Distribution" +msgstr "Distribuzione analitica" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__analytic_distribution_search +msgid "Analytic Distribution Search" +msgstr "Ricerca distribuzione analitica" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_account_analytic_line +msgid "Analytic Line" +msgstr "Riga analitica" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_line_ids +msgid "Analytic Lines" +msgstr "Righe analitiche" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__analytic_precision +msgid "Analytic Precision" +msgstr "Precisione analitica" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__stock_analytic_date +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_date +msgid "Analytic date" +msgstr "Data analitica" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__assigned +msgid "Assigned" +msgstr "Assegnato" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__cancel +msgid "Cancel" +msgstr "Annulla" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Cancel Materials" +msgstr "Annulla materiali" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Check availability materials" +msgstr "Controlla disponibilità materiali" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Confirm materials" +msgstr "Conferma materiali" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__confirmed +msgid "Confirmed" +msgstr "Confermato" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "Consumed" +msgstr "Consumato" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_project__location_id +msgid "Default location from which materials are consumed." +msgstr "Ubicazione predefinita da cui i materiali vengono consumati." + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_project__location_dest_id +msgid "Default location to which materials are consumed." +msgstr "Ubicazione predefinita alla quale i materiali vengono consumati." + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__location_dest_id +#: model:ir.model.fields,field_description:project_stock.field_project_task__location_dest_id +msgid "Destination Location" +msgstr "Ubicazione di destinazione" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__done +msgid "Done" +msgstr "Eseguito" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__done_stock_moves +#: model:ir.model.fields,field_description:project_stock.field_project_task_type__done_stock_moves +msgid "Done Stock Moves" +msgstr "Movimenti di magazzino eseguiti" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "Forecasted Report" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__group_id +msgid "Group" +msgstr "Gruppo" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__done_stock_moves +#: model:ir.model.fields,help:project_stock.field_project_task_type__done_stock_moves +msgid "" +"If you check this box, when a task is in this state, you will not be able to " +"add more stock moves but they can be viewed." +msgstr "" +"Se si spunta questa opzione, quando un lavoro è in questo stato, non si " +"potrà aggiungere altri movimenti di magazzino ma potranno essere " +"visualizzati." + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__use_stock_moves +#: model:ir.model.fields,help:project_stock.field_project_task_type__use_stock_moves +msgid "" +"If you mark this check, when a task goes to this state, it will use stock " +"moves" +msgstr "" +"Se si seleziona questa opzione, quando un lavoro viene spostato in questo " +"stato, utilizzerà i movimenti di magazzino" + +#. module: project_stock +#: model:ir.actions.act_window,name:project_stock.action_project_task_moves +msgid "Inventory Moves" +msgstr "Movimenti di magazzino" + +#. module: project_stock +#. odoo-python +#: code:addons/project_stock/models/project_task.py:0 +#, python-format +msgid "It is not possible to change this with reserved movements in tasks." +msgstr "Non è possibile modificarlo con movimenti prenotati nei lavori." + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Lock" +msgstr "Blocco" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_account_id +msgid "Move Analytic Account" +msgstr "Movimento conto analitico" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__stock_analytic_account_id +msgid "Move created will be assigned to this analytic account" +msgstr "Il movimento creato verrà assegnato a questo conto analitico" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__picking_type_id +#: model:ir.model.fields,field_description:project_stock.field_project_task__picking_type_id +msgid "Operation Type" +msgstr "Tipo di operazione" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__pending +msgid "Pending" +msgstr "In attesa" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Product Moves" +msgstr "Movimenti prodotto" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_stock_move_line +msgid "Product Moves (Stock Move Line)" +msgstr "Movimenti prodotto (riga movimento di magazzino)" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_project_project +msgid "Project" +msgstr "Progetto" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_account_analytic_line__stock_task_id +msgid "Project Task" +msgstr "Lavoro del progetto" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_stock_move__task_id +msgid "Related Task" +msgstr "Lavoro correlato" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "Reserved" +msgstr "Prenotato" + +#. module: project_stock +#. odoo-python +#: code:addons/project_stock/models/project_task.py:0 +#: model:ir.model,name:project_stock.model_stock_scrap +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +#, python-format +msgid "Scrap" +msgstr "Scarto" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__scrap_count +msgid "Scrap Move" +msgstr "Movimento scarto" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__scrap_ids +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Scraps" +msgstr "Scarti" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__location_id +#: model:ir.model.fields,field_description:project_stock.field_project_task__location_id +msgid "Source Location" +msgstr "Ubicazione di origine" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.edit_project +msgid "Stock" +msgstr "Giacenza" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Stock Info" +msgstr "Informazioni giacenza" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_stock_move +msgid "Stock Move" +msgstr "Movimento di magazzino" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__move_ids +msgid "Stock Moves" +msgstr "Movimenti di magazzino" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_moves_is_locked +msgid "Stock Moves Is Locked" +msgstr "I movimenti di magazzino sono bloccati" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_state +msgid "Stock State" +msgstr "Stato giacenza" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_project_task +#: model:ir.model.fields,field_description:project_stock.field_stock_move_line__task_id +#: model:ir.model.fields,field_description:project_stock.field_stock_scrap__task_id +msgid "Task" +msgstr "Lavoro" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_project_task_type +msgid "Task Stage" +msgstr "Fase lavoro" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_stock_move__raw_material_task_id +msgid "Task for material" +msgstr "Lavoro per materiale" + +#. module: project_stock +#: model:project.project,name:project_stock.project_project_tm_test +#: model:stock.picking.type,name:project_stock.stock_picking_type_tm_test +msgid "Task material" +msgstr "Materiale lavoro" + +#. module: project_stock +#: model:project.project,label_tasks:project_stock.project_project_tm_test +msgid "Tasks" +msgstr "Lavori" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__unreserve_visible +msgid "Technical field to check when we can unreserve" +msgstr "Campo tecnico per controllare quando si può rilasciare" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "To Consume" +msgstr "Da consumare" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Transfer Materials" +msgstr "Trasferimento materiali" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Unlock" +msgstr "Sblocca" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Unreserve" +msgstr "Rilascia" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__use_stock_moves +#: model:ir.model.fields,field_description:project_stock.field_project_task_type__use_stock_moves +msgid "Use Stock Moves" +msgstr "Utilizza movimenti di magazzino" + +#~ msgid "Move Analytic Tags" +#~ msgstr "Movimento etichette analitiche" + +#~ msgid "Display Name" +#~ msgstr "Nome visualizzato" + +#~ msgid "ID" +#~ msgstr "ID" + +#~ msgid "Last Modified on" +#~ msgstr "Ultima modifica il" diff --git a/project_stock/i18n/project_stock.pot b/project_stock/i18n/project_stock.pot new file mode 100644 index 0000000000..454c2e883b --- /dev/null +++ b/project_stock/i18n/project_stock.pot @@ -0,0 +1,336 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * project_stock +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.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: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__allow_moves_action_assign +msgid "Allow Moves Action Assign" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__allow_moves_action_confirm +msgid "Allow Moves Action Confirm" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__unreserve_visible +msgid "Allowed to Unreserve Inventory" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__analytic_distribution +msgid "Analytic" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_distribution +msgid "Analytic Distribution" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__analytic_distribution_search +msgid "Analytic Distribution Search" +msgstr "" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_account_analytic_line +msgid "Analytic Line" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_line_ids +msgid "Analytic Lines" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__analytic_precision +msgid "Analytic Precision" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__stock_analytic_date +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_date +msgid "Analytic date" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__assigned +msgid "Assigned" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__cancel +msgid "Cancel" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Cancel Materials" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Check availability materials" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Confirm materials" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__confirmed +msgid "Confirmed" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "Consumed" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_project__location_id +msgid "Default location from which materials are consumed." +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_project__location_dest_id +msgid "Default location to which materials are consumed." +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__location_dest_id +#: model:ir.model.fields,field_description:project_stock.field_project_task__location_dest_id +msgid "Destination Location" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__done +msgid "Done" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__done_stock_moves +#: model:ir.model.fields,field_description:project_stock.field_project_task_type__done_stock_moves +msgid "Done Stock Moves" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "Forecasted Report" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__group_id +msgid "Group" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__done_stock_moves +#: model:ir.model.fields,help:project_stock.field_project_task_type__done_stock_moves +msgid "" +"If you check this box, when a task is in this state, you will not be able to" +" add more stock moves but they can be viewed." +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__use_stock_moves +#: model:ir.model.fields,help:project_stock.field_project_task_type__use_stock_moves +msgid "" +"If you mark this check, when a task goes to this state, it will use stock " +"moves" +msgstr "" + +#. module: project_stock +#: model:ir.actions.act_window,name:project_stock.action_project_task_moves +msgid "Inventory Moves" +msgstr "" + +#. module: project_stock +#. odoo-python +#: code:addons/project_stock/models/project_task.py:0 +#, python-format +msgid "It is not possible to change this with reserved movements in tasks." +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Lock" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_account_id +msgid "Move Analytic Account" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__stock_analytic_account_id +msgid "Move created will be assigned to this analytic account" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__picking_type_id +#: model:ir.model.fields,field_description:project_stock.field_project_task__picking_type_id +msgid "Operation Type" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__pending +msgid "Pending" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Product Moves" +msgstr "" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_stock_move_line +msgid "Product Moves (Stock Move Line)" +msgstr "" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_project_project +msgid "Project" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_account_analytic_line__stock_task_id +msgid "Project Task" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_stock_move__task_id +msgid "Related Task" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "Reserved" +msgstr "" + +#. module: project_stock +#. odoo-python +#: code:addons/project_stock/models/project_task.py:0 +#: model:ir.model,name:project_stock.model_stock_scrap +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +#, python-format +msgid "Scrap" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__scrap_count +msgid "Scrap Move" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__scrap_ids +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Scraps" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__location_id +#: model:ir.model.fields,field_description:project_stock.field_project_task__location_id +msgid "Source Location" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.edit_project +msgid "Stock" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Stock Info" +msgstr "" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_stock_move +msgid "Stock Move" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__move_ids +msgid "Stock Moves" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_moves_is_locked +msgid "Stock Moves Is Locked" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_state +msgid "Stock State" +msgstr "" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_project_task +#: model:ir.model.fields,field_description:project_stock.field_stock_move_line__task_id +#: model:ir.model.fields,field_description:project_stock.field_stock_scrap__task_id +msgid "Task" +msgstr "" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_project_task_type +msgid "Task Stage" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_stock_move__raw_material_task_id +msgid "Task for material" +msgstr "" + +#. module: project_stock +#: model:project.project,name:project_stock.project_project_tm_test +#: model:stock.picking.type,name:project_stock.stock_picking_type_tm_test +msgid "Task material" +msgstr "" + +#. module: project_stock +#: model:project.project,label_tasks:project_stock.project_project_tm_test +msgid "Tasks" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__unreserve_visible +msgid "Technical field to check when we can unreserve" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "To Consume" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Transfer Materials" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Unlock" +msgstr "" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Unreserve" +msgstr "" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__use_stock_moves +#: model:ir.model.fields,field_description:project_stock.field_project_task_type__use_stock_moves +msgid "Use Stock Moves" +msgstr "" diff --git a/project_stock/i18n/pt_BR.po b/project_stock/i18n/pt_BR.po new file mode 100644 index 0000000000..76884b545b --- /dev/null +++ b/project_stock/i18n/pt_BR.po @@ -0,0 +1,348 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * project_stock +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-06-11 15:35+0000\n" +"Last-Translator: Rodrigo Macedo \n" +"Language-Team: none\n" +"Language: pt_BR\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.17\n" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__allow_moves_action_assign +msgid "Allow Moves Action Assign" +msgstr "Permitir Atribuição de Ação em Movimentos" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__allow_moves_action_confirm +msgid "Allow Moves Action Confirm" +msgstr "Permitir Confirmar Ação em Movimentos" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__unreserve_visible +msgid "Allowed to Unreserve Inventory" +msgstr "Permite cancelar a Reserva de Inventário" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__analytic_distribution +msgid "Analytic" +msgstr "Analítico" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_distribution +msgid "Analytic Distribution" +msgstr "Distribuição Analítica" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__analytic_distribution_search +msgid "Analytic Distribution Search" +msgstr "Pesquisa de Distribuição Analítica" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_account_analytic_line +msgid "Analytic Line" +msgstr "Linha Analítica" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_line_ids +msgid "Analytic Lines" +msgstr "Linhas Analíticas" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__analytic_precision +msgid "Analytic Precision" +msgstr "Precisão Analítica" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__stock_analytic_date +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_date +msgid "Analytic date" +msgstr "Data Analítica" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__assigned +msgid "Assigned" +msgstr "Atribuído" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__cancel +msgid "Cancel" +msgstr "Cancelar" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Cancel Materials" +msgstr "Cancelar Materiais" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Check availability materials" +msgstr "Verifique a disponibilidade de materiais" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Confirm materials" +msgstr "Confirmar Materiais" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__confirmed +msgid "Confirmed" +msgstr "Confirmado" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "Consumed" +msgstr "Consumido" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_project__location_id +msgid "Default location from which materials are consumed." +msgstr "Local padrão de onde os materiais são consumidos." + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_project__location_dest_id +msgid "Default location to which materials are consumed." +msgstr "Local padrão para o qual os materiais são consumidos." + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__location_dest_id +#: model:ir.model.fields,field_description:project_stock.field_project_task__location_dest_id +msgid "Destination Location" +msgstr "Local de Destino" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__done +msgid "Done" +msgstr "Feito" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__done_stock_moves +#: model:ir.model.fields,field_description:project_stock.field_project_task_type__done_stock_moves +msgid "Done Stock Moves" +msgstr "Movimentos de Estoque Feitos" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "Forecasted Report" +msgstr "Relatório Previsto" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__group_id +msgid "Group" +msgstr "Grupo" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__done_stock_moves +#: model:ir.model.fields,help:project_stock.field_project_task_type__done_stock_moves +msgid "" +"If you check this box, when a task is in this state, you will not be able to " +"add more stock moves but they can be viewed." +msgstr "" +"Se você marcar esta caixa, quando uma tarefa estiver neste estado, você não " +"poderá adicionar mais movimentos de estoque, mas eles poderão ser " +"visualizados." + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__use_stock_moves +#: model:ir.model.fields,help:project_stock.field_project_task_type__use_stock_moves +msgid "" +"If you mark this check, when a task goes to this state, it will use stock " +"moves" +msgstr "" +"Se você marcar esta verificação, quando uma tarefa for para este estado, ela " +"usará movimentos de estoque" + +#. module: project_stock +#: model:ir.actions.act_window,name:project_stock.action_project_task_moves +msgid "Inventory Moves" +msgstr "Movimentações de Inventário" + +#. module: project_stock +#. odoo-python +#: code:addons/project_stock/models/project_task.py:0 +#, python-format +msgid "It is not possible to change this with reserved movements in tasks." +msgstr "Não é possível alterar isso com movimentos reservados em tarefas." + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Lock" +msgstr "Trancar" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_analytic_account_id +msgid "Move Analytic Account" +msgstr "Conta Analítica do Movimento" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__stock_analytic_account_id +msgid "Move created will be assigned to this analytic account" +msgstr "O movimento criado será atribuído a esta conta analítica" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__picking_type_id +#: model:ir.model.fields,field_description:project_stock.field_project_task__picking_type_id +msgid "Operation Type" +msgstr "Tipo de Operação" + +#. module: project_stock +#: model:ir.model.fields.selection,name:project_stock.selection__project_task__stock_state__pending +msgid "Pending" +msgstr "Pendente" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Product Moves" +msgstr "Movimentações de Produtos" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_stock_move_line +msgid "Product Moves (Stock Move Line)" +msgstr "Movimentações de Produto (Linha de Movimentação de Estoque)" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_project_project +msgid "Project" +msgstr "Projeto" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_account_analytic_line__stock_task_id +msgid "Project Task" +msgstr "Tarefa do Projeto" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_stock_move__task_id +msgid "Related Task" +msgstr "Tarefa Relacionada" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "Reserved" +msgstr "Reservado" + +#. module: project_stock +#. odoo-python +#: code:addons/project_stock/models/project_task.py:0 +#: model:ir.model,name:project_stock.model_stock_scrap +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +#, python-format +msgid "Scrap" +msgstr "Sucatear" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__scrap_count +msgid "Scrap Move" +msgstr "Movimento de Sucata" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__scrap_ids +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Scraps" +msgstr "Sucatas" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_project__location_id +#: model:ir.model.fields,field_description:project_stock.field_project_task__location_id +msgid "Source Location" +msgstr "Local de Origem" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.edit_project +msgid "Stock" +msgstr "Estoque" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Stock Info" +msgstr "Info Estoque" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_stock_move +msgid "Stock Move" +msgstr "Mover Estoque" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__move_ids +msgid "Stock Moves" +msgstr "Movimentação de Estoque" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_moves_is_locked +msgid "Stock Moves Is Locked" +msgstr "Movimentação de Estoque esta Bloqueada" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__stock_state +msgid "Stock State" +msgstr "Situação do Estoque" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_project_task +#: model:ir.model.fields,field_description:project_stock.field_stock_move_line__task_id +#: model:ir.model.fields,field_description:project_stock.field_stock_scrap__task_id +msgid "Task" +msgstr "Tarefa" + +#. module: project_stock +#: model:ir.model,name:project_stock.model_project_task_type +msgid "Task Stage" +msgstr "Estagio da Tarefa" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_stock_move__raw_material_task_id +msgid "Task for material" +msgstr "Tarefa para Material" + +#. module: project_stock +#: model:project.project,name:project_stock.project_project_tm_test +#: model:stock.picking.type,name:project_stock.stock_picking_type_tm_test +msgid "Task material" +msgstr "Material de Tarefa" + +#. module: project_stock +#: model:project.project,label_tasks:project_stock.project_project_tm_test +msgid "Tasks" +msgstr "Tarefas" + +#. module: project_stock +#: model:ir.model.fields,help:project_stock.field_project_task__unreserve_visible +msgid "Technical field to check when we can unreserve" +msgstr "Campo técnico para verificar quando podemos cancelar a reserva" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_stock_move_raw_tree +msgid "To Consume" +msgstr "Consumir" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Transfer Materials" +msgstr "Transferir Materiais" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Unlock" +msgstr "Destravar" + +#. module: project_stock +#: model_terms:ir.ui.view,arch_db:project_stock.view_task_form2 +msgid "Unreserve" +msgstr "Cancelar reserva" + +#. module: project_stock +#: model:ir.model.fields,field_description:project_stock.field_project_task__use_stock_moves +#: model:ir.model.fields,field_description:project_stock.field_project_task_type__use_stock_moves +msgid "Use Stock Moves" +msgstr "Usar Movimentos de Estoque" + +#~ msgid "Move Analytic Tags" +#~ msgstr "Etiqueta Movimento Analítico" diff --git a/project_stock/models/__init__.py b/project_stock/models/__init__.py new file mode 100644 index 0000000000..e94b5f58b5 --- /dev/null +++ b/project_stock/models/__init__.py @@ -0,0 +1,7 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import account_analytic_line +from . import project_project +from . import project_task +from . import stock_move +from . import stock_scrap diff --git a/project_stock/models/account_analytic_line.py b/project_stock/models/account_analytic_line.py new file mode 100644 index 0000000000..03cf95a3f9 --- /dev/null +++ b/project_stock/models/account_analytic_line.py @@ -0,0 +1,21 @@ +# Copyright 2022 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) +from odoo import fields, models + + +class AccountAnalyticLine(models.Model): + _inherit = "account.analytic.line" + + stock_task_id = fields.Many2one( + comodel_name="project.task", string="Project Task", ondelete="cascade" + ) + + def _timesheet_postprocess_values(self, values): + """When hr_timesheet addon is installed, in the create() and write() methods, + the amount is recalculated according to the employee cost. + We need to force that in the records related to stock tasks the price is not + updated.""" + res = super()._timesheet_postprocess_values(values) + for key in self.filtered(lambda x: x.stock_task_id).ids: + res[key].pop("amount", None) + return res diff --git a/project_stock/models/project_project.py b/project_stock/models/project_project.py new file mode 100644 index 0000000000..ecc6bbc15f --- /dev/null +++ b/project_stock/models/project_project.py @@ -0,0 +1,46 @@ +# Copyright 2022 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) +from odoo import api, fields, models + + +class ProjectProject(models.Model): + _inherit = "project.project" + + picking_type_id = fields.Many2one( + comodel_name="stock.picking.type", + string="Operation Type", + readonly=False, + domain="[('company_id', '=', company_id)]", + index=True, + check_company=True, + ) + location_id = fields.Many2one( + comodel_name="stock.location", + string="Source Location", + readonly=False, + check_company=True, + index=True, + help="Default location from which materials are consumed.", + ) + location_dest_id = fields.Many2one( + comodel_name="stock.location", + string="Destination Location", + readonly=False, + index=True, + check_company=True, + help="Default location to which materials are consumed.", + ) + stock_analytic_date = fields.Date(string="Analytic date") + + @api.onchange("picking_type_id") + def _onchange_picking_type_id(self): + self.location_id = self.picking_type_id.default_location_src_id.id + self.location_dest_id = self.picking_type_id.default_location_dest_id.id + + def write(self, vals): + """Update location information on pending moves when changed.""" + res = super().write(vals) + field_names = ("location_id", "location_dest_id") + if any(vals.get(field) for field in field_names): + self.task_ids._update_moves_info() + return res diff --git a/project_stock/models/project_task.py b/project_stock/models/project_task.py new file mode 100644 index 0000000000..81a7cc4a10 --- /dev/null +++ b/project_stock/models/project_task.py @@ -0,0 +1,244 @@ +# Copyright 2022 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) +from odoo import _, api, fields, models +from odoo.exceptions import UserError + + +class ProjectTask(models.Model): + _name = "project.task" + _inherit = ["project.task", "analytic.mixin"] + + scrap_ids = fields.One2many( + comodel_name="stock.scrap", inverse_name="task_id", string="Scraps" + ) + scrap_count = fields.Integer( + compute="_compute_scrap_move_count", string="Scrap Move" + ) + move_ids = fields.One2many( + comodel_name="stock.move", + inverse_name="raw_material_task_id", + string="Stock Moves", + copy=False, + domain=[("scrapped", "=", False)], + ) + use_stock_moves = fields.Boolean(related="stage_id.use_stock_moves") + done_stock_moves = fields.Boolean(related="stage_id.done_stock_moves") + stock_moves_is_locked = fields.Boolean(default=True) + allow_moves_action_confirm = fields.Boolean( + compute="_compute_allow_moves_action_confirm" + ) + allow_moves_action_assign = fields.Boolean( + compute="_compute_allow_moves_action_assign" + ) + stock_state = fields.Selection( + selection=[ + ("pending", "Pending"), + ("confirmed", "Confirmed"), + ("assigned", "Assigned"), + ("done", "Done"), + ("cancel", "Cancel"), + ], + compute="_compute_stock_state", + ) + picking_type_id = fields.Many2one( + comodel_name="stock.picking.type", + string="Operation Type", + readonly=False, + index=True, + ) + location_id = fields.Many2one( + comodel_name="stock.location", + string="Source Location", + readonly=False, + index=True, + check_company=True, + ) + location_dest_id = fields.Many2one( + comodel_name="stock.location", + string="Destination Location", + readonly=False, + index=True, + check_company=True, + ) + stock_analytic_date = fields.Date(string="Analytic date") + stock_analytic_account_id = fields.Many2one( + comodel_name="account.analytic.account", + string="Move Analytic Account", + help="Move created will be assigned to this analytic account", + ) + stock_analytic_distribution = fields.Json( + "Analytic Distribution", + copy=True, + readonly=False, + ) + stock_analytic_line_ids = fields.One2many( + comodel_name="account.analytic.line", + inverse_name="stock_task_id", + string="Analytic Lines", + ) + group_id = fields.Many2one( + comodel_name="procurement.group", + ) + company_id = fields.Many2one(default=lambda self: self.env.company) + + def _compute_scrap_move_count(self): + data = self.env["stock.scrap"].read_group( + [("task_id", "in", self.ids)], ["task_id"], ["task_id"] + ) + count_data = {item["task_id"][0]: item["task_id_count"] for item in data} + for item in self: + item.scrap_count = count_data.get(item.id, 0) + + @api.depends("move_ids", "move_ids.state") + def _compute_allow_moves_action_confirm(self): + for item in self: + item.allow_moves_action_confirm = any( + move.state == "draft" for move in item.move_ids + ) + + @api.depends("move_ids", "move_ids.state") + def _compute_allow_moves_action_assign(self): + for item in self: + item.allow_moves_action_assign = any( + move.state in ("confirmed", "partially_available") + for move in item.move_ids + ) + + @api.depends("move_ids", "move_ids.state") + def _compute_stock_state(self): + for task in self: + task.stock_state = "pending" + if task.move_ids: + states = task.mapped("move_ids.state") + for state in ("confirmed", "assigned", "done", "cancel"): + if state in states: + task.stock_state = state + break + + @api.onchange("picking_type_id") + def _onchange_picking_type_id(self): + self.location_id = self.picking_type_id.default_location_src_id.id + self.location_dest_id = self.picking_type_id.default_location_dest_id.id + + def _check_tasks_with_pending_moves(self): + if self.move_ids and "assigned" in self.mapped("move_ids.state"): + raise UserError( + _("It is not possible to change this with reserved movements in tasks.") + ) + + def _update_moves_info(self): + for item in self: + item._check_tasks_with_pending_moves() + picking_type = item.picking_type_id or item.project_id.picking_type_id + location = item.location_id or item.project_id.location_id + location_dest = item.location_dest_id or item.project_id.location_dest_id + moves = item.move_ids.filtered( + lambda x, loc=location, loc_dest=location_dest: ( + x.state not in ("cancel", "done") + and (x.location_id != loc or x.location_dest_id != loc_dest) + ) + ) + moves.update( + { + "warehouse_id": location.warehouse_id.id, + "location_id": location.id, + "location_dest_id": location_dest.id, + "picking_type_id": picking_type.id, + } + ) + self.action_assign() + + @api.model + def _prepare_procurement_group_vals(self): + return {"name": "Task-ID: %s" % self.id} + + def action_confirm(self): + self.move_ids._action_confirm() + self.move_ids.filtered( + lambda move: move.state not in ("draft", "cancel", "done") + )._trigger_scheduler() + + def action_assign(self): + self.action_confirm() + self.mapped("move_ids")._action_assign() + + def button_scrap(self): + self.ensure_one() + move_items = self.move_ids.filtered(lambda x: x.state not in ("done", "cancel")) + return { + "name": _("Scrap"), + "view_mode": "form", + "res_model": "stock.scrap", + "view_id": self.env.ref("stock.stock_scrap_form_view2").id, + "type": "ir.actions.act_window", + "context": { + "default_task_id": self.id, + "product_ids": move_items.mapped("product_id").ids, + "default_company_id": self.company_id.id, + }, + "target": "new", + } + + def action_cancel(self): + """Cancel the stock moves and remove the analytic lines created from + stock moves when cancelling the task. + """ + self.mapped("move_ids.move_line_ids").write({"quantity": 0}) + # Use sudo to avoid error for users with no access to analytic + self.sudo().stock_analytic_line_ids.unlink() + self.stock_moves_is_locked = True + return True + + def action_toggle_stock_moves_is_locked(self): + self.ensure_one() + self.stock_moves_is_locked = not self.stock_moves_is_locked + return True + + def action_done(self): + picking_ids = self.move_ids.picking_id + for picking in picking_ids: + picking.with_context(skip_sanity_check=True).button_validate() + # Use sudo to avoid error for users with no access to analytic + analytic_line_model = self.env["account.analytic.line"].sudo() + for move in self.move_ids: + vals = move._prepare_analytic_line_from_task() + if vals: + analytic_line_model.create(vals) + + def action_see_move_scrap(self): + self.ensure_one() + action = self.env["ir.actions.actions"]._for_xml_id("stock.action_stock_scrap") + action["domain"] = [("task_id", "=", self.id)] + action["context"] = dict(self._context, default_origin=self.name) + return action + + def write(self, vals): + res = super().write(vals) + if "stage_id" in vals: + stage = self.env["project.task.type"].browse(vals.get("stage_id")) + if stage.done_stock_moves: + # Avoid permissions error if the user does not have access to stock. + self.sudo().action_assign() + # Update info + field_names = ("location_id", "location_dest_id") + if any(vals.get(field) for field in field_names): + self._update_moves_info() + return res + + def unlink(self): + # Use sudo to avoid error to users with no access to analytic + # related to hr_timesheet addon + return super(ProjectTask, self.sudo()).unlink() + + +class ProjectTaskType(models.Model): + _inherit = "project.task.type" + + use_stock_moves = fields.Boolean( + help="If you mark this check, when a task goes to this state, " + "it will use stock moves", + ) + done_stock_moves = fields.Boolean( + help="If you check this box, when a task is in this state, you will not " + "be able to add more stock moves but they can be viewed." + ) diff --git a/project_stock/models/stock_move.py b/project_stock/models/stock_move.py new file mode 100644 index 0000000000..406c218246 --- /dev/null +++ b/project_stock/models/stock_move.py @@ -0,0 +1,134 @@ +# Copyright 2022 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) +from odoo import api, fields, models + + +class StockMove(models.Model): + _inherit = "stock.move" + + task_id = fields.Many2one( + comodel_name="project.task", + string="Related Task", + check_company=True, + ) + raw_material_task_id = fields.Many2one( + comodel_name="project.task", string="Task for material", check_company=True + ) + + @api.onchange("product_id") + def _onchange_product_id(self): + """It is necessary to overwrite the name to prevent set product name + from being auto-defined.""" + res = super()._onchange_product_id() + if self.raw_material_task_id: + self.name = self.raw_material_task_id.name + return res + + def _prepare_analytic_line_from_task(self): + product = self.product_id + company_id = self.env.company + task = self.task_id or self.raw_material_task_id + analytic_account = ( + task.stock_analytic_account_id or task.project_id.analytic_account_id + ) + if not analytic_account: + return False + res = { + "date": ( + task.stock_analytic_date + or task.project_id.stock_analytic_date + or fields.date.today() + ), + "name": task.name + ": " + product.name, + "unit_amount": self.quantity, + "account_id": analytic_account.id, + "user_id": self._uid, + "product_uom_id": self.product_uom.id, + "company_id": analytic_account.company_id.id or self.env.company.id, + "partner_id": task.partner_id.id or task.project_id.partner_id.id or False, + "stock_task_id": task.id, + } + amount_unit = product.with_context(uom=self.product_uom.id)._price_compute( + "standard_price" + )[product.id] + amount = amount_unit * self.quantity or 0.0 + result = round(amount, company_id.currency_id.decimal_places) * -1 + vals = {"amount": result} + analytic_line_fields = self.env["account.analytic.line"]._fields + # Extra fields added in account addon + if "ref" in analytic_line_fields: + vals["ref"] = task.name + if "product_id" in analytic_line_fields: + vals["product_id"] = product.id + # Prevent incoherence when hr_timesheet addon is installed. + if "project_id" in analytic_line_fields: + vals["project_id"] = False + # distributions + if task.stock_analytic_distribution: + new_amount = 0 + for distribution in task.stock_analytic_distribution.values(): + new_amount -= (amount / 100) * distribution + vals["amount"] = new_amount + res.update(vals) + return res + + @api.model + def default_get(self, fields_list): + defaults = super().default_get(fields_list) + if self.env.context.get("default_raw_material_task_id"): + task = self.env["project.task"].browse( + self.env.context.get("default_raw_material_task_id") + ) + if not task.group_id: + task.group_id = self.env["procurement.group"].create( + task._prepare_procurement_group_vals() + ) + defaults.update( + { + "group_id": task.group_id.id, + "location_id": ( + task.location_id.id or task.project_id.location_id.id + ), + "location_dest_id": ( + task.location_dest_id.id or task.project_id.location_dest_id.id + ), + "picking_type_id": ( + task.picking_type_id.id or task.project_id.picking_type_id.id + ), + } + ) + return defaults + + def action_task_product_forecast_report(self): + self.ensure_one() + action = self.product_id.action_product_forecast_report() + action["context"] = { + "active_id": self.product_id.id, + "active_model": "product.product", + "move_to_match_ids": self.ids, + } + warehouse = self.warehouse_id + if warehouse: + action["context"]["warehouse"] = warehouse.id + return action + + +class StockMoveLine(models.Model): + _inherit = "stock.move.line" + + task_id = fields.Many2one( + comodel_name="project.task", + string="Task", + compute="_compute_task_id", + store=True, + ) + + @api.depends("move_id.raw_material_task_id", "move_id.task_id") + def _compute_task_id(self): + for item in self: + task = ( + item.move_id.raw_material_task_id + if item.move_id.raw_material_task_id + else item.move_id.task_id + ) + item.task_id = task if task else False diff --git a/project_stock/models/stock_scrap.py b/project_stock/models/stock_scrap.py new file mode 100644 index 0000000000..e0f3243e46 --- /dev/null +++ b/project_stock/models/stock_scrap.py @@ -0,0 +1,25 @@ +# Copyright 2022 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) +from odoo import api, fields, models + + +class StockMove(models.Model): + _inherit = "stock.scrap" + + task_id = fields.Many2one( + comodel_name="project.task", string="Task", check_company=True + ) + + @api.onchange("task_id") + def _onchange_task_id(self): + if self.task_id: + self.location_id = self.task_id.move_raw_ids.filtered( + lambda x: x.state not in ("done", "cancel") + ) and (self.task_id.location_src_id.id or self.task_id.location_dest_id.id) + + def _prepare_move_values(self): + vals = super()._prepare_move_values() + if self.task_id: + vals["origin"] = vals["origin"] or self.task_id.name + vals.update({"raw_material_task_id": self.task_id.id}) + return vals diff --git a/project_stock/pyproject.toml b/project_stock/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/project_stock/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/project_stock/readme/CONFIGURE.md b/project_stock/readme/CONFIGURE.md new file mode 100644 index 0000000000..278ec8d258 --- /dev/null +++ b/project_stock/readme/CONFIGURE.md @@ -0,0 +1,25 @@ +To configure this module, you need to: + +1. Go to *Inventory -\> Configuration -\> Settings* and check "Storage + Locations" option. + +2. Go to *Inventory -\> Configuration -\> Operation types*. + +3. Create a new operation type with the following options: + - \`Operation type\`: Task material + - \`Code\`: TM + - \`Type of operation\`: Delivery + - \`Default Source Location\`: WH/Stock + - \`Default Destination Location\`: WH/Stock/Shelf 1 + +4. Go to *Project -\> Configuration -\> Projects*. + +5. Create a new project with the following options: + - \`Name\`: Task material + - \`Operation type\`: Task material + +6. Go to *Project -\> Configuration -\> Task Stages* and edit some records. + - \`In progress\`: Check Use Stock Moves option and add the created + project. + - \`Done\`: Check Use Stock Moves option + Done Stock Moves and add + the created project. diff --git a/project_stock/readme/CONTRIBUTORS.md b/project_stock/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..5fee390427 --- /dev/null +++ b/project_stock/readme/CONTRIBUTORS.md @@ -0,0 +1,3 @@ +- [Tecnativa](https://www.tecnativa.com): + - Víctor Martínez + - Pedro M. Baeza diff --git a/project_stock/readme/DESCRIPTION.md b/project_stock/readme/DESCRIPTION.md new file mode 100644 index 0000000000..25fda0ebf0 --- /dev/null +++ b/project_stock/readme/DESCRIPTION.md @@ -0,0 +1 @@ +This module allows to consume products directly from a project task. diff --git a/project_stock/readme/USAGE.md b/project_stock/readme/USAGE.md new file mode 100644 index 0000000000..eea7ef970f --- /dev/null +++ b/project_stock/readme/USAGE.md @@ -0,0 +1,21 @@ +1. Go to *Projects -\> Task material (project)* and create a task and + edit it. + +2. *Stock Info* is displayed in the *Extra info* tab with the same + project information, but it can be modified. + +3. Add some product to *Stock Info* tab and set some initial demand (1 + for example). + +4. Click on the button *Confirm material* to confirm all moves. + +5. Change the stage to Done. + +6. *Stock Info* tab is readonly and some buttons show in header: + - \`Check availability materials\`: Product availability will be + checked. + - \`Transfer Materials\`: Stock moves are confirmed and moved from + one location to another. + - \`Unreserve\`: Remove the reservation stock of the products. + - \`Cancel Materials\`: Set the moves of the products as cancelled. + - \`Scrap\`: Allows the defined products to be scrapped. diff --git a/project_stock/static/description/icon.png b/project_stock/static/description/icon.png new file mode 100644 index 0000000000..3a0328b516 Binary files /dev/null and b/project_stock/static/description/icon.png differ diff --git a/project_stock/static/description/index.html b/project_stock/static/description/index.html new file mode 100644 index 0000000000..829ddbd55b --- /dev/null +++ b/project_stock/static/description/index.html @@ -0,0 +1,485 @@ + + + + + +Project Stock + + + +
+

Project Stock

+ + +

Beta License: AGPL-3 OCA/project Translate me on Weblate Try me on Runboat

+

This module allows to consume products directly from a project task.

+

Table of contents

+ +
+

Configuration

+

To configure this module, you need to:

+
    +
  1. Go to Inventory -> Configuration -> Settings and check “Storage +Locations” option.
  2. +
  3. Go to Inventory -> Configuration -> Operation types.
  4. +
  5. Create a new operation type with the following options:
      +
    • `Operation type`: Task material
    • +
    • `Code`: TM
    • +
    • `Type of operation`: Delivery
    • +
    • `Default Source Location`: WH/Stock
    • +
    • `Default Destination Location`: WH/Stock/Shelf 1
    • +
    +
  6. +
  7. Go to Project -> Configuration -> Projects.
  8. +
  9. Create a new project with the following options:
      +
    • `Name`: Task material
    • +
    • `Operation type`: Task material
    • +
    +
  10. +
  11. Go to Project -> Configuration -> Task Stages and edit some +records.
      +
    • `In progress`: Check Use Stock Moves option and add the created +project.
    • +
    • `Done`: Check Use Stock Moves option + Done Stock Moves and add +the created project.
    • +
    +
  12. +
+
+
+

Usage

+
    +
  1. Go to Projects -> Task material (project) and create a task and +edit it.
  2. +
  3. Stock Info is displayed in the Extra info tab with the same +project information, but it can be modified.
  4. +
  5. Add some product to Stock Info tab and set some initial demand (1 +for example).
  6. +
  7. Click on the button Confirm material to confirm all moves.
  8. +
  9. Change the stage to Done.
  10. +
  11. Stock Info tab is readonly and some buttons show in header:
      +
    • `Check availability materials`: Product availability will be +checked.
    • +
    • `Transfer Materials`: Stock moves are confirmed and moved from +one location to another.
    • +
    • `Unreserve`: Remove the reservation stock of the products.
    • +
    • `Cancel Materials`: Set the moves of the products as cancelled.
    • +
    • `Scrap`: Allows the defined products to be scrapped.
    • +
    +
  12. +
+
+
+

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 to smash it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Tecnativa
  • +
+
+
+

Contributors

+
    +
  • Tecnativa:
      +
    • Víctor Martínez
    • +
    • Pedro M. Baeza
    • +
    +
  • +
+
+
+

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:

+

victoralmau

+

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

+

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

+
+
+
+ + diff --git a/project_stock/tests/__init__.py b/project_stock/tests/__init__.py new file mode 100644 index 0000000000..cc6748ba93 --- /dev/null +++ b/project_stock/tests/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2022 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import test_project_stock diff --git a/project_stock/tests/common.py b/project_stock/tests/common.py new file mode 100644 index 0000000000..4ee8a6ea2f --- /dev/null +++ b/project_stock/tests/common.py @@ -0,0 +1,87 @@ +# Copyright 2022 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.tests import Form, common +from odoo.tests.common import new_test_user + +from odoo.addons.base.tests.common import DISABLED_MAIL_CONTEXT + + +class TestProjectStockBase(common.TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, **DISABLED_MAIL_CONTEXT)) + cls.product_a = cls.env["product.product"].create( + {"name": "Test product A", "detailed_type": "product", "standard_price": 10} + ) + cls.product_b = cls.env["product.product"].create( + {"name": "Test product B", "detailed_type": "product", "standard_price": 20} + ) + cls.product_c = cls.env["product.product"].create( + {"name": "Test product C", "detailed_type": "product", "standard_price": 0} + ) + cls.picking_type = cls.env.ref("project_stock.stock_picking_type_tm_test") + cls.location = cls.picking_type.default_location_src_id + cls.location_dest = cls.picking_type.default_location_dest_id + cls.plan = cls.env["account.analytic.plan"].create( + { + "name": "Projects Plan", + } + ) + cls.analytic_account = cls.env["account.analytic.account"].create( + { + "name": "Test account", + "plan_id": cls.plan.id, + }, + ) + cls.analytic_account_2 = cls.analytic_account.copy( + { + "name": "Test account 2", + "plan_id": cls.plan.id, + } + ) + cls.project = cls.env.ref("project_stock.project_project_tm_test") + cls.project.analytic_account_id = cls.analytic_account + cls.stage_in_progress = cls.env.ref("project.project_stage_1") + cls.stage_done = cls.env.ref("project.project_stage_2") + group_stock_user = "stock.group_stock_user" + cls.basic_user = new_test_user( + cls.env, + login="basic-user", + groups="project.group_project_user,%s" % group_stock_user, + ) + new_test_user( + cls.env, + login="manager-user", + groups="project.group_project_manager,%s,analytic.group_analytic_accounting" + % group_stock_user, + ) + new_test_user( + cls.env, + login="project-task-user", + groups="project.group_project_user,stock.group_stock_user", + ) + + def _prepare_context_task(self): + return { + "default_project_id": self.project.id, + "default_stage_id": self.stage_in_progress.id, + # We need to set default values according to compute store fields + "default_location_id": self.project.location_id.id, + "default_location_dest_id": self.project.location_dest_id.id, + "default_picking_type_id": self.project.picking_type_id.id, + } + + def _create_task(self, products): + task_form = Form( + self.env["project.task"].with_context(**self._prepare_context_task(self)) + ) + task_form.name = "Test task" + # Save task to use default_get() correctlly in stock.moves + task_form.save() + for product in products: + with task_form.move_ids.new() as move_form: + move_form.product_id = product[0] + move_form.product_uom_qty = product[1] + return task_form.save() diff --git a/project_stock/tests/test_project_stock.py b/project_stock/tests/test_project_stock.py new file mode 100644 index 0000000000..09f4b0102f --- /dev/null +++ b/project_stock/tests/test_project_stock.py @@ -0,0 +1,307 @@ +# Copyright 2022-2024 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from odoo import fields +from odoo.tests import Form +from odoo.tests.common import users +from odoo.tools import mute_logger + +from .common import TestProjectStockBase + + +class TestProjectStock(TestProjectStockBase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls._create_stock_quant(cls, cls.product_a, cls.location, 2) + cls._create_stock_quant(cls, cls.product_b, cls.location, 1) + cls._create_stock_quant(cls, cls.product_c, cls.location, 1) + cls.task = cls._create_task(cls, [(cls.product_a, 2), (cls.product_b, 1)]) + cls.move_product_a = cls.task.move_ids.filtered( + lambda x: x.product_id == cls.product_a + ) + cls.move_product_b = cls.task.move_ids.filtered( + lambda x: x.product_id == cls.product_b + ) + cls.env.ref("base.user_admin").write( + { + "groups_id": [ + (4, cls.env.ref("analytic.group_analytic_accounting").id), + ], + } + ) + + def _create_stock_quant(self, product, location, qty): + self.env["stock.quant"].create( + {"product_id": product.id, "location_id": location.id, "quantity": qty} + ) + + def test_project_task_misc(self): + self.assertTrue(self.task.group_id) + self.assertEqual(self.task.picking_type_id, self.picking_type) + self.assertEqual(self.task.location_id, self.location) + self.assertEqual(self.task.location_dest_id, self.location_dest) + self.assertEqual(self.move_product_a.name, self.task.name) + self.assertEqual(self.move_product_a.reference, self.task.name) + self.assertEqual(self.move_product_a.location_id, self.location) + self.assertEqual(self.move_product_a.location_dest_id, self.location_dest) + self.assertEqual(self.move_product_a.picking_type_id, self.picking_type) + self.assertEqual(self.move_product_a.raw_material_task_id, self.task) + self.assertEqual(self.move_product_b.location_id, self.location) + self.assertEqual(self.move_product_b.location_dest_id, self.location_dest) + self.assertEqual(self.move_product_b.picking_type_id, self.picking_type) + self.assertEqual(self.move_product_b.raw_material_task_id, self.task) + + def _test_task_analytic_lines_from_task(self, amount): + self.task = self.env["project.task"].browse(self.task.id) + # Prevent error when hr_timesheet addon is installed. + stock_analytic_lines = self.task.sudo().stock_analytic_line_ids + self.assertEqual(len(stock_analytic_lines), 2) + self.assertEqual(sum(stock_analytic_lines.mapped("unit_amount")), 3) + self.assertEqual(sum(stock_analytic_lines.mapped("amount")), amount) + self.assertIn( + self.analytic_account, + stock_analytic_lines.mapped("account_id"), + ) + # Prevent incoherence when hr_timesheet addon is installed. + if "project_id" in self.task.stock_analytic_line_ids._fields: + self.assertFalse(self.task.stock_analytic_line_ids.project_id) + + def test_project_task_without_analytic_account(self): + self.task = self.env["project.task"].browse(self.task.id) + # Prevent error when hr_timesheet addon is installed. + if "allow_timesheets" in self.task.project_id._fields: + self.task.project_id.allow_timesheets = False + self.task.project_id.analytic_account_id = False + self.task.write({"stage_id": self.stage_done.id}) + self.task.action_done() + self.assertFalse(self.task.stock_analytic_line_ids) + + @users("manager-user") + def test_project_task_without_analytic_account_manager_user(self): + self.test_project_task_without_analytic_account() + + def test_project_task_user_access_without_stock_group(self): + self.basic_user.write( + { + "groups_id": [(6, 0, [self.env.ref("project.group_project_user").id])], + } + ) + task_form = Form(self.task.with_user(self.basic_user)) + self.assertEqual(task_form.project_id, self.project) + + def test_project_task_analytic_lines_without_tags(self): + self.task = self.env["project.task"].browse(self.task.id) + self.task.write({"stage_id": self.stage_done.id}) + self.task.action_done() + self._test_task_analytic_lines_from_task(-40) + self.assertEqual( + fields.first(self.task.stock_analytic_line_ids).date, + fields.Date.from_string("1990-01-01"), + ) + + @users("manager-user") + def test_project_task_analytic_lines_without_tags_manager_user(self): + self.test_project_task_analytic_lines_without_tags() + + def test_project_task_analytic_lines_with_tag_1(self): + self.task = self.env["project.task"].browse(self.task.id) + self.task.write( + { + "stock_analytic_date": "1991-01-01", + } + ) + self.task.write({"stage_id": self.stage_done.id}) + self.task.action_done() + self._test_task_analytic_lines_from_task(-40) + self.assertEqual( + fields.first(self.task.stock_analytic_line_ids).date, + fields.Date.from_string("1991-01-01"), + ) + + @users("manager-user") + def test_project_task_analytic_lines_with_tag_1_manager_user(self): + self.task.stock_analytic_distribution = {self.analytic_account.id: 100} + self.test_project_task_analytic_lines_with_tag_1() + + def test_project_task_analytic_lines_with_tag_2(self): + self.task = self.env["project.task"].browse(self.task.id) + self.task.project_id.stock_analytic_date = False + self.task.write({"stage_id": self.stage_done.id}) + self.task.action_done() + self._test_task_analytic_lines_from_task(-40) + self.assertEqual( + fields.first(self.task.stock_analytic_line_ids).date, fields.date.today() + ) + + @users("manager-user") + def test_project_task_analytic_lines_with_tag_2_manager_user(self): + self.task.stock_analytic_distribution = { + self.analytic_account.id: 50, + self.analytic_account_2.id: 50, + } + self.test_project_task_analytic_lines_with_tag_2() + + def test_project_task_process_done(self): + self.task = self.env["project.task"].browse(self.task.id) + self.assertEqual(self.move_product_a.state, "draft") + self.assertEqual(self.move_product_b.state, "draft") + # Change task stage (auto-confirm + auto-assign) + self.task.write({"stage_id": self.stage_done.id}) + self.assertEqual(self.move_product_a.state, "assigned") + self.assertEqual(self.move_product_b.state, "assigned") + self.assertEqual(self.move_product_a.quantity, 2) + self.assertEqual(self.move_product_b.quantity, 1) + self.assertTrue(self.task.stock_moves_is_locked) + self.task.action_toggle_stock_moves_is_locked() + self.assertFalse(self.task.stock_moves_is_locked) + # Add new stock_move + self.task.write({"stage_id": self.stage_in_progress.id}) + task_form = Form(self.task) + with task_form.move_ids.new() as move_form: + move_form.product_id = self.product_c + move_form.product_uom_qty = 1 + task_form.save() + move_product_c = self.task.move_ids.filtered( + lambda x: x.product_id == self.product_c + ) + self.assertEqual(move_product_c.state, "draft") + self.task.action_assign() + self.assertEqual(move_product_c.state, "assigned") + self.task.write({"stage_id": self.stage_done.id}) + # action_done + self.task.action_done() + self.assertEqual(self.move_product_a.state, "done") + self.assertEqual(self.move_product_b.state, "done") + self.assertEqual(self.move_product_a.quantity, 2) + self.assertEqual(self.move_product_b.quantity, 1) + self.assertEqual(move_product_c.quantity, 1) + + @users("basic-user") + def test_project_task_process_done_basic_user(self): + self.test_project_task_process_done() + + @mute_logger("odoo.models.unlink") + def test_project_task_process_cancel(self): + self.task = self.env["project.task"].browse(self.task.id) + self.assertEqual(self.move_product_a.state, "draft") + self.assertEqual(self.move_product_b.state, "draft") + # Change task stage + self.task.write({"stage_id": self.stage_done.id}) + self.assertEqual(self.move_product_a.state, "assigned") + self.assertEqual(self.move_product_b.state, "assigned") + # action_done + self.task.action_done() + self.assertEqual(self.move_product_a.state, "done") + self.assertEqual(self.move_product_b.state, "done") + self.assertEqual(self.move_product_a.quantity, 2) + self.assertEqual(self.move_product_b.quantity, 1) + self.assertTrue(self.task.sudo().stock_analytic_line_ids) + # action_cancel + self.task.action_cancel() + self.assertEqual(self.move_product_a.state, "done") + self.assertEqual(self.move_product_b.state, "done") + self.assertEqual(self.move_product_a.quantity, 0) + self.assertEqual(self.move_product_b.quantity, 0) + self.assertFalse(self.task.stock_analytic_line_ids) + quant_a = self.product_a.stock_quant_ids.filtered( + lambda x: x.location_id == self.location + ) + quant_b = self.product_b.stock_quant_ids.filtered( + lambda x: x.location_id == self.location + ) + quant_c = self.product_c.stock_quant_ids.filtered( + lambda x: x.location_id == self.location + ) + self.assertEqual(quant_a.quantity, 2) + self.assertEqual(quant_b.quantity, 1) + self.assertEqual(quant_c.quantity, 1) + + @users("manager-user") + def test_project_task_process_cancel_manager_user(self): + self.test_project_task_process_cancel() + + @mute_logger("odoo.models.unlink") + def test_project_task_process_01(self): + """Product A move cancel + Product B move OK.""" + self.task = self.env["project.task"].browse(self.task.id) + self.move_product_b.unlink() + self.assertEqual(self.move_product_a.state, "draft") + # Confirm + Edit to qty=0 + self.task.action_confirm() + self.assertEqual(self.move_product_a.state, "assigned") + self.move_product_a.product_uom_qty = 0 + self.task.action_done() + self.assertEqual(self.move_product_a.state, "cancel") + # Add extra line + task_form = Form(self.task) + with task_form.move_ids.new() as move_form: + move_form.product_id = self.product_b + move_form.product_uom_qty = 1 + task_form.save() + self.move_product_b = self.task.move_ids.filtered( + lambda x: x.product_id == self.product_b + ) + self.task.action_confirm() + self.assertEqual(self.move_product_b.state, "assigned") + self.task.action_done() + self.assertEqual(self.move_product_b.state, "done") + + def test_project_task_process_02(self): + self.task.action_confirm() + self.assertEqual(self.move_product_a.state, "assigned") + self.assertEqual(self.move_product_b.state, "assigned") + self.task.action_done() + self.assertEqual(self.move_product_a.state, "done") + self.assertEqual(self.move_product_b.state, "done") + self.assertEqual(len(self.task.stock_analytic_line_ids), 2) + self.task.action_done() + + def test_project_task_action_cancel(self): + self.assertTrue(self.env["project.task"].browse(self.task.id).action_cancel()) + + @users("basic-user") + def test_project_task_action_cancel_basic_user(self): + self.test_project_task_action_cancel() + + def test_project_task_action_done(self): + self.task = self.env["project.task"].browse(self.task.id) + self.task.write({"stage_id": self.stage_done.id}) + self.task.action_done() + self.assertTrue(self.task.sudo().stock_analytic_line_ids) + + @users("basic-user") + def test_project_task_action_done_basic_user(self): + self.test_project_task_action_done() + + @mute_logger("odoo.models.unlink") + def test_project_task_unlink(self): + self.assertTrue(self.env["project.task"].browse(self.task.id).unlink()) + + @users("basic-user") + def test_project_task_unlink_basic_user(self): + self.test_project_task_unlink() + + @mute_logger("odoo.models.unlink") + def test_project_project_onchange(self): + new_type = self.env.ref("stock.picking_type_out") + self.project.write({"picking_type_id": new_type.id}) + self.project._onchange_picking_type_id() + self.assertEqual(self.project.location_id, new_type.default_location_src_id) + self.assertEqual( + self.project.location_dest_id, new_type.default_location_dest_id + ) + move = fields.first(self.task.move_ids) + self.assertEqual(move.location_id, new_type.default_location_src_id) + + def test_project_task_scrap(self): + move = fields.first(self.task.move_ids) + scrap = self.env["stock.scrap"].create( + { + "product_id": move.product_id.id, + "product_uom_id": move.product_id.uom_id.id, + "scrap_qty": 1, + "task_id": self.task.id, + } + ) + scrap.do_scrap() + self.assertEqual(scrap.move_ids.raw_material_task_id, self.task) diff --git a/project_stock/views/project_project_view.xml b/project_stock/views/project_project_view.xml new file mode 100644 index 0000000000..2d97ba2685 --- /dev/null +++ b/project_stock/views/project_project_view.xml @@ -0,0 +1,24 @@ + + + + project.project.form + project.project + + + + + + + + + + + + + diff --git a/project_stock/views/project_task_type_view.xml b/project_stock/views/project_task_type_view.xml new file mode 100644 index 0000000000..ed9dbe8b3d --- /dev/null +++ b/project_stock/views/project_task_type_view.xml @@ -0,0 +1,14 @@ + + + + project.task.type.form + project.task.type + + + + + + + + + diff --git a/project_stock/views/project_task_view.xml b/project_stock/views/project_task_view.xml new file mode 100644 index 0000000000..844934da23 --- /dev/null +++ b/project_stock/views/project_task_view.xml @@ -0,0 +1,137 @@ + + + + project.task.form + project.task + + + + + + + + + + + +