diff --git a/hr_expense_invoice/README.rst b/hr_expense_invoice/README.rst new file mode 100644 index 000000000..bb9fbeabf --- /dev/null +++ b/hr_expense_invoice/README.rst @@ -0,0 +1,122 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +================================ +Supplier invoices on HR expenses +================================ + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:85b7c666fd5804c4bc60c81b824e7fd5b22a60e9b7be702b07a7fb2deea2edfe + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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/license-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%2Fhr--expense-lightgray.png?logo=github + :target: https://github.com/OCA/hr-expense/tree/19.0/hr_expense_invoice + :alt: OCA/hr-expense +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/hr-expense-19-0/hr-expense-19-0-hr_expense_invoice + :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/hr-expense&target_branch=19.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module should be used when a vendor bill is paid by an employee. It +allows to register a vendor bill, adding the corresponding journal items +to transfer the debt to the employee. + +You can set the vendor bill in the Expense or create a new one. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +- Create an expense paid by an employee. +- Select a Vendor Bill or create a new one with "Create Vendor Bill" + button. +- Clic on Post Journal Entries button. +- At this point: + + - A new Transfer Entry has been created to transfer the debt from the + Vendor to the Employee. + - Vendor Bill has been reconciled with the Transfer Entry. + +- Go to the Transfer move by clicking on the "Transfer Moves" button. +- Pay this Entry clicking on the Gears > Pay. +- You will see: + + - Vendor Bill has been reconciled with the Transfer Entry Vendor line. + - Transfer Entry Employee line has been paid. + +Known issues / Roadmap +====================== + +- Multiple payment terms for a vendor bills are not handled correctly. +- Partial reconcile vendor bill are also not correctly handled. +- Since Odoo 19 only supports isolated expenses and clear vendor + bill/receipt creation, invoice_id field on expense should be migrated + to account_move_id field and deeply refactor the module. + +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 `__: + + - Pedro M. Baeza + - Vicent Cubells + - Víctor Martínez + +- Kitti Upariphutthiphong +- Rattapong Chokmasermkul +- Saran Lim. +- Eduardo de Miguel (``Moduon ``\ \_\_) + +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. + +This module is part of the `OCA/hr-expense `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/hr_expense_invoice/__init__.py b/hr_expense_invoice/__init__.py new file mode 100644 index 000000000..69f7babdf --- /dev/null +++ b/hr_expense_invoice/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import models diff --git a/hr_expense_invoice/__manifest__.py b/hr_expense_invoice/__manifest__.py new file mode 100644 index 000000000..5add07f03 --- /dev/null +++ b/hr_expense_invoice/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright 2015-2021 Tecnativa - Pedro M. Baeza +# Copyright 2017 Tecnativa - Vicent Cubells +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Supplier invoices on HR expenses", + "version": "19.0.1.0.0", + "category": "Human Resources", + "author": "Tecnativa, Odoo Community Association (OCA)", + "license": "AGPL-3", + "website": "https://github.com/OCA/hr-expense", + "depends": ["hr_expense"], + "data": [ + "views/hr_expense_views.xml", + ], + "installable": True, +} diff --git a/hr_expense_invoice/i18n/cs_CZ.po b/hr_expense_invoice/i18n/cs_CZ.po new file mode 100644 index 000000000..17f9e98ed --- /dev/null +++ b/hr_expense_invoice/i18n/cs_CZ.po @@ -0,0 +1,129 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_expense_invoice +# +# Translators: +# Lukáš Spurný , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-02-23 03:45+0000\n" +"PO-Revision-Date: 2018-02-23 03:45+0000\n" +"Last-Translator: Lukáš Spurný , 2018\n" +"Language-Team: Czech (Czech Republic) (https://www.transifex.com/oca/" +"teams/23907/cs_CZ/)\n" +"Language: cs_CZ\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" + +#. module: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.view_move_form +msgid "Expense" +msgstr "" + +#. module: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +msgid "Create Vendor Bill" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense +msgid "Expense" +msgstr "Výdaje" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense_sheet +msgid "Expense Report" +msgstr "Zpráva o výdajích" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__expense_ids +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__expense_ids +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_payment__expense_ids +#, fuzzy +msgid "Expenses" +msgstr "Výdaje" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense_sheet__invoice_count +#, fuzzy +msgid "Invoice Count" +msgstr "Faktura" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +#, fuzzy, python-format +msgid "Invoices" +msgstr "Faktura" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move +msgid "Journal Entry" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move_line +msgid "Journal Item" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,help:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,help:hr_expense_invoice.field_account_move__source_invoice_expense_id +#: model:ir.model.fields,help:hr_expense_invoice.field_account_payment__source_invoice_expense_id +msgid "" +"Reference to the expense with a linked invoice that generated thistransfer " +"journal entry" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__sheet_id_state +msgid "Sheet state" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__source_invoice_expense_id +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_payment__source_invoice_expense_id +msgid "Source Invoice Expense" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__transfer_move_ids +msgid "Transfer Move" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__invoice_id +msgid "Vendor Bill" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#, python-format +msgid "" +"Vendor bill amount mismatch!\n" +"Please make sure amount in vendor bills equal to amount of its expense lines" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense.py:0 +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#, python-format +msgid "Vendor bill state must be Posted" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/account_move.py:0 +#, python-format +msgid "" +"You can't change the total amount, as there's an expense linked to this " +"invoice." +msgstr "" diff --git a/hr_expense_invoice/i18n/de.po b/hr_expense_invoice/i18n/de.po new file mode 100644 index 000000000..93e1e9ff0 --- /dev/null +++ b/hr_expense_invoice/i18n/de.po @@ -0,0 +1,127 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_expense_invoice +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2019-07-12 14:43+0000\n" +"Last-Translator: Maria Sparenberg \n" +"Language-Team: none\n" +"Language: de\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 3.7.1\n" + +#. module: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.view_move_form +msgid "Expense" +msgstr "" + +#. module: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +#, fuzzy +msgid "Create Vendor Bill" +msgstr "Lieferantenrechnung" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense +msgid "Expense" +msgstr "Spesen" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense_sheet +msgid "Expense Report" +msgstr "Spesen-Bericht" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__expense_ids +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__expense_ids +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_payment__expense_ids +#, fuzzy +msgid "Expenses" +msgstr "Spesen" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense_sheet__invoice_count +#, fuzzy +msgid "Invoice Count" +msgstr "Rechnung" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +#, fuzzy, python-format +msgid "Invoices" +msgstr "Rechnung" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move +msgid "Journal Entry" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move_line +msgid "Journal Item" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,help:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,help:hr_expense_invoice.field_account_move__source_invoice_expense_id +#: model:ir.model.fields,help:hr_expense_invoice.field_account_payment__source_invoice_expense_id +msgid "" +"Reference to the expense with a linked invoice that generated thistransfer " +"journal entry" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__sheet_id_state +msgid "Sheet state" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__source_invoice_expense_id +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_payment__source_invoice_expense_id +msgid "Source Invoice Expense" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__transfer_move_ids +msgid "Transfer Move" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__invoice_id +msgid "Vendor Bill" +msgstr "Lieferantenrechnung" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#, python-format +msgid "" +"Vendor bill amount mismatch!\n" +"Please make sure amount in vendor bills equal to amount of its expense lines" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense.py:0 +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#, python-format +msgid "Vendor bill state must be Posted" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/account_move.py:0 +#, python-format +msgid "" +"You can't change the total amount, as there's an expense linked to this " +"invoice." +msgstr "" diff --git a/hr_expense_invoice/i18n/es.po b/hr_expense_invoice/i18n/es.po new file mode 100644 index 000000000..c51105990 --- /dev/null +++ b/hr_expense_invoice/i18n/es.po @@ -0,0 +1,140 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_expense_invoice +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-09-27 16:34+0000\n" +"PO-Revision-Date: 2023-10-29 23:38+0000\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: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.view_move_form +msgid "Expense" +msgstr "" + +#. module: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +msgid "Create Vendor Bill" +msgstr "Crear Factura de Vendedor" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense +msgid "Expense" +msgstr "Gasto" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense_sheet +msgid "Expense Report" +msgstr "Informe de gastos" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__expense_ids +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__expense_ids +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_payment__expense_ids +msgid "Expenses" +msgstr "Gastos" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense_sheet__invoice_count +msgid "Invoice Count" +msgstr "Conteo de Factura" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +#, python-format +msgid "Invoices" +msgstr "Facturas" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move +msgid "Journal Entry" +msgstr "Entrada Diaria" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move_line +msgid "Journal Item" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,help:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,help:hr_expense_invoice.field_account_move__source_invoice_expense_id +#: model:ir.model.fields,help:hr_expense_invoice.field_account_payment__source_invoice_expense_id +msgid "" +"Reference to the expense with a linked invoice that generated thistransfer " +"journal entry" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__sheet_id_state +msgid "Sheet state" +msgstr "Estado de la hoja" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__source_invoice_expense_id +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_payment__source_invoice_expense_id +msgid "Source Invoice Expense" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__transfer_move_ids +msgid "Transfer Move" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__invoice_id +msgid "Vendor Bill" +msgstr "Factura de Proveedor" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#, python-format +msgid "" +"Vendor bill amount mismatch!\n" +"Please make sure amount in vendor bills equal to amount of its expense lines" +msgstr "" +"El importe de la factura del proveedor no coincide.\n" +"Asegúrese de que el importe de la factura del proveedor coincide con el " +"importe de sus líneas de gasto" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense.py:0 +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#, python-format +msgid "Vendor bill state must be Posted" +msgstr "Debe publicarse el estado de la factura del proveedor" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/account_move.py:0 +#, python-format +msgid "" +"You can't change the total amount, as there's an expense linked to this " +"invoice." +msgstr "" +"No puede modificar el importe total, ya que hay un gasto vinculado a esta " +"factura." + +#~ msgid "Expense Report State" +#~ msgstr "Estado del Informe de Gastos" + +#~ msgid "Register Payment" +#~ msgstr "Registrar Pago" + +#, python-format +#~ msgid "Register payment on expense's invoice is not allowed" +#~ msgstr "No se permite registrar el pago en la factura del gasto" diff --git a/hr_expense_invoice/i18n/fr.po b/hr_expense_invoice/i18n/fr.po new file mode 100644 index 000000000..5b2061c64 --- /dev/null +++ b/hr_expense_invoice/i18n/fr.po @@ -0,0 +1,129 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_expense_invoice +# +# Translators: +# guillaume bauer , 2017 +# Alexandre Fayolle , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-02-23 03:45+0000\n" +"PO-Revision-Date: 2018-02-23 03:45+0000\n" +"Last-Translator: Alexandre Fayolle , 2018\n" +"Language-Team: French (https://www.transifex.com/oca/teams/23907/fr/)\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: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.view_move_form +msgid "Expense" +msgstr "" + +#. module: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +msgid "Create Vendor Bill" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense +msgid "Expense" +msgstr "Note de frais" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense_sheet +msgid "Expense Report" +msgstr "Rapport de dépenses" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__expense_ids +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__expense_ids +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_payment__expense_ids +#, fuzzy +msgid "Expenses" +msgstr "Note de frais" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense_sheet__invoice_count +#, fuzzy +msgid "Invoice Count" +msgstr "Facture" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +#, fuzzy, python-format +msgid "Invoices" +msgstr "Facture" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move +msgid "Journal Entry" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move_line +msgid "Journal Item" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,help:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,help:hr_expense_invoice.field_account_move__source_invoice_expense_id +#: model:ir.model.fields,help:hr_expense_invoice.field_account_payment__source_invoice_expense_id +msgid "" +"Reference to the expense with a linked invoice that generated thistransfer " +"journal entry" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__sheet_id_state +msgid "Sheet state" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__source_invoice_expense_id +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_payment__source_invoice_expense_id +msgid "Source Invoice Expense" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__transfer_move_ids +msgid "Transfer Move" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__invoice_id +msgid "Vendor Bill" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#, python-format +msgid "" +"Vendor bill amount mismatch!\n" +"Please make sure amount in vendor bills equal to amount of its expense lines" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense.py:0 +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#, python-format +msgid "Vendor bill state must be Posted" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/account_move.py:0 +#, python-format +msgid "" +"You can't change the total amount, as there's an expense linked to this " +"invoice." +msgstr "" diff --git a/hr_expense_invoice/i18n/hr.po b/hr_expense_invoice/i18n/hr.po new file mode 100644 index 000000000..408f0ddb2 --- /dev/null +++ b/hr_expense_invoice/i18n/hr.po @@ -0,0 +1,129 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_expense_invoice +# +# Translators: +# Bole , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-02-23 03:45+0000\n" +"PO-Revision-Date: 2018-02-23 03:45+0000\n" +"Last-Translator: Bole , 2017\n" +"Language-Team: Croatian (https://www.transifex.com/oca/teams/23907/hr/)\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" + +#. module: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.view_move_form +msgid "Expense" +msgstr "" + +#. module: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +msgid "Create Vendor Bill" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense +msgid "Expense" +msgstr "Trošak" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense_sheet +msgid "Expense Report" +msgstr "Izvještaj troškova" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__expense_ids +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__expense_ids +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_payment__expense_ids +#, fuzzy +msgid "Expenses" +msgstr "Trošak" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense_sheet__invoice_count +#, fuzzy +msgid "Invoice Count" +msgstr "Račun" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +#, fuzzy, python-format +msgid "Invoices" +msgstr "Račun" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move +msgid "Journal Entry" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move_line +msgid "Journal Item" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,help:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,help:hr_expense_invoice.field_account_move__source_invoice_expense_id +#: model:ir.model.fields,help:hr_expense_invoice.field_account_payment__source_invoice_expense_id +msgid "" +"Reference to the expense with a linked invoice that generated thistransfer " +"journal entry" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__sheet_id_state +msgid "Sheet state" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__source_invoice_expense_id +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_payment__source_invoice_expense_id +msgid "Source Invoice Expense" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__transfer_move_ids +msgid "Transfer Move" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__invoice_id +msgid "Vendor Bill" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#, python-format +msgid "" +"Vendor bill amount mismatch!\n" +"Please make sure amount in vendor bills equal to amount of its expense lines" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense.py:0 +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#, python-format +msgid "Vendor bill state must be Posted" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/account_move.py:0 +#, python-format +msgid "" +"You can't change the total amount, as there's an expense linked to this " +"invoice." +msgstr "" diff --git a/hr_expense_invoice/i18n/hr_expense_invoice.pot b/hr_expense_invoice/i18n/hr_expense_invoice.pot new file mode 100644 index 000000000..17ac05504 --- /dev/null +++ b/hr_expense_invoice/i18n/hr_expense_invoice.pot @@ -0,0 +1,176 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_expense_invoice +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.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: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.view_move_form +msgid "" +"\n" +" Expense\n" +" " +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__amount_residual +msgid "Amount Due" +msgstr "" + +#. module: hr_expense_invoice +#: model:mail.message.subtype,name:hr_expense_invoice.mt_expense_approved_inherited +msgid "Approved" +msgstr "" + +#. module: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +msgid "Create Vendor Bill" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense +msgid "Expense" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense_sheet +msgid "Expense Report" +msgstr "" + +#. module: hr_expense_invoice +#: model:mail.message.subtype,description:hr_expense_invoice.mt_expense_approved_inherited +msgid "Expense report approved" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__expense_ids +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__expense_ids +msgid "Expenses" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense_sheet__invoice_count +msgid "Invoice Count" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +msgid "Invoices" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move +msgid "Journal Entry" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move_line +msgid "Journal Item" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "" +"Please specify an expense journal in order to generate" +" accounting entries." +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "" +"Please specify if the expenses for this report were paid by" +" the company, or the employee" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,help:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,help:hr_expense_invoice.field_account_move__source_invoice_expense_id +msgid "" +"Reference to the expense with a linked invoice that generated thistransfer " +"journal entry" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__sheet_id_state +msgid "Sheet state" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "Show missing work email employees" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__source_invoice_expense_id +msgid "Source Invoice Expense" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "" +"The work email of some employees is missing. Please add it on" +" the employee form" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__transfer_move_ids +msgid "Transfer Move" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__invoice_id +msgid "Vendor Bill" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "" +"Vendor bill amount mismatch!\n" +"Please make sure amount in vendor bills equal to amount of its expense lines" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense.py:0 +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "Vendor bill state must be Posted" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "You can only generate an accounting entry for approved expense(s)." +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/account_move.py:0 +msgid "" +"You can't change the total amount, as there's an expense linked to this " +"invoice." +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "" +"You cannot create accounting entries for an expense " +"report without expenses." +msgstr "" diff --git a/hr_expense_invoice/i18n/it.po b/hr_expense_invoice/i18n/it.po new file mode 100644 index 000000000..1743086ee --- /dev/null +++ b/hr_expense_invoice/i18n/it.po @@ -0,0 +1,141 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_expense_invoice +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 15.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-05-30 13:38+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: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.view_move_form +msgid "Expense" +msgstr "Spesa" + +#. module: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +msgid "Create Vendor Bill" +msgstr "Crea una fattura fornitore" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense +msgid "Expense" +msgstr "Spesa" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense_sheet +msgid "Expense Report" +msgstr "Nota spese" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__expense_ids +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__expense_ids +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_payment__expense_ids +msgid "Expenses" +msgstr "Spese" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense_sheet__invoice_count +msgid "Invoice Count" +msgstr "Numero fatture" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +#, python-format +msgid "Invoices" +msgstr "Fatture" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move +msgid "Journal Entry" +msgstr "Registrazione contabile" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move_line +msgid "Journal Item" +msgstr "Movimento contabile" + +#. module: hr_expense_invoice +#: model:ir.model.fields,help:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,help:hr_expense_invoice.field_account_move__source_invoice_expense_id +#: model:ir.model.fields,help:hr_expense_invoice.field_account_payment__source_invoice_expense_id +msgid "" +"Reference to the expense with a linked invoice that generated thistransfer " +"journal entry" +msgstr "" +"Riferimento alla spesa con una fattura collegata che ha generato questa " +"registrazione contabile del trasferimento" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__sheet_id_state +msgid "Sheet state" +msgstr "Stato prospetto" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__source_invoice_expense_id +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_payment__source_invoice_expense_id +msgid "Source Invoice Expense" +msgstr "Fattura spesa origine" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__transfer_move_ids +msgid "Transfer Move" +msgstr "Movimento di trasferimento" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__invoice_id +msgid "Vendor Bill" +msgstr "Fattura fornitore" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#, python-format +msgid "" +"Vendor bill amount mismatch!\n" +"Please make sure amount in vendor bills equal to amount of its expense lines" +msgstr "" +"Differenza fattura fornitore!\n" +"Assicurarsi che il valore nel conto del fornitore sia pari al valore delle " +"righe di spesa" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense.py:0 +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#, python-format +msgid "Vendor bill state must be Posted" +msgstr "Lo stato del conto fornitore deve essere Inviato" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/account_move.py:0 +#, python-format +msgid "" +"You can't change the total amount, as there's an expense linked to this " +"invoice." +msgstr "" +"Non si può cambiare il valore totale, perché c'è una spesa collegata a " +"questa fattura." + +#~ msgid "Expense Report State" +#~ msgstr "Stato nota spese" + +#~ msgid "Register Payment" +#~ msgstr "Registra pagamento" + +#, python-format +#~ msgid "Register payment on expense's invoice is not allowed" +#~ msgstr "Non è consentito registrare il pagamento sulla fattura delle spese" diff --git a/hr_expense_invoice/i18n/nl_NL.po b/hr_expense_invoice/i18n/nl_NL.po new file mode 100644 index 000000000..d82751219 --- /dev/null +++ b/hr_expense_invoice/i18n/nl_NL.po @@ -0,0 +1,128 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_expense_invoice +# +# Translators: +# Peter Hageman , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-11-28 01:43+0000\n" +"PO-Revision-Date: 2017-11-28 01:43+0000\n" +"Last-Translator: Peter Hageman , 2017\n" +"Language-Team: Dutch (Netherlands) (https://www.transifex.com/oca/" +"teams/23907/nl_NL/)\n" +"Language: nl_NL\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: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.view_move_form +msgid "Expense" +msgstr "" + +#. module: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +msgid "Create Vendor Bill" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense +msgid "Expense" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense_sheet +msgid "Expense Report" +msgstr "Onkostennota" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__expense_ids +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__expense_ids +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_payment__expense_ids +#, fuzzy +msgid "Expenses" +msgstr "Onkostennota" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense_sheet__invoice_count +msgid "Invoice Count" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +#, python-format +msgid "Invoices" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move +msgid "Journal Entry" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move_line +msgid "Journal Item" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,help:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,help:hr_expense_invoice.field_account_move__source_invoice_expense_id +#: model:ir.model.fields,help:hr_expense_invoice.field_account_payment__source_invoice_expense_id +msgid "" +"Reference to the expense with a linked invoice that generated thistransfer " +"journal entry" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__sheet_id_state +msgid "Sheet state" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__source_invoice_expense_id +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_payment__source_invoice_expense_id +msgid "Source Invoice Expense" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__transfer_move_ids +msgid "Transfer Move" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__invoice_id +msgid "Vendor Bill" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#, python-format +msgid "" +"Vendor bill amount mismatch!\n" +"Please make sure amount in vendor bills equal to amount of its expense lines" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense.py:0 +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#, python-format +msgid "Vendor bill state must be Posted" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/account_move.py:0 +#, python-format +msgid "" +"You can't change the total amount, as there's an expense linked to this " +"invoice." +msgstr "" diff --git a/hr_expense_invoice/i18n/pt.po b/hr_expense_invoice/i18n/pt.po new file mode 100644 index 000000000..41c6049de --- /dev/null +++ b/hr_expense_invoice/i18n/pt.po @@ -0,0 +1,126 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_expense_invoice +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2018-10-10 12:08+0000\n" +"Last-Translator: Pedro Castro Silva \n" +"Language-Team: none\n" +"Language: pt\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 3.1.1\n" + +#. module: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.view_move_form +msgid "Expense" +msgstr "" + +#. module: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +msgid "Create Vendor Bill" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense +msgid "Expense" +msgstr "Despesa" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense_sheet +msgid "Expense Report" +msgstr "Relatório de Despesas" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__expense_ids +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__expense_ids +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_payment__expense_ids +#, fuzzy +msgid "Expenses" +msgstr "Despesa" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense_sheet__invoice_count +#, fuzzy +msgid "Invoice Count" +msgstr "Fatura" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +#, fuzzy, python-format +msgid "Invoices" +msgstr "Fatura" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move +msgid "Journal Entry" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move_line +msgid "Journal Item" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,help:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,help:hr_expense_invoice.field_account_move__source_invoice_expense_id +#: model:ir.model.fields,help:hr_expense_invoice.field_account_payment__source_invoice_expense_id +msgid "" +"Reference to the expense with a linked invoice that generated thistransfer " +"journal entry" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__sheet_id_state +msgid "Sheet state" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__source_invoice_expense_id +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_payment__source_invoice_expense_id +msgid "Source Invoice Expense" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__transfer_move_ids +msgid "Transfer Move" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__invoice_id +msgid "Vendor Bill" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#, python-format +msgid "" +"Vendor bill amount mismatch!\n" +"Please make sure amount in vendor bills equal to amount of its expense lines" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense.py:0 +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#, python-format +msgid "Vendor bill state must be Posted" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/account_move.py:0 +#, python-format +msgid "" +"You can't change the total amount, as there's an expense linked to this " +"invoice." +msgstr "" diff --git a/hr_expense_invoice/i18n/sl.po b/hr_expense_invoice/i18n/sl.po new file mode 100644 index 000000000..92c27dc06 --- /dev/null +++ b/hr_expense_invoice/i18n/sl.po @@ -0,0 +1,195 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_expense_invoice +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2026-06-08 08:46+0000\n" +"Last-Translator: Matjaz Mozetic \n" +"Language-Team: none\n" +"Language: sl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || " +"n%100==4 ? 2 : 3;\n" +"X-Generator: Weblate 5.15.2\n" + +#. module: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.view_move_form +msgid "" +"\n" +" Expense\n" +" " +msgstr "" +"\n" +" Izdatek\n" +" " + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__amount_residual +msgid "Amount Due" +msgstr "Znesek za plačilo" + +#. module: hr_expense_invoice +#: model:mail.message.subtype,name:hr_expense_invoice.mt_expense_approved_inherited +msgid "Approved" +msgstr "Odobreno" + +#. module: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +msgid "Create Vendor Bill" +msgstr "Ustvari prejeti račun" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense +msgid "Expense" +msgstr "Izdatek" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense_sheet +msgid "Expense Report" +msgstr "Poročilo o stroških" + +#. module: hr_expense_invoice +#: model:mail.message.subtype,description:hr_expense_invoice.mt_expense_approved_inherited +msgid "Expense report approved" +msgstr "Poročilo o stroških odobreno" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__expense_ids +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__expense_ids +msgid "Expenses" +msgstr "Stroški" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense_sheet__invoice_count +msgid "Invoice Count" +msgstr "Št. računov" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +msgid "Invoices" +msgstr "Računi" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move +msgid "Journal Entry" +msgstr "Temeljnica" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move_line +msgid "Journal Item" +msgstr "Postavka" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "" +"Please specify an expense journal in order to generate" +" accounting entries." +msgstr "" +"Prosimo, navedite dnevnik izdatkov za ustvarjanje računovodskih vknjižb." + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "" +"Please specify if the expenses for this report were paid by" +" the company, or the employee" +msgstr "" +"Prosimo, navedite, ali je stroške za to poročilo krilo podjetje ali zaposleni" + +#. module: hr_expense_invoice +#: model:ir.model.fields,help:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,help:hr_expense_invoice.field_account_move__source_invoice_expense_id +msgid "" +"Reference to the expense with a linked invoice that generated thistransfer " +"journal entry" +msgstr "" +"Sklic na strošek s povezanim računom, na podlagi katerega je bila ustvarjena " +"ta prenosna temeljnica" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__sheet_id_state +msgid "Sheet state" +msgstr "Stanje preglednice" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "Show missing work email employees" +msgstr "Prikaži zaposlene, ki nimajo službenega e-poštnega naslova" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__source_invoice_expense_id +msgid "Source Invoice Expense" +msgstr "Izvorni strošek računa" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "" +"The work email of some employees is missing. Please add it on" +" the employee form" +msgstr "" +"Manjka službeni e-poštni naslov nekaterih zaposlenih. Prosimo, dodajte ga na " +"obrazcu zaposlenega" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__transfer_move_ids +msgid "Transfer Move" +msgstr "Prenosna temeljnica" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__invoice_id +msgid "Vendor Bill" +msgstr "Prejeti račun" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "" +"Vendor bill amount mismatch!\n" +"Please make sure amount in vendor bills equal to amount of its expense lines" +msgstr "" +"Znesek na prejetem računu se ne ujema!\n" +"Preverite, ali se znesek na prejetih računih ujema z zneskom v posameznih " +"stroškovnih postavkah" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense.py:0 +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "Vendor bill state must be Posted" +msgstr "Prejeti račun mora biti v stanju 'knjiženo'" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "You can only generate an accounting entry for approved expense(s)." +msgstr "Računovodski vnos lahko ustvarite le za odobrene stroške." + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/account_move.py:0 +msgid "" +"You can't change the total amount, as there's an expense linked to this " +"invoice." +msgstr "" +"Skupnega zneska ni mogoče spremeniti, saj je s tem računom povezan izdatek." + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "" +"You cannot create accounting entries for an expense " +"report without expenses." +msgstr "" +"Za poročilo o stroških ni mogoče ustvariti računovodskih vnosov, če v njem " +"stroškov ni." diff --git a/hr_expense_invoice/i18n/tr.po b/hr_expense_invoice/i18n/tr.po new file mode 100644 index 000000000..5faf0ebac --- /dev/null +++ b/hr_expense_invoice/i18n/tr.po @@ -0,0 +1,186 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_expense_invoice +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2026-06-03 18:46+0000\n" +"Last-Translator: Betül Öğmen \n" +"Language-Team: none\n" +"Language: tr\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 5.15.2\n" + +#. module: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.view_move_form +msgid "" +"\n" +" Expense\n" +" " +msgstr "" +"\n" +" Masraf\n" +" " + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__amount_residual +msgid "Amount Due" +msgstr "Ödenecek Tutar" + +#. module: hr_expense_invoice +#: model:mail.message.subtype,name:hr_expense_invoice.mt_expense_approved_inherited +msgid "Approved" +msgstr "Onaylandı" + +#. module: hr_expense_invoice +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +msgid "Create Vendor Bill" +msgstr "Tedarikçi Faturası Oluşturun" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense +msgid "Expense" +msgstr "Masraf" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_hr_expense_sheet +msgid "Expense Report" +msgstr "Masraf Formu" + +#. module: hr_expense_invoice +#: model:mail.message.subtype,description:hr_expense_invoice.mt_expense_approved_inherited +msgid "Expense report approved" +msgstr "Masraf formu onaylandı" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__expense_ids +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__expense_ids +msgid "Expenses" +msgstr "Masraflar" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense_sheet__invoice_count +msgid "Invoice Count" +msgstr "Fatura Sayısı" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +#: model_terms:ir.ui.view,arch_db:hr_expense_invoice.hr_expense_sheet_form_view_inherit_sale_expense +msgid "Invoices" +msgstr "Faturalar" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move +msgid "Journal Entry" +msgstr "Yevmiye Kaydı" + +#. module: hr_expense_invoice +#: model:ir.model,name:hr_expense_invoice.model_account_move_line +msgid "Journal Item" +msgstr "Yevmiye Kalemi" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "" +"Please specify an expense journal in order to generate" +" accounting entries." +msgstr "Muhasebe kayıtları oluşturmak için bir gider günlüğü belirtiniz." + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "" +"Please specify if the expenses for this report were paid by" +" the company, or the employee" +msgstr "" +"Bu raporun masraflarının şirket tarafından mı yoksa çalışan tarafından mı " +"ödendiğini belirtiniz" + +#. module: hr_expense_invoice +#: model:ir.model.fields,help:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,help:hr_expense_invoice.field_account_move__source_invoice_expense_id +msgid "" +"Reference to the expense with a linked invoice that generated thistransfer " +"journal entry" +msgstr "" +"Bu transfer yevmiye kaydını oluşturan bağlantılı faturaya sahip gidere " +"referans" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__sheet_id_state +msgid "Sheet state" +msgstr "Çizelge Durumu" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "Show missing work email employees" +msgstr "Eksik iş e-postası olan çalışanları göster" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_bank_statement_line__source_invoice_expense_id +#: model:ir.model.fields,field_description:hr_expense_invoice.field_account_move__source_invoice_expense_id +msgid "Source Invoice Expense" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "" +"The work email of some employees is missing. Please add it on" +" the employee form" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__transfer_move_ids +msgid "Transfer Move" +msgstr "" + +#. module: hr_expense_invoice +#: model:ir.model.fields,field_description:hr_expense_invoice.field_hr_expense__invoice_id +msgid "Vendor Bill" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "" +"Vendor bill amount mismatch!\n" +"Please make sure amount in vendor bills equal to amount of its expense lines" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense.py:0 +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "Vendor bill state must be Posted" +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "You can only generate an accounting entry for approved expense(s)." +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/account_move.py:0 +msgid "" +"You can't change the total amount, as there's an expense linked to this " +"invoice." +msgstr "" + +#. module: hr_expense_invoice +#. odoo-python +#: code:addons/hr_expense_invoice/models/hr_expense_sheet.py:0 +msgid "" +"You cannot create accounting entries for an expense " +"report without expenses." +msgstr "" diff --git a/hr_expense_invoice/models/__init__.py b/hr_expense_invoice/models/__init__.py new file mode 100644 index 000000000..885d39b3f --- /dev/null +++ b/hr_expense_invoice/models/__init__.py @@ -0,0 +1,4 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import hr_expense +from . import account_move diff --git a/hr_expense_invoice/models/account_move.py b/hr_expense_invoice/models/account_move.py new file mode 100644 index 000000000..dfbbc9e8d --- /dev/null +++ b/hr_expense_invoice/models/account_move.py @@ -0,0 +1,80 @@ +# Copyright 2019 Ecosoft +# Copyright 2021 Tecnativa - Víctor Martínez +# Copyright 2024 Tecnativa - Pedro M. Baeza +# Copyright 2026 Moduon - Eduardo de Miguel +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from odoo import api, fields, models +from odoo.exceptions import ValidationError +from odoo.tools import float_compare + + +class AccountMove(models.Model): + _inherit = "account.move" + + invoice_expense_ids = fields.One2many( + comodel_name="hr.expense", inverse_name="invoice_id", string="Expenses" + ) + source_invoice_expense_id = fields.Many2one( + comodel_name="hr.expense", + help="Reference to the expense with a linked invoice that generated this" + "transfer journal entry", + ) + + @api.constrains("amount_total") + def _check_expense_ids(self): + DecimalPrecision = self.env["decimal.precision"] + precision = DecimalPrecision.precision_get("Product Price") + for move in self.filtered("invoice_expense_ids"): + expense_amount = sum( + move.invoice_expense_ids.mapped("total_amount_currency") + ) + if float_compare(expense_amount, move.amount_total, precision) != 0: + raise ValidationError( + self.env._( + "You can't change the total amount, as there's an expense " + "linked to this invoice." + ) + ) + + def action_force_register_payment(self): + if self.source_invoice_expense_id: + return self.line_ids.action_register_payment() + return super().action_force_register_payment() + + def _compute_nb_expenses(self): + res = super()._compute_nb_expenses() + for move in self.filtered("invoice_expense_ids"): + move.nb_expenses = len(move.invoice_expense_ids) + return res + + def action_open_expense(self): + self.ensure_one() + if not self.invoice_expense_ids: + return super().action_open_expense() + linked_expenses = self.invoice_expense_ids + if len(linked_expenses) > 1: + return { + "name": self.env._("Expenses"), + "type": "ir.actions.act_window", + "view_mode": "list,form", + "views": [(False, "list"), (False, "form")], + "res_model": "hr.expense", + "domain": [("id", "in", linked_expenses.ids)], + } + return { + "name": linked_expenses.name, + "type": "ir.actions.act_window", + "view_mode": "form", + "views": [(False, "form")], + "res_model": "hr.expense", + "res_id": linked_expenses.id, + } + + +class AccountMoveLine(models.Model): + _inherit = "account.move.line" + + @api.constrains("account_id", "display_type") + def _check_payable_receivable(self): + _self = self.filtered("expense_id") + return super(AccountMoveLine, (self - _self))._check_payable_receivable() diff --git a/hr_expense_invoice/models/hr_expense.py b/hr_expense_invoice/models/hr_expense.py new file mode 100644 index 000000000..4381d9191 --- /dev/null +++ b/hr_expense_invoice/models/hr_expense.py @@ -0,0 +1,426 @@ +# Copyright 2017 Tecnativa - Vicent Cubells +# Copyright 2020 Tecnativa - David Vidal +# Copyright 2021 Tecnativa - Víctor Martínez +# Copyright 2015-2024 Tecnativa - Pedro M. Baeza +# Copyright 2026 Moduon - Eduardo de Miguel +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import Command, api, fields, models +from odoo.exceptions import RedirectWarning, UserError +from odoo.tools.misc import clean_context + + +class HrExpense(models.Model): + _inherit = "hr.expense" + + invoice_id = fields.Many2one( + comodel_name="account.move", + string="Vendor Bill", + domain=[ + ("move_type", "=", "in_invoice"), + ("state", "=", "posted"), + ("payment_state", "=", "not_paid"), + ("invoice_expense_ids", "=", False), + ], + copy=False, + ) + transfer_move_ids = fields.One2many( + comodel_name="account.move", + inverse_name="source_invoice_expense_id", + ) + # This field has been added to reintroduce tracking for the amount due on each + # expense, a feature that existed in previous versions. The tracking is necessary + # to accurately reflect the payment state of the expense sheet. + amount_residual = fields.Monetary( + string="Amount Due", compute="_compute_amount_residual", store=True + ) + + def _prepare_invoice_values(self): + invoice_lines = [ + Command.create( + { + "product_id": self.product_id.id, + "name": self.name, + # Odoo considers always the amount taxes included, we need to take + # the base amount and quantity = 1 + "price_unit": self.untaxed_amount_currency, + "quantity": 1, + "account_id": self.account_id.id, + "analytic_distribution": self.analytic_distribution, + "tax_ids": [Command.set(self.tax_ids.ids)], + } + ) + ] + return { + "name": "/", + "move_type": "in_invoice", + "invoice_date": self.date, + "invoice_line_ids": invoice_lines, + "partner_id": self.vendor_id.id, + } + + def _prepare_own_account_transfer_move_vals(self): + self.ensure_one() + self = self.with_company(self.company_id) + # TODO: Allow to select a specific journal + journal = self.env["account.journal"].search( + [ + ("company_id", "=", self.company_id.id), + ("type", "=", "general"), + ], + limit=1, + ) + employee_partner = self.employee_id.sudo().work_contact_id + invoice_partner = self.invoice_id.partner_id + ap_lines = self.invoice_id.line_ids.filtered( + lambda x: x.display_type == "payment_term" + ) + amount_invoice = sum(ap_lines.mapped("credit")) + return { + "journal_id": journal.id, + "move_type": "entry", + "name": "/", + "date": self.date, + "ref": self.name, + "source_invoice_expense_id": self.id, + "line_ids": [ + Command.create( + { + "account_id": ap_lines.account_id[:1].id, + "partner_id": invoice_partner.id, + "debit": amount_invoice, + } + ), + Command.create( + { + "account_id": employee_partner.property_account_payable_id.id, + "partner_id": employee_partner.id, + "credit": amount_invoice, + } + ), + ], + } + + def action_expense_create_invoice(self): + invoice = self.env["account.move"].create(self._prepare_invoice_values()) + attachments = self.env["ir.attachment"].search( + [("res_model", "=", self._name), ("res_id", "in", self.ids)] + ) + for attachment in attachments: + attachment.copy({"res_model": invoice._name, "res_id": invoice.id}) + self.write( + { + "invoice_id": invoice.id, + "quantity": 1, + "tax_ids": False, + "price_unit": invoice.amount_total, + } + ) + if self.payment_mode == "company_account": + invoice.action_post() + return True + + def action_view_invoice(self): + self.ensure_one() + return { + "type": "ir.actions.act_window", + "res_model": "account.move", + "name": self.invoice_id.name, + "view_mode": "form", + "res_id": self.invoice_id.id, + "views": [(self.env.ref("account.view_move_form").id, "form")], + "target": "current", + } + + def action_view_transfer_moves(self): + self.ensure_one() + action_name = self.env._("Transfer of %s", self.name) + if len(self.transfer_move_ids) == 1: + return { + "type": "ir.actions.act_window", + "res_model": "account.move", + "name": action_name, + "view_mode": "form", + "res_id": self.transfer_move_ids.id, + "views": [(self.env.ref("account.view_move_form").id, "form")], + "target": "current", + } + # Multiple transfer moves + action = self.env["ir.actions.act_window"]._for_xml_id( + "account.action_move_journal_line" + ) + action["name"] = action_name + action["domain"] = [("id", "in", self.transfer_move_ids.ids)] + return action + + @api.constrains("invoice_id", "state", "payment_mode") + def _check_invoice_id(self): + for expense in self: # Only non binding expense + if expense.state not in ("posted", "in_payment", "paid"): + continue + if expense.payment_mode == "company_account": + continue + if expense.invoice_id and expense.invoice_id.state != "posted": + raise UserError(self.env._("Vendor bill state must be Posted")) + + @api.onchange("invoice_id") + def _onchange_invoice_id(self): + """Assure quantity is 1 if an invoice is set for having proper totals, and + the rest of the fields that are not computed writable, avoiding to ud + """ + if self.invoice_id: + self.quantity = 1 + self.name = self.name.split(" | ")[0].strip() + self.name = "{} | {}".format(self.name or "", self.invoice_id.name) + self.date = self.invoice_id.date + if self.invoice_id.company_id != self.company_id: + # for avoiding to trigger dependent computes + self.company_id = self.invoice_id.company_id.id + + # tax_ids put as dependency for assuring this is computed after setting tax_ids + @api.depends("invoice_id", "tax_ids") + def _compute_price_unit(self): + with_invoice = self.filtered("invoice_id") + for record in with_invoice: + record.price_unit = record.invoice_id.amount_total + return super(HrExpense, self - with_invoice)._compute_price_unit() + + # tax_ids put as dependency for assuring this is computed after setting tax_ids + @api.depends("invoice_id", "tax_ids") + def _compute_total_amount_currency(self): + with_invoice = self.filtered("invoice_id") + for record in with_invoice: + record.total_amount_currency = record.invoice_id.amount_total + return super(HrExpense, self - with_invoice)._compute_total_amount_currency() + + @api.depends("invoice_id") + def _compute_currency_id(self): + with_invoice = self.filtered("invoice_id") + for record in with_invoice: + record.currency_id = record.invoice_id.currency_id.id + return super(HrExpense, self - with_invoice)._compute_currency_id() + + @api.depends("invoice_id") + def _compute_tax_ids(self): + with_invoice = self.filtered("invoice_id") + for record in with_invoice: + record.tax_ids = [(5,)] + return super(HrExpense, self - with_invoice)._compute_tax_ids() + + @api.depends( + "transfer_move_ids.line_ids.amount_residual", + "transfer_move_ids.line_ids.amount_residual_currency", + ) + def _compute_amount_residual(self): + """Compute the amount residual for expenses paid by employee with invoices.""" + for rec in self: + if not rec.currency_id or rec.currency_id == rec.company_currency_id: + residual_field = "amount_residual" + else: + residual_field = "amount_residual_currency" + payment_term_lines = rec.transfer_move_ids.sudo().line_ids.filtered( + lambda x: x.account_type in ("asset_receivable", "liability_payable") + ) + rec.amount_residual = -sum(payment_term_lines.mapped(residual_field)) + + def _check_can_create_move(self): + res = super()._check_can_create_move() + expenses_with_invoices = self.filtered("invoice_id") + # Check expeneses with transfer moves + if exp_w_tranfers := expenses_with_invoices.filtered_domain( + [("transfer_move_ids", "!=", False)] + ): + raise UserError( + self.env._( + "You can't create an accounting entry for an expense " + "already linked to a transfer journal entry.\n" + "Please unselect %s and try again.", + ", ".join(exp_w_tranfers.mapped("name")), + ) + ) + # Check expeneses without posted invoices + if exp_wo_posted_invoices := expenses_with_invoices.filtered_domain( + [("invoice_id.state", "!=", "posted")] + ): + raise UserError( + self.env._( + "You can't create an accounting entry for an expense " + "linked to a vendor bill that is not posted.\n" + "Please post Vendor Bills of %s and try again.", + ", ".join(exp_wo_posted_invoices.mapped("name")), + ) + ) + # Check expeneses without employee work email + if emp_wo_email := expenses_with_invoices.employee_id.filtered_domain( + [ + ("work_email", "=", False), + ] + ): + action = self.env["ir.actions.actions"]._for_xml_id( + "hr.open_view_employee_list_my" + ) + action["domain"] = [("id", "in", emp_wo_email.ids)] + raise RedirectWarning( + self.env._( + "The work email of some employees is missing.\n" + "Please add it on the employee form." + ), + action, + self.env._("Show missing work email employees"), + ) + return res + + def _reconcile_transfer_moves(self): + # Reconcile transfer entries with vendor bills once they are posted + self.ensure_one() + if self.payment_mode != "own_account": + return + if not self.invoice_id or not self.transfer_move_ids: + raise UserError( + self.env._( + "You can't reconcile an expense linked to a " + "Vendor Bill or Transfer that doesn't exist (%s).", + self.name, + ) + ) + # All transfer moves should be posted + vendor_inv_lines = self.invoice_id.line_ids.filtered_domain( + [ + ("display_type", "=", "payment_term"), + ] + ) + vendor_transfer_lines = self.transfer_move_ids.line_ids.filtered_domain( + [ + ("partner_id", "=", self.invoice_id.partner_id.id), + ] + ) + if vendor_inv_lines and vendor_transfer_lines: + (vendor_inv_lines + vendor_transfer_lines).reconcile() + + def _action_expense_create_transfer_moves(self): + for expense in self: + transfer_move_vals = expense._prepare_own_account_transfer_move_vals() + transfer_move = self.env["account.move"].create(transfer_move_vals) + transfer_move.action_post() + expense._reconcile_transfer_moves() + + def action_post(self): + self._check_can_create_move() + expenses_with_invoices = self.filtered("invoice_id") + expenses_with_invoices._action_expense_create_transfer_moves() + if expenses_without_invoices := self - expenses_with_invoices: + return super(HrExpense, expenses_without_invoices).action_post() + return + + @api.depends("invoice_id.state", "transfer_move_ids.line_ids.reconciled") + def _compute_state(self): + expenses_with_invoices = self.filtered("invoice_id") + if expenses_without_invoices := self - expenses_with_invoices: + super(HrExpense, expenses_without_invoices)._compute_state() + + for expense in expenses_with_invoices: + bill = expense.invoice_id + transfers = expense.transfer_move_ids + employee_parnter = expense.employee_id.sudo().work_contact_id + # Shortcut to paid, as it's already paid, + # but we may not have the bank statement yet + if expense.payment_mode == "company_account": + expense.state = "paid" + # Check state of vendor bills + elif bill.state == "cancel": + # Nothing to do with the expense + expense.state = "paid" + elif bill.state == "draft" or not transfers: + # Bill created, and not posted yet + # No transfer moves, so need to be able to create + expense.state = "approved" + elif bill.payment_state == "not_paid": + # Transfers are created and bill is posted, but not reconciled + # They should reconcile manually with the transfer moves + expense.state = "posted" + elif bill.payment_state in ("partial", "in_payment", "paid", "reversed"): + # All vendor move lines are reconciled: in_payment + vendor_transfer_lines = transfers.line_ids.filtered_domain( + [ + ("partner_id", "=", bill.partner_id.id), + ] + ) + if all(vendor_transfer_lines.mapped("reconciled")): + expense.state = "in_payment" + # All employee move lines are reconciled: paid + employee_transfer_lines = transfers.line_ids.filtered_domain( + [ + ("partner_id", "=", employee_parnter.id), + ] + ) + if all(employee_transfer_lines.mapped("reconciled")): + expense.state = "paid" + else: + expense.state = expense.approval_state or "draft" + return + + def _check_can_reset_approval(self): + expenses_with_invoices = self.filtered("invoice_id") + res = super( + HrExpense, self - expenses_with_invoices + )._check_can_reset_approval() + if not all(self.mapped("can_reset")): + raise UserError( + self.env._( + "Only HR Officers, accountants, " + "or the concerned employee can reset to draft." + ) + ) + if any( + state not in {False, "draft"} + for state in expenses_with_invoices.invoice_id.mapped("state") + ): + raise UserError( + self.env._( + "You cannot reset to draft an " + "expense linked to a posted journal entry." + ) + ) + if any( + state not in {False, "draft"} + for state in expenses_with_invoices.transfer_move_ids.mapped("state") + ): + raise UserError( + self.env._( + "You cannot reset to draft an " + "expense linked to a posted transfer journal entry." + ) + ) + return res + + def action_reset(self): + self = self.with_context(**clean_context(self.env.context)) + # Invoices + invoices_sudo = self.sudo().invoice_id + draft_invoices_sudo = invoices_sudo.filtered(lambda m: m.state == "draft") + non_draft_invoices_sudo = invoices_sudo - draft_invoices_sudo + non_draft_invoices_sudo._reverse_moves( + default_values_list=[ + {"invoice_date": fields.Date.context_today(inv_sudo)} + for inv_sudo in non_draft_invoices_sudo + ], + cancel=True, + ) + draft_invoices_sudo.unlink() + # Trasfers + transfers_sudo = self.sudo().transfer_move_ids + draft_transfers_sudo = transfers_sudo.filtered(lambda m: m.state == "draft") + non_draft_transfers_sudo = transfers_sudo - draft_transfers_sudo + non_draft_transfers_sudo._reverse_moves( + default_values_list=[ + {"invoice_date": fields.Date.context_today(transfer_sudo)} + for transfer_sudo in non_draft_transfers_sudo + ], + cancel=True, + ) + draft_transfers_sudo.unlink() + return super().action_reset() + + def _do_reset_approval(self): + self.sudo().write({"invoice_id": False, "transfer_move_ids": []}) + return super()._do_reset_approval() diff --git a/hr_expense_invoice/pyproject.toml b/hr_expense_invoice/pyproject.toml new file mode 100644 index 000000000..4231d0ccc --- /dev/null +++ b/hr_expense_invoice/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/hr_expense_invoice/readme/CONTRIBUTORS.md b/hr_expense_invoice/readme/CONTRIBUTORS.md new file mode 100644 index 000000000..c7cfc9a17 --- /dev/null +++ b/hr_expense_invoice/readme/CONTRIBUTORS.md @@ -0,0 +1,8 @@ +- [Tecnativa](https://www.tecnativa.com): + - Pedro M. Baeza + - Vicent Cubells + - Víctor Martínez +- Kitti Upariphutthiphong \<\> +- Rattapong Chokmasermkul \<\> +- Saran Lim. \<\> +- Eduardo de Miguel (`Moduon `__) diff --git a/hr_expense_invoice/readme/DESCRIPTION.md b/hr_expense_invoice/readme/DESCRIPTION.md new file mode 100644 index 000000000..bb77ca60d --- /dev/null +++ b/hr_expense_invoice/readme/DESCRIPTION.md @@ -0,0 +1,6 @@ +This module should be used when a vendor bill is paid by an +employee. It allows to register a vendor bill, +adding the corresponding journal items to transfer the debt to the +employee. + +You can set the vendor bill in the Expense or create a new one. diff --git a/hr_expense_invoice/readme/ROADMAP.md b/hr_expense_invoice/readme/ROADMAP.md new file mode 100644 index 000000000..8576bd927 --- /dev/null +++ b/hr_expense_invoice/readme/ROADMAP.md @@ -0,0 +1,3 @@ +- Multiple payment terms for a vendor bills are not handled correctly. +- Partial reconcile vendor bill are also not correctly handled. +- Since Odoo 19 only supports isolated expenses and clear vendor bill/receipt creation, invoice_id field on expense should be migrated to account_move_id field and deeply refactor the module. diff --git a/hr_expense_invoice/readme/USAGE.md b/hr_expense_invoice/readme/USAGE.md new file mode 100644 index 000000000..a3879491e --- /dev/null +++ b/hr_expense_invoice/readme/USAGE.md @@ -0,0 +1,11 @@ +- Create an expense paid by an employee. +- Select a Vendor Bill or create a new one with "Create Vendor Bill" button. +- Clic on Post Journal Entries button. +- At this point: + - A new Transfer Entry has been created to transfer the debt from the Vendor to the Employee. + - Vendor Bill has been reconciled with the Transfer Entry. +- Go to the Transfer move by clicking on the "Transfer Moves" button. +- Pay this Entry clicking on the Gears > Pay. +- You will see: + - Vendor Bill has been reconciled with the Transfer Entry Vendor line. + - Transfer Entry Employee line has been paid. diff --git a/hr_expense_invoice/static/description/icon.png b/hr_expense_invoice/static/description/icon.png new file mode 100644 index 000000000..8e5a7f402 Binary files /dev/null and b/hr_expense_invoice/static/description/icon.png differ diff --git a/hr_expense_invoice/static/description/index.html b/hr_expense_invoice/static/description/index.html new file mode 100644 index 000000000..05822c666 --- /dev/null +++ b/hr_expense_invoice/static/description/index.html @@ -0,0 +1,475 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Supplier invoices on HR expenses

+ +

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

+

This module should be used when a vendor bill is paid by an employee. It +allows to register a vendor bill, adding the corresponding journal items +to transfer the debt to the employee.

+

You can set the vendor bill in the Expense or create a new one.

+

Table of contents

+ +
+

Usage

+
    +
  • Create an expense paid by an employee.
  • +
  • Select a Vendor Bill or create a new one with “Create Vendor Bill” +button.
  • +
  • Clic on Post Journal Entries button.
  • +
  • At this point:
      +
    • A new Transfer Entry has been created to transfer the debt from the +Vendor to the Employee.
    • +
    • Vendor Bill has been reconciled with the Transfer Entry.
    • +
    +
  • +
  • Go to the Transfer move by clicking on the “Transfer Moves” button.
  • +
  • Pay this Entry clicking on the Gears > Pay.
  • +
  • You will see:
      +
    • Vendor Bill has been reconciled with the Transfer Entry Vendor line.
    • +
    • Transfer Entry Employee line has been paid.
    • +
    +
  • +
+
+
+

Known issues / Roadmap

+
    +
  • Multiple payment terms for a vendor bills are not handled correctly.
  • +
  • Partial reconcile vendor bill are also not correctly handled.
  • +
  • Since Odoo 19 only supports isolated expenses and clear vendor +bill/receipt creation, invoice_id field on expense should be migrated +to account_move_id field and deeply refactor the module.
  • +
+
+
+

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

+ +
+
+

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.

+

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

+

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

+
+
+
+
+ + diff --git a/hr_expense_invoice/tests/__init__.py b/hr_expense_invoice/tests/__init__.py new file mode 100644 index 000000000..571c2e78e --- /dev/null +++ b/hr_expense_invoice/tests/__init__.py @@ -0,0 +1 @@ +from . import test_hr_expense_invoice diff --git a/hr_expense_invoice/tests/test_hr_expense_invoice.py b/hr_expense_invoice/tests/test_hr_expense_invoice.py new file mode 100644 index 000000000..652780795 --- /dev/null +++ b/hr_expense_invoice/tests/test_hr_expense_invoice.py @@ -0,0 +1,214 @@ +# Copyright 2017 Tecnativa - Vicent Cubells +# Copyright 2021 Tecnativa - Pedro M. Baeza +# Copyright 2021-2023 Tecnativa - Víctor Martínez +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo import fields +from odoo.exceptions import UserError +from odoo.tests import Form, tagged + +from odoo.addons.hr_expense.tests.common import TestExpenseCommon + + +@tagged("post_install", "-at_install") +class TestHrExpenseInvoice(TestExpenseCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, test_hr_expense_invoice=True)) + cls.account_payment_register = cls.env["account.payment.register"] + cls.payment_obj = cls.env["account.payment"] + cls.cash_journal = cls.company_data["default_journal_cash"] + cls.company_data["company"].account_sale_tax_id = False + cls.company_data["company"].account_purchase_tax_id = False + cls.product_a.supplier_taxes_id = False + cls.product_c.supplier_taxes_id = False + cls.invoice = cls.init_invoice( + "in_invoice", + products=[cls.product_a], + ) + cls.invoice.invoice_line_ids.price_unit = 100 + cls.invoice2 = cls.invoice.copy( + { + "invoice_date": fields.Date.today(), + } + ) + cls.expense = cls.create_expenses( + { + "name": "Expense 1 Paid by Employee", + "employee_id": cls.expense_employee.id, + "product_id": cls.product_c.id, + "payment_mode": "own_account", + "total_amount_currency": 100.0, + "company_id": cls.company_data["company"].id, + } + ) + cls.expense2 = cls.create_expenses( + { + "name": "Expense 2 Paid by Company", + "employee_id": cls.expense_employee.id, + "product_id": cls.product_c.id, + "payment_mode": "company_account", + "total_amount_currency": 100.0, + "company_id": cls.company_data["company"].id, + } + ) + cls._create_attachment(cls, cls.expense) + cls._create_attachment(cls, cls.expense2) + + def _expense_register_payment(self, expense): + in_payment_state = expense.account_move_id._get_invoice_in_payment_state() + payment = self.get_new_payment(expense, expense.total_amount) + # liquidity_lines = payment._seek_for_lines()[0] + self.assertEqual(expense.state, in_payment_state) + return payment + + def _transfer_move_register_payment(self, expense): + to_pay_lines = expense.transfer_move_ids.line_ids.filtered_domain( + [ + ("partner_id", "=", self.expense_employee.work_contact_id.id), + ] + ) + payment_register = ( + self.env["account.payment.register"] + .with_context( + active_model="account.move", active_ids=expense.transfer_move_ids.ids + ) + .create( + { + "amount": sum(to_pay_lines.mapped("credit")), + "journal_id": self.company_data["default_journal_bank"].id, + "payment_method_line_id": self.inbound_payment_method_line.id, + } + ) + ) + self.assertEqual( + payment_register.partner_bank_id.partner_id, + expense.employee_id.work_contact_id, + ) + return payment_register._create_payments() + + def _create_attachment(self, expense): + res_model, res_id = expense._name, expense.id + attachment = self.env["ir.attachment"].create( + { + "name": f"Test attachment {res_id} ({res_model})", + "res_model": res_model, + "res_id": res_id, + "raw": b"R0lGODdhAQABAIAAAP///////ywAAAAAAQABAAACAkQBADs=", + } + ) + expense.message_main_attachment_id = attachment + return attachment + + def _action_submit_expenses(self, expenses): + expenses.action_submit() + expenses._do_approve(check=False) + for expense in expenses: + self.assertEqual(expense.state, "approved") + + def test_0_hr_tests_misc(self): + expenses = self.expense + self.expense2 + self.assertRecordValues( + expenses.message_main_attachment_id, + [ + {"name": f"Test attachment {self.expense.id} (hr.expense)"}, + {"name": f"Test attachment {self.expense2.id} (hr.expense)"}, + ], + ) + + def test_1_hr_test_no_invoice(self): + # We add an expense + self.assertAlmostEqual(self.expense.total_amount_currency, 100.0) + # Change product, check price changed + self.expense.product_id = self.product_a + self.assertAlmostEqual( + self.expense.total_amount_currency, self.product_a.standard_price + ) + # We approve expense, no invoice + self._action_submit_expenses(self.expense) + self.assertFalse(self.expense.invoice_id) + # We post journal entries + self.post_expenses_with_wizard(self.expense) + self.assertEqual(self.expense.account_move_id.state, "posted") + self.assertEqual(self.expense.account_move_id.payment_state, "not_paid") + self.assertEqual(self.expense.state, "posted") + # We make payment on invoice + self._expense_register_payment(self.expense) + + def test_2_hr_test_invoice(self): + # We add an expense + self.expense.total_amount_currency = 50 + self._action_submit_expenses(self.expense) + # We add invoice to expense + self.invoice.action_post() # residual = 100 + self.assertEqual(self.invoice.amount_total, 100.0) + with Form(self.expense) as f: + f.invoice_id = self.invoice + self.assertTrue(self.expense.invoice_id) + # Adding the invoice, changes the total amount + self.assertEqual(self.expense.total_amount, self.invoice.amount_total) + # Test error when invoice is not posted + self.expense.invoice_id.button_draft() + with self.assertRaises(UserError): + self.expense.action_post() + self.expense.invoice_id.action_post() + # We post journal entries (transfer) + self.expense.action_post() + self.assertEqual(self.expense.state, "in_payment") + self.assertEqual(self.expense.invoice_id.payment_state, "paid") + self.assertTrue(self.expense.transfer_move_ids) + # Pay the transferred amount (through a hack using reversal) + payment = self._transfer_move_register_payment(self.expense) + for transfer_line in self.expense.transfer_move_ids.line_ids: + self.assertTrue(transfer_line.reconciled) + self.assertEqual(self.expense.state, "paid") + # Delete the payment + payment.action_draft() + payment.unlink() + self.assertEqual(self.expense.state, "in_payment") + + def test_3_hr_test_create_invoice(self): + # We add an expense + self._action_submit_expenses(self.expense) + self.assertFalse(self.expense.invoice_id) + # We create an invoice from the expense + self.expense.action_expense_create_invoice() + self.assertTrue(self.expense.invoice_id) + self.assertEqual(self.expense.invoice_id.state, "draft") + self.assertRecordValues( + self.expense.invoice_id.attachment_ids, + [ + {"name": f"Test attachment {self.expense.id} (hr.expense)"}, + ], + ) + self.expense.invoice_id.partner_id = self.partner_a + self.expense.invoice_id.action_post() + self.assertEqual(self.expense.state, "approved") + self.expense.action_post() + self.assertEqual(self.expense.state, "in_payment") + self.assertEqual(self.expense.invoice_id.payment_state, "paid") + self.assertTrue(self.expense.transfer_move_ids) + # Pay the transferred amount + payment = self._transfer_move_register_payment(self.expense) + for transfer_line in self.expense.transfer_move_ids.line_ids: + self.assertTrue(transfer_line.reconciled) + self.assertEqual(self.expense.state, "paid") + # Delete the payment + payment.action_draft() + payment.unlink() + self.assertEqual(self.expense.state, "in_payment") + + def test_4_hr_test_invoice_paid_by_company(self): + # We add an expense + self._action_submit_expenses(self.expense2) + # Vendor is required in order to create an invoice + with self.assertRaises(UserError): + self.expense2.action_expense_create_invoice() + # Set Vendor + self.expense2.vendor_id = self.partner_a + # We create an invoice from the expense + self.expense2.action_expense_create_invoice() + self.assertTrue(self.expense2.invoice_id) + # Invoice is created in posted state + self.assertEqual(self.expense2.invoice_id.state, "posted") diff --git a/hr_expense_invoice/views/hr_expense_views.xml b/hr_expense_invoice/views/hr_expense_views.xml new file mode 100644 index 000000000..6fc24faeb --- /dev/null +++ b/hr_expense_invoice/views/hr_expense_views.xml @@ -0,0 +1,128 @@ + + + + hr.expense.form + hr.expense + + + + 1 + + + + + + + + + + + + 1 + + + 1 + + + 1 + + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + +