diff --git a/hr_expense_meal_allowance/README.rst b/hr_expense_meal_allowance/README.rst new file mode 100644 index 00000000..bd9c4c7f --- /dev/null +++ b/hr_expense_meal_allowance/README.rst @@ -0,0 +1,96 @@ +========================= +Hr Expense Meal Allowance +========================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:4e23d4e921f97da5d5d0a749271e711a371ccb625726baa51d7983c6d6e20710 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fl10n--germany-lightgray.png?logo=github + :target: https://github.com/OCA/l10n-germany/tree/18.0/hr_expense_meal_allowance + :alt: OCA/l10n-germany +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/l10n-germany-18-0/l10n-germany-18-0-hr_expense_meal_allowance + :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/l10n-germany&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Adds German "Verpflegungsmehraufwände" processing in the expense module. + +When a meal allowance product is selected, the UI is changed as +following. |meal allowance rates| |image1| + +| The product tag controls whether the Product is of type meal allowance + and controls the UI. +| |image2| + +The rates are imported by a csv file. When a rate changes for a certain +country, create a new csv line and set the expire_on date on the +existing line. |image3| + +.. |meal allowance rates| image:: https://raw.githubusercontent.com/OCA/l10n-germany/18.0/hr_expense_meal_allowance/static/description/expense_1.png +.. |image1| image:: https://raw.githubusercontent.com/OCA/l10n-germany/18.0/hr_expense_meal_allowance/static/description/expense_2.png +.. |image2| image:: https://raw.githubusercontent.com/OCA/l10n-germany/18.0/hr_expense_meal_allowance/static/description/product_tag.png +.. |image3| image:: https://raw.githubusercontent.com/OCA/l10n-germany/18.0/hr_expense_meal_allowance/static/description/settings_rates.png + +**Table of contents** + +.. contents:: + :local: + +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 +------- + +* IFE Gesellschaft für Forschung und Entwicklung +* glueckkanja AG + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-CRogos| image:: https://github.com/CRogos.png?size=40px + :target: https://github.com/CRogos + :alt: CRogos + +Current `maintainer `__: + +|maintainer-CRogos| + +This module is part of the `OCA/l10n-germany `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/hr_expense_meal_allowance/__init__.py b/hr_expense_meal_allowance/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/hr_expense_meal_allowance/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/hr_expense_meal_allowance/__manifest__.py b/hr_expense_meal_allowance/__manifest__.py new file mode 100644 index 00000000..00732506 --- /dev/null +++ b/hr_expense_meal_allowance/__manifest__.py @@ -0,0 +1,25 @@ +{ + "name": "Hr Expense Meal Allowance", + "author": "IFE Gesellschaft für Forschung und Entwicklung, " + "glueckkanja AG, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/l10n-germany", + "category": "Human Resources/Expenses", + "license": "AGPL-3", + "summary": "Automatic calculation of expenses", + "version": "18.0.1.1.2", + "depends": ["sale_expense"], + "maintainers": ["CRogos"], + "data": [ + "data/product_data.xml", + "data/hr.expense.meal.allowance.rate.csv", + "views/hr_expense_meal_allowance_rate.xml", + "views/hr_expense_meal_allowance.xml", + "views/hr_expense.xml", + "views/product_product.xml", + "security/ir.model.access.csv", + "report/expense_included_meal_report.xml", + "report/expense_included_meal.xml", + ], + "installable": True, + "application": False, +} diff --git a/hr_expense_meal_allowance/data/hr.expense.meal.allowance.rate.csv b/hr_expense_meal_allowance/data/hr.expense.meal.allowance.rate.csv new file mode 100644 index 00000000..067a82df --- /dev/null +++ b/hr_expense_meal_allowance/data/hr.expense.meal.allowance.rate.csv @@ -0,0 +1,270 @@ +"id","city_name","country_id/id","daily_rate_24h","daily_rate_8h","percentage_for_breakfast","percentage_for_dinner","percentage_for_lunch","expire_on" +"rate_base_af","","base.af","30","20","0.2","0.4","0.4","" +"rate_base_al","","base.al","27","18","0.2","0.4","0.4","2025-12-31" +"rate_base_al_2026","","base.al","33","22","0.2","0.4","0.4","" +"rate_base_dz","","base.dz","47","32","0.2","0.4","0.4","" +"rate_base_ad","","base.ad","41","28","0.2","0.4","0.4","2025-12-31" +"rate_base_ad_2026","","base.ad","45","30","0.2","0.4","0.4","" +"rate_base_ao","","base.ao","40","27","0.2","0.4","0.4","" +"rate_base_ar","","base.ar","35","24","0.2","0.4","0.4","2025-12-31" +"rate_base_ar_2026","","base.ar","42","28","0.2","0.4","0.4","" +"rate_base_am","","base.am","29","20","0.2","0.4","0.4","" +"rate_base_au_canberra","Canberra","base.au","74","49","0.2","0.4","0.4","" +"rate_base_au","","base.au","57","38","0.2","0.4","0.4","" +"rate_base_au_sydney","Sydney","base.au","57","38","0.2","0.4","0.4","" +"rate_base_at","","base.at","50","33","0.2","0.4","0.4","" +"rate_base_az","","base.az","44","29","0.2","0.4","0.4","" +"rate_base_bh","","base.bh","48","32","0.2","0.4","0.4","" +"rate_base_bd","","base.bd","46","31","0.2","0.4","0.4","" +"rate_base_bb","","base.bb","54","36","0.2","0.4","0.4","" +"rate_base_by","","base.by","20","13","0.2","0.4","0.4","2025-12-31" +"rate_base_by_2026","","base.by","21","14","0.2","0.4","0.4","" +"rate_base_be","","base.be","59","40","0.2","0.4","0.4","" +"rate_base_bj","","base.bj","52","35","0.2","0.4","0.4","" +"rate_base_bt","","base.bt","27","18","0.2","0.4","0.4","" +"rate_base_bn","","base.bn","45","30","0.2","0.4","0.4","" +"rate_base_bo","","base.bo","46","31","0.2","0.4","0.4","" +"rate_base_ba","","base.ba","23","16","0.2","0.4","0.4","2025-12-31" +"rate_base_ba_2026","","base.ba","32","21","0.2","0.4","0.4","" +"rate_base_bw","","base.bw","46","31","0.2","0.4","0.4","2025-12-31" +"rate_base_bw_2026","","base.bw","40","27","0.2","0.4","0.4","" +"rate_base_br_brasilia","Brasilia","base.br","51","34","0.2","0.4","0.4","" +"rate_base_br","","base.br","46","31","0.2","0.4","0.4","" +"rate_base_br_rio_de_jeneiro","Rio de Janeiro","base.br","69","46","0.2","0.4","0.4","" +"rate_base_br_sao_paulo","Sao Paulo","base.br","46","31","0.2","0.4","0.4","" +"rate_base_bg","","base.bg","22","15","0.2","0.4","0.4","2025-12-31" +"rate_base_bg_2026","","base.bg","38","25","0.2","0.4","0.4","" +"rate_base_bf","","base.bf","38","25","0.2","0.4","0.4","2025-12-31" +"rate_base_bf_2026","","base.bf","39","26","0.2","0.4","0.4","" +"rate_base_bi","","base.bi","36","24","0.2","0.4","0.4","2025-12-31" +"rate_base_bi_2026","","base.bi","58","39","0.2","0.4","0.4","" +"rate_base_kh","","base.kh","42","28","0.2","0.4","0.4","" +"rate_base_cm","","base.cm","56","37","0.2","0.4","0.4","" +"rate_base_ca_ottawa","Ottawa","base.ca","62","41","0.2","0.4","0.4","" +"rate_base_ca","","base.ca","54","36","0.2","0.4","0.4","" +"rate_base_ca_toronto","Toronto","base.ca","54","36","0.2","0.4","0.4","" +"rate_base_ca_vancouver","Vancouver","base.ca","63","42","0.2","0.4","0.4","" +"rate_base_cv","","base.cv","30","20","0.2","0.4","0.4","" +"rate_base_cf","","base.cf","53","36","0.2","0.4","0.4","" +"rate_base_td","","base.td","42","28","0.2","0.4","0.4","" +"rate_base_cl","","base.cl","44","29","0.2","0.4","0.4","" +"rate_base_cn","","base.cn","48","32","0.2","0.4","0.4","2025-12-31" +"rate_base_cn_2026","","base.cn","48","32","0.2","0.4","0.4","" +"rate_base_cn_beijing","Beijing","base.cn","30","20","0.2","0.4","0.4","2025-12-31" +"rate_base_cn_beijing_2026","Beijing","base.cn","57","38","0.2","0.4","0.4","" +"rate_base_cn_canton","Canton","base.cn","36","24","0.2","0.4","0.4","2025-12-31" +"rate_base_cn_chengu","Chengdu","base.cn","41","28","0.2","0.4","0.4","2025-12-31" +"rate_base_cn_hong_kong","Hong Kong","base.cn","71","48","0.2","0.4","0.4","2025-12-31" +"rate_base_cn_hong_kong_2026","Hong Kong","base.cn","83","56","0.2","0.4","0.4","" +"rate_base_cn_shanghai","Shanghai","base.cn","58","39","0.2","0.4","0.4","2025-12-31" +"rate_base_cn_shanghai_2026","Shanghai","base.cn","48","32","0.2","0.4","0.4","" +"rate_base_co","","base.co","34","23","0.2","0.4","0.4","" +"rate_base_cd","","base.cd","65","44","0.2","0.4","0.4","" +"rate_base_cg","","base.cg","62","41","0.2","0.4","0.4","2025-12-31" +"rate_base_cg_2026","","base.cg","53","36","0.2","0.4","0.4","" +"rate_base_cr","","base.cr","60","40","0.2","0.4","0.4","" +"rate_base_hr","","base.hr","46","31","0.2","0.4","0.4","" +"rate_base_cu","","base.cu","51","34","0.2","0.4","0.4","" +"rate_base_cy","","base.cy","42","28","0.2","0.4","0.4","" +"rate_base_cz","","base.cz","32","21","0.2","0.4","0.4","" +"rate_base_dk","","base.dk","75","50","0.2","0.4","0.4","" +"rate_base_dj","","base.dj","65","44","0.2","0.4","0.4","" +"rate_base_do","","base.do","45","30","0.2","0.4","0.4","" +"rate_base_ec","","base.ec","27","18","0.2","0.4","0.4","" +"rate_base_eg","","base.eg","50","33","0.2","0.4","0.4","" +"rate_base_sv","","base.sv","65","44","0.2","0.4","0.4","" +"rate_base_gq","","base.gq","36","24","0.2","0.4","0.4","" +"rate_base_er","","base.er","46","31","0.2","0.4","0.4","" +"rate_base_ee","","base.ee","29","20","0.2","0.4","0.4","2025-12-31" +"rate_base_ee_2026","","base.ee","39","26","0.2","0.4","0.4","" +"rate_base_et","","base.et","44","29","0.2","0.4","0.4","" +"rate_base_fj","","base.fj","32","21","0.2","0.4","0.4","" +"rate_base_fi","","base.fi","54","36","0.2","0.4","0.4","" +"rate_base_fr_dep_92_94","departments 92-94","base.fr","58","39","0.2","0.4","0.4","" +"rate_base_fr_paris","Paris","base.fr","58","39","0.2","0.4","0.4","" +"rate_base_fr","","base.fr","53","36","0.2","0.4","0.4","" +"rate_base_ga","","base.ga","64","43","0.2","0.4","0.4","" +"rate_base_gm","","base.gm","40","27","0.2","0.4","0.4","" +"rate_base_ge","","base.ge","45","30","0.2","0.4","0.4","" +"rate_base_de","","base.de","28","14","0.2","0.4","0.4","" +"rate_base_gh","","base.gh","46","31","0.2","0.4","0.4","" +"rate_base_uk_london","London","base.uk","66","44","0.2","0.4","0.4","" +"rate_base_uk","","base.uk","52","35","0.2","0.4","0.4","" +"rate_base_gr_athens","Athens","base.gr","40","27","0.2","0.4","0.4","" +"rate_base_gr","","base.gr","36","24","0.2","0.4","0.4","" +"rate_base_gt","","base.gt","46","31","0.2","0.4","0.4","" +"rate_base_gn","","base.gn","59","40","0.2","0.4","0.4","" +"rate_base_gw","","base.gw","32","21","0.2","0.4","0.4","" +"rate_base_ht","","base.ht","58","39","0.2","0.4","0.4","" +"rate_base_hn","","base.hn","57","38","0.2","0.4","0.4","" +"rate_base_hu","","base.hu","32","21","0.2","0.4","0.4","" +"rate_base_is","","base.is","62","41","0.2","0.4","0.4","" +"rate_base_in_bangalore","Bangalore","base.in","42","28","0.2","0.4","0.4","" +"rate_base_in_calcutta","Calcutta","base.in","32","21","0.2","0.4","0.4","" +"rate_base_in_chennai","Chennai","base.in","22","15","0.2","0.4","0.4","" +"rate_base_in_mumbai","Mumbai","base.in","53","36","0.2","0.4","0.4","" +"rate_base_in_new_delhi","New Delhi","base.in","46","31","0.2","0.4","0.4","" +"rate_base_in","","base.in","22","15","0.2","0.4","0.4","" +"rate_base_id","","base.id","45","30","0.2","0.4","0.4","" +"rate_base_ir","","base.ir","33","22","0.2","0.4","0.4","" +"rate_base_ie","","base.ie","58","39","0.2","0.4","0.4","2025-12-31" +"rate_base_ie_2026","","base.ie","64","43","0.2","0.4","0.4","" +"rate_base_il","","base.il","66","44","0.2","0.4","0.4","2025-12-31" +"rate_base_il_2026","","base.il","59","40","0.2","0.4","0.4","" +"rate_base_it_milan","Milan","base.it","42","28","0.2","0.4","0.4","" +"rate_base_it","","base.it","42","28","0.2","0.4","0.4","" +"rate_base_it_rome","Rome","base.it","48","32","0.2","0.4","0.4","" +"rate_base_ci","","base.ci","59","40","0.2","0.4","0.4","2025-12-31" +"rate_base_ci_2026","","base.ci","60","40","0.2","0.4","0.4","" +"rate_base_jm","","base.jm","39","26","0.2","0.4","0.4","" +"rate_base_jp","","base.jp","33","22","0.2","0.4","0.4","" +"rate_base_jp_tokyo","Tokyo","base.jp","50","33","0.2","0.4","0.4","" +"rate_base_jo","","base.jo","57","38","0.2","0.4","0.4","" +"rate_base_kz","","base.kz","33","22","0.2","0.4","0.4","" +"rate_base_ke","","base.ke","51","34","0.2","0.4","0.4","2025-12-31" +"rate_base_ke_2026","","base.ke","48","32","0.2","0.4","0.4","" +"rate_base_kp","","base.kp","28","19","0.2","0.4","0.4","2025-12-31" +"rate_base_kp_2026","","base.kp","39","26","0.2","0.4","0.4","" +"rate_base_kr","","base.kr","48","32","0.2","0.4","0.4","" +"rate_base_xk","","base.xk","24","16","0.2","0.4","0.4","" +"rate_base_kw","","base.kw","56","37","0.2","0.4","0.4","2025-12-31" +"rate_base_kw_2026","","base.kw","63","42","0.2","0.4","0.4","" +"rate_base_kg","","base.kg","27","18","0.2","0.4","0.4","" +"rate_base_la","","base.la","35","24","0.2","0.4","0.4","" +"rate_base_lv","","base.lv","35","24","0.2","0.4","0.4","2025-12-31" +"rate_base_lv_2026","","base.lv","46","31","0.2","0.4","0.4","" +"rate_base_lb","","base.lb","69","46","0.2","0.4","0.4","" +"rate_base_ls","","base.ls","28","19","0.2","0.4","0.4","" +"rate_base_lr","","base.lr","65","44","0.2","0.4","0.4","" +"rate_base_ly","","base.ly","63","42","0.2","0.4","0.4","" +"rate_base_li","","base.li","56","37","0.2","0.4","0.4","2025-12-31" +"rate_base_li_2026","","base.li","57","38","0.2","0.4","0.4","" +"rate_base_lt","","base.lt","26","17","0.2","0.4","0.4","2025-12-31" +"rate_base_lt_2026","","base.lt","48","32","0.2","0.4","0.4","" +"rate_base_lu","","base.lu","63","42","0.2","0.4","0.4","" +"rate_base_mg","","base.mg","33","22","0.2","0.4","0.4","" +"rate_base_mw","","base.mw","41","28","0.2","0.4","0.4","" +"rate_base_my","","base.my","36","24","0.2","0.4","0.4","" +"rate_base_mv","","base.mv","70","47","0.2","0.4","0.4","" +"rate_base_ml","","base.ml","38","25","0.2","0.4","0.4","2025-12-31" +"rate_base_ml_2026","","base.ml","42","28","0.2","0.4","0.4","" +"rate_base_mt","","base.mt","46","31","0.2","0.4","0.4","2025-12-31" +"rate_base_mt_2026","","base.mt","59","40","0.2","0.4","0.4","" +"rate_base_mh","","base.mh","63","42","0.2","0.4","0.4","2025-12-31" +"rate_base_mh_2026","","base.mh","45","30","0.2","0.4","0.4","" +"rate_base_mr","","base.mr","35","24","0.2","0.4","0.4","" +"rate_base_mu","","base.mu","44","29","0.2","0.4","0.4","" +"rate_base_mx","","base.mx","48","32","0.2","0.4","0.4","2025-12-31" +"rate_base_mx_2026","","base.mx","40","27","0.2","0.4","0.4","" +"rate_base_md","","base.md","26","17","0.2","0.4","0.4","" +"rate_base_mc","","base.mc","52","35","0.2","0.4","0.4","" +"rate_base_mn","","base.mn","23","16","0.2","0.4","0.4","" +"rate_base_me","","base.me","32","21","0.2","0.4","0.4","" +"rate_base_ma","","base.ma","41","28","0.2","0.4","0.4","" +"rate_base_mz","","base.mz","51","34","0.2","0.4","0.4","" +"rate_base_mm","","base.mm","23","16","0.2","0.4","0.4","" +"rate_base_na","","base.na","30","20","0.2","0.4","0.4","2025-12-31" +"rate_base_na_2026","","base.na","28","19","0.2","0.4","0.4","" +"rate_base_np","","base.np","36","24","0.2","0.4","0.4","2025-12-31" +"rate_base_np_2026","","base.np","33","22","0.2","0.4","0.4","" +"rate_base_nl","","base.nl","47","32","0.2","0.4","0.4","2025-12-31" +"rate_base_nl_2026","","base.nl","58","39","0.2","0.4","0.4","" +"rate_base_nz","","base.nz","58","39","0.2","0.4","0.4","" +"rate_base_ni","","base.ni","46","31","0.2","0.4","0.4","" +"rate_base_ne","","base.ne","42","28","0.2","0.4","0.4","" +"rate_base_ng","","base.ng","46","31","0.2","0.4","0.4","2025-12-31" +"rate_base_ng_2026","","base.ng","52","35","0.2","0.4","0.4","" +"rate_base_no","","base.no","75","50","0.2","0.4","0.4","" +"rate_base_om","","base.om","64","43","0.2","0.4","0.4","" +"rate_base_pk_islamabad","Islamabad","base.pk","23","16","0.2","0.4","0.4","" +"rate_base_pk","","base.pk","34","23","0.2","0.4","0.4","" +"rate_base_pw","","base.pw","51","34","0.2","0.4","0.4","" +"rate_base_pa","","base.pa","41","28","0.2","0.4","0.4","" +"rate_base_pg","","base.pg","59","40","0.2","0.4","0.4","" +"rate_base_py","","base.py","39","26","0.2","0.4","0.4","" +"rate_base_pe","","base.pe","34","23","0.2","0.4","0.4","2025-12-31" +"rate_base_pe_2026","","base.pe","52","35","0.2","0.4","0.4","" +"rate_base_ph","","base.ph","41","28","0.2","0.4","0.4","" +"rate_base_pl_gdansk","Gdansk","base.pl","30","30","0.2","0.4","0.4","" +"rate_base_pl_krakow","Krakow","base.pl","27","18","0.2","0.4","0.4","" +"rate_base_pl","","base.pl","34","23","0.2","0.4","0.4","" +"rate_base_pl_warsaw","Warsaw","base.pl","40","27","0.2","0.4","0.4","" +"rate_base_pl_wroclaw","Wroclaw","base.pl","34","23","0.2","0.4","0.4","" +"rate_base_pt","","base.pt","32","21","0.2","0.4","0.4","" +"rate_base_qa","","base.qa","56","37","0.2","0.4","0.4","2025-12-31" +"rate_base_qa_2026","","base.qa","81","54","0.2","0.4","0.4","" +"rate_base_ro_bucharest","Bucharest","base.ro","32","21","0.2","0.4","0.4","" +"rate_base_ro","","base.ro","27","18","0.2","0.4","0.4","" +"rate_base_ru_moscow","Moscow","base.ru","30","20","0.2","0.4","0.4","" +"rate_base_ru","","base.ru","28","19","0.2","0.4","0.4","" +"rate_base_ru_st_petersburg","St. Petersburg","base.ru","28","19","0.2","0.4","0.4","" +"rate_base_ru_yekatarinburg","Yekatarinburg","base.ru","28","19","0.2","0.4","0.4","" +"rate_base_rw","","base.rw","44","29","0.2","0.4","0.4","" +"rate_base_ws","","base.ws","39","26","0.2","0.4","0.4","" +"rate_base_sm","","base.sm","34","23","0.2","0.4","0.4","" +"rate_base_sa_djidda","Djidda","base.sa","57","38","0.2","0.4","0.4","" +"rate_base_sa","","base.sa","56","37","0.2","0.4","0.4","" +"rate_base_sa_riyadh","Riyadh","base.sa","56","37","0.2","0.4","0.4","" +"rate_base_sn","","base.sn","42","28","0.2","0.4","0.4","2025-12-31" +"rate_base_sn_2026","","base.sn","48","32","0.2","0.4","0.4","" +"rate_base_st","","base.st","36","24","0.2","0.4","0.4","" +"rate_base_rs","","base.rs","27","18","0.2","0.4","0.4","" +"rate_base_sl","","base.sl","57","38","0.2","0.4","0.4","" +"rate_base_sg","","base.sg","71","48","0.2","0.4","0.4","" +"rate_base_sk","","base.sk","33","22","0.2","0.4","0.4","" +"rate_base_si","","base.si","38","25","0.2","0.4","0.4","" +"rate_base_za_cape_town","Cape Town","base.za","33","22","0.2","0.4","0.4","" +"rate_base_za_johannisbourg","Johannisburg","base.za","36","24","0.2","0.4","0.4","" +"rate_base_za","","base.za","29","20","0.2","0.4","0.4","" +"rate_base_ss","","base.ss","51","34","0.2","0.4","0.4","" +"rate_base_es_barcelona","Barcelona","base.es","34","23","0.2","0.4","0.4","" +"rate_base_es_canary_islands","Canary Islands","base.es","36","24","0.2","0.4","0.4","" +"rate_base_es_madrid","Madrid","base.es","42","28","0.2","0.4","0.4","" +"rate_base_es_palma_de_mallorca","Palma de Mallorca","base.es","44","29","0.2","0.4","0.4","" +"rate_base_es","","base.es","34","23","0.2","0.4","0.4","" +"rate_base_lk","","base.lk","36","24","0.2","0.4","0.4","" +"rate_base_sd","","base.sd","33","22","0.2","0.4","0.4","" +"rate_base_se","","base.se","66","44","0.2","0.4","0.4","" +"rate_base_ch_geneve","Geneva","base.ch","66","44","0.2","0.4","0.4","2025-12-31" +"rate_base_ch_geneve_2026","Geneva","base.ch","70","47","0.2","0.4","0.4","" +"rate_base_ch","","base.ch","64","43","0.2","0.4","0.4","2025-12-31" +"rate_base_ch_2026","","base.ch","70","47","0.2","0.4","0.4","" +"rate_base_sy","","base.sy","38","25","0.2","0.4","0.4","" +"rate_base_tw","","base.tw","46","31","0.2","0.4","0.4","" +"rate_base_tj","","base.tj","27","18","0.2","0.4","0.4","" +"rate_base_tz","","base.tz","44","29","0.2","0.4","0.4","" +"rate_base_th","","base.th","36","24","0.2","0.4","0.4","" +"rate_base_tg","","base.tg","39","26","0.2","0.4","0.4","2025-12-31" +"rate_base_tg_2026","","base.tg","36","24","0.2","0.4","0.4","" +"rate_base_to","","base.to","29","20","0.2","0.4","0.4","" +"rate_base_tt","","base.tt","66","44","0.2","0.4","0.4","" +"rate_base_tn","","base.tn","40","27","0.2","0.4","0.4","" +"rate_base_tr_ankara","Ankara","base.tr","32","21","0.2","0.4","0.4","" +"rate_base_tr_izmir","Izmir","base.tr","44","29","0.2","0.4","0.4","" +"rate_base_tr","","base.tr","24","16","0.2","0.4","0.4","" +"rate_base_tm","","base.tm","28","19","0.2","0.4","0.4","" +"rate_base_ug","","base.ug","41","28","0.2","0.4","0.4","2025-12-31" +"rate_base_ug_2026","","base.ug","45","30","0.2","0.4","0.4","" +"rate_base_ua","","base.ua","26","17","0.2","0.4","0.4","2025-12-31" +"rate_base_ua_2026","","base.ua","33","22","0.2","0.4","0.4","" +"rate_base_ae","","base.ae","65","44","0.2","0.4","0.4","2025-12-31" +"rate_base_ae_2026","","base.ae","81","54","0.2","0.4","0.4","" +"rate_base_uy","","base.uy","40","27","0.2","0.4","0.4","" +"rate_base_us_atlanta","Atlanta","base.us","77","52","0.2","0.4","0.4","" +"rate_base_us_boston","Boston","base.us","63","42","0.2","0.4","0.4","" +"rate_base_us_chicago","Chicago","base.us","65","44","0.2","0.4","0.4","" +"rate_base_us_houston","Houston","base.us","62","41","0.2","0.4","0.4","" +"rate_base_us_los_angeles","Los Angeles","base.us","64","43","0.2","0.4","0.4","" +"rate_base_us_miami","Miami","base.us","65","44","0.2","0.4","0.4","" +"rate_base_us_new_york_city","New York City","base.us","66","44","0.2","0.4","0.4","" +"rate_base_us","","base.us","59","40","0.2","0.4","0.4","" +"rate_base_us_san_francisco","San Francisco","base.us","59","40","0.2","0.4","0.4","" +"rate_base_us_washington_dc","Washington D.C.","base.us","66","44","0.2","0.4","0.4","" +"rate_base_uz","","base.uz","34","23","0.2","0.4","0.4","2025-12-31" +"rate_base_uz_2026","","base.uz","32","21","0.2","0.4","0.4","" +"rate_base_ve","","base.ve","45","30","0.2","0.4","0.4","2025-12-31" +"rate_base_ve_2026","","base.ve","51","34","0.2","0.4","0.4","" +"rate_base_vn","","base.vn","36","24","0.2","0.4","0.4","" +"rate_base_ye","","base.ye","24","16","0.2","0.4","0.4","" +"rate_base_zm","","base.zm","38","25","0.2","0.4","0.4","" +"rate_base_zw","","base.zw","63","42","0.2","0.4","0.4","" diff --git a/hr_expense_meal_allowance/data/product_data.xml b/hr_expense_meal_allowance/data/product_data.xml new file mode 100644 index 00000000..e5970a06 --- /dev/null +++ b/hr_expense_meal_allowance/data/product_data.xml @@ -0,0 +1,17 @@ + + + + Expense / Meal Allowance + + + Meal Allowance + service + True + cost + + + + diff --git a/hr_expense_meal_allowance/i18n/de.po b/hr_expense_meal_allowance/i18n/de.po new file mode 100644 index 00000000..316daf8d --- /dev/null +++ b/hr_expense_meal_allowance/i18n/de.po @@ -0,0 +1,625 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_expense_meal_allowance +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-11-26 16:06+0000\n" +"PO-Revision-Date: 2025-11-26 16:06+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "2025-01-03" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "2025-01-05" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Breakfast Included?" +msgstr "Frühstück inbegriffen?" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Date" +msgstr "Datum" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Day" +msgstr "Tag" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Dinner Included?" +msgstr "Abendessen inbegriffen?" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Expenses For This Day" +msgstr "Spesen für diesen Tag" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Lunch Included?" +msgstr "Mittagessen inbegriffen?" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Meal Allowance" +msgstr "Verpflegungsmehraufwand" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Customer" +msgstr "Kunde" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Employee" +msgstr "Mitarbeiter" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Number Of Travel Days" +msgstr "Anzahl der Reisetage" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Number Of Whole Days" +msgstr "Anzahl der vollen Tage" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Total:" +msgstr "Gesamt:" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Travel Begin" +msgstr "Reisebeginn" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Travel End" +msgstr "Reiseende" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_gr_athens +msgid "Athens" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_us_atlanta +msgid "Atlanta" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Azure Interior" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_in_bangalore +msgid "Bangalore" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_es_barcelona +msgid "Barcelona" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_cn_beijing +msgid "Beijing" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_us_boston +msgid "Boston" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_br_brasilia +msgid "Brasilia" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__breakfast_rate +msgid "Breakfast Rate" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__breakfast_included +msgid "Breakfast included?" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_ro_bucharest +msgid "Bucharest" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_in_calcutta +msgid "Calcutta" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_es_canary_islands +msgid "Canary Islands" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_au_canberra +msgid "Canberra" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_cn_canton +msgid "Canton" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_za_cape_town +msgid "Cape Town" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_cn_chengu +msgid "Chengdu" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_in_chennai +msgid "Chennai" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_us_chicago +msgid "Chicago" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__city_name +msgid "City Name" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__country_id +msgid "Country" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__create_uid +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__create_uid +msgid "Created by" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__create_date +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__create_date +msgid "Created on" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__currency_id +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__currency_id +msgid "Currency" +msgstr "Währung" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense__customer_id +msgid "Customer" +msgstr "Kunde" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__daily_rate_24h +msgid "Daily Rate - 24h" +msgstr "Tagessatz - 24Std" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__daily_rate_8h +msgid "Daily Rate - 8h" +msgstr "Tagessatz - 8Std" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__date +msgid "Date" +msgstr "Datum" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__day +msgid "Day" +msgstr "Tag" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__dinner_rate +msgid "Dinner Rate" +msgstr "Abendessenssatz" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__dinner_included +msgid "Dinner included?" +msgstr "Abendessen inbegriffen?" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__display_name +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__display_name +msgid "Display Name" +msgstr "Anzeigename" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_sa_djidda +msgid "Djidda" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__employee_id +msgid "Employee" +msgstr "Mitarbeiter" + +#. module: hr_expense_meal_allowance +#: model:ir.model,name:hr_expense_meal_allowance.model_hr_expense +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__hr_expense_id +msgid "Expense" +msgstr "Ausgabe" + +#. module: hr_expense_meal_allowance +#: model:product.tag,name:hr_expense_meal_allowance.product_tag_meal_allowance +msgid "Expense / Meal Allowance" +msgstr "Ausgabe / Verpflegungsmehraufwand" + +#. module: hr_expense_meal_allowance +#: model:ir.model,name:hr_expense_meal_allowance.model_hr_expense_meal_allowance +msgid "Expense Meal Allowances for a date." +msgstr "Verpflegungsmehraufwand für ein Datum." + +#. module: hr_expense_meal_allowance +#: model:ir.model,name:hr_expense_meal_allowance.model_hr_expense_sheet +msgid "Expense Report" +msgstr "Spesenreport" + +#. module: hr_expense_meal_allowance +#: model:ir.model,name:hr_expense_meal_allowance.model_hr_expense_meal_allowance_rate +msgid "Expense meal allowances rate for a city or country." +msgstr "Verpflegungsmehraufwandssatz für eine Stadt oder ein Land." + +#. module: hr_expense_meal_allowance +#: model:ir.actions.report,name:hr_expense_meal_allowance.action_report_hr_expense_meal_allowance +msgid "Expenses Report" +msgstr "Spesenreport" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__expense_for_day +msgid "Expenses for This Day" +msgstr "Ausgaben für diesen Tag" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_pl_gdansk +msgid "Gdansk" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_ch_geneve +msgid "Geneva" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_cn_hong_kong +msgid "Hong Kong" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_us_houston +msgid "Houston" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__id +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__id +msgid "ID" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense__meal_allowance_ids +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.hr_expense_sheet_view_form_extended +msgid "Included Meals" +msgstr "Beinhaltete Mahlzeiten" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__is_editable +msgid "Is Editable By Current User" +msgstr "Ist vom aktuellen Benutzer bearbeitbar" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense__is_meal_allowance +msgid "Is Meal Allowance" +msgstr "Ist Verpflegungsmehraufwand" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_pk_islamabad +msgid "Islamabad" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_tr_istanbul +msgid "Istanbul" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_tr_izmir +msgid "Izmir" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_za_johannisbourg +msgid "Johannisburg" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_pl_krakow +msgid "Krakow" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__write_uid +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__write_date +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__write_date +msgid "Last Updated on" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_uk_london +msgid "London" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_us_los_angeles +msgid "Los Angeles" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__lunch_rate +msgid "Lunch Rate" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__lunch_included +msgid "Lunch included?" +msgstr "Mittagessen inbegriffen?" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_es_madrid +msgid "Madrid" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.actions.act_window,name:hr_expense_meal_allowance.action_hr_expense_meal_allowance +#: model:ir.ui.menu,name:hr_expense_meal_allowance.expense_included_meal_menu +msgid "Meal Allowance" +msgstr "Verpflegungsmehraufwand" + +#. module: hr_expense_meal_allowance +#: model:ir.actions.act_window,name:hr_expense_meal_allowance.action_hr_expense_meal_allowance_rate +#: model:ir.ui.menu,name:hr_expense_meal_allowance.menu_hr_meal_allowance_rate +msgid "Meal Allowance Rate" +msgstr "Verpflegungsmehraufwandsatz" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_us_miami +msgid "Miami" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_it_milan +msgid "Milan" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Mitchell Admin" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_ru_moscow +msgid "Moscow" +msgstr "" + +#. module: hr_expense_meal_allowance +#. odoo-python +#: code:addons/hr_expense_meal_allowance/models/hr_expense.py:0 +msgid "Multiple currencies found in meal allowance lines." +msgstr "Mehrere Währungen in Verpflegungsmehraufwand-Zeilen gefunden." + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_in_mumbai +msgid "Mumbai" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_in_new_delhi +msgid "New Delhi" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_us_new_york_city +msgid "New York City" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense__number_of_days +msgid "Number Of Days" +msgstr "Anzahl ganze Tage" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense__number_of_travel_days +msgid "Number Of Travel Days" +msgstr "Anzahl An-/Abreise Tage" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_ca_ottawa +msgid "Ottawa" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_es_palma_de_mallorca +msgid "Palma de Mallorca" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_fr_paris +msgid "Paris" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__percentage_for_breakfast +msgid "Percentage for Breakfast" +msgstr "Prozentsatz für Frühstück" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__percentage_for_dinner +msgid "Percentage for Dinner" +msgstr "Prozentsatz für Abendessen" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__percentage_for_lunch +msgid "Percentage for Lunch" +msgstr "Prozentsatz für Mittagessen" + +#. module: hr_expense_meal_allowance +#. odoo-python +#: code:addons/hr_expense_meal_allowance/models/hr_expense.py:0 +#: code:addons/hr_expense_meal_allowance/models/hr_expense_meal_allowance.py:0 +msgid "Please set a timezone in user settings" +msgstr "Bitte legen Sie eine Zeitzone in den Benutzereinstellungen fest" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.hr_expense_sheet_view_form_extended +msgid "Print Expenses" +msgstr "Ausgaben drucken" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense__meal_allowance_rate_id +msgid "Rate" +msgstr "Satz" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_br_rio_de_jeneiro +msgid "Rio de Janeiro" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_sa_riyadh +msgid "Riyadh" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_it_rome +msgid "Rome" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_us_san_francisco +msgid "San Francisco" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_br_sao_paulo +msgid "Sao Paulo" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_cn_shanghai +msgid "Shanghai" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_ru_st_petersburg +msgid "St. Petersburg" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_au_sydney +msgid "Sydney" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_jp_tokyo +msgid "Tokyo" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_ca_toronto +msgid "Toronto" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense__travel_begin +msgid "Travel Begin" +msgstr "Reisebeginn" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense__travel_end +msgid "Travel End" +msgstr "Reiseende" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.hr_expense_sheet_view_form_extended +msgid "Travel Information" +msgstr "Reiseinformationen" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,help:hr_expense_meal_allowance.field_hr_expense_meal_allowance__currency_id +msgid "Utility field to express amount currency" +msgstr "Hilfsfeld zur Angabe der Währungsbeträge" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_ca_vancouver +msgid "Vancouver" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:product.template,name:hr_expense_meal_allowance.product_meal_allowance +msgid "Verpflegungsmehraufwand" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_pl_warsaw +msgid "Warsaw" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_us_washington_dc +msgid "Washington D.C." +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_pl_wroclaw +msgid "Wroclaw" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_ru_yekatarinburg +msgid "Yekatarinburg" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_fr_dep_92_94 +msgid "departments 92-94" +msgstr "" diff --git a/hr_expense_meal_allowance/i18n/hr_expense_meal_allowance.pot b/hr_expense_meal_allowance/i18n/hr_expense_meal_allowance.pot new file mode 100644 index 00000000..11e5a4c8 --- /dev/null +++ b/hr_expense_meal_allowance/i18n/hr_expense_meal_allowance.pot @@ -0,0 +1,625 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * hr_expense_meal_allowance +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-11-26 16:06+0000\n" +"PO-Revision-Date: 2025-11-26 16:06+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "2025-01-03" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "2025-01-05" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Breakfast Included?" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Date" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Day" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Dinner Included?" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Expenses For This Day" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Lunch Included?" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Meal Allowance" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Customer" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Employee" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Number Of Travel Days" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Number Of Whole Days" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Total:" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Travel Begin" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Travel End" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_gr_athens +msgid "Athens" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_us_atlanta +msgid "Atlanta" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Azure Interior" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_in_bangalore +msgid "Bangalore" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_es_barcelona +msgid "Barcelona" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_cn_beijing +msgid "Beijing" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_us_boston +msgid "Boston" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_br_brasilia +msgid "Brasilia" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__breakfast_rate +msgid "Breakfast Rate" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__breakfast_included +msgid "Breakfast included?" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_ro_bucharest +msgid "Bucharest" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_in_calcutta +msgid "Calcutta" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_es_canary_islands +msgid "Canary Islands" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_au_canberra +msgid "Canberra" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_cn_canton +msgid "Canton" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_za_cape_town +msgid "Cape Town" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_cn_chengu +msgid "Chengdu" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_in_chennai +msgid "Chennai" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_us_chicago +msgid "Chicago" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__city_name +msgid "City Name" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__country_id +msgid "Country" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__create_uid +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__create_uid +msgid "Created by" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__create_date +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__create_date +msgid "Created on" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__currency_id +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__currency_id +msgid "Currency" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense__customer_id +msgid "Customer" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__daily_rate_24h +msgid "Daily Rate - 24h" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__daily_rate_8h +msgid "Daily Rate - 8h" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__date +msgid "Date" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__day +msgid "Day" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__dinner_rate +msgid "Dinner Rate" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__dinner_included +msgid "Dinner included?" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__display_name +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__display_name +msgid "Display Name" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_sa_djidda +msgid "Djidda" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__employee_id +msgid "Employee" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model,name:hr_expense_meal_allowance.model_hr_expense +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__hr_expense_id +msgid "Expense" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:product.tag,name:hr_expense_meal_allowance.product_tag_meal_allowance +msgid "Expense / Meal Allowance" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model,name:hr_expense_meal_allowance.model_hr_expense_meal_allowance +msgid "Expense Meal Allowances for a date." +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model,name:hr_expense_meal_allowance.model_hr_expense_sheet +msgid "Expense Report" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model,name:hr_expense_meal_allowance.model_hr_expense_meal_allowance_rate +msgid "Expense meal allowances rate for a city or country." +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.actions.report,name:hr_expense_meal_allowance.action_report_hr_expense_meal_allowance +msgid "Expenses Report" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__expense_for_day +msgid "Expenses for This Day" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_pl_gdansk +msgid "Gdansk" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_ch_geneve +msgid "Geneva" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_cn_hong_kong +msgid "Hong Kong" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_us_houston +msgid "Houston" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__id +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__id +msgid "ID" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense__meal_allowance_ids +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.hr_expense_sheet_view_form_extended +msgid "Included Meals" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__is_editable +msgid "Is Editable By Current User" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense__is_meal_allowance +msgid "Is Meal Allowance" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_pk_islamabad +msgid "Islamabad" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_tr_istanbul +msgid "Istanbul" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_tr_izmir +msgid "Izmir" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_za_johannisbourg +msgid "Johannisburg" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_pl_krakow +msgid "Krakow" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__write_uid +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__write_date +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__write_date +msgid "Last Updated on" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_uk_london +msgid "London" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_us_los_angeles +msgid "Los Angeles" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__lunch_rate +msgid "Lunch Rate" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance__lunch_included +msgid "Lunch included?" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_es_madrid +msgid "Madrid" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.actions.act_window,name:hr_expense_meal_allowance.action_hr_expense_meal_allowance +#: model:ir.ui.menu,name:hr_expense_meal_allowance.expense_included_meal_menu +msgid "Meal Allowance" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.actions.act_window,name:hr_expense_meal_allowance.action_hr_expense_meal_allowance_rate +#: model:ir.ui.menu,name:hr_expense_meal_allowance.menu_hr_meal_allowance_rate +msgid "Meal Allowance Rate" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_us_miami +msgid "Miami" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_it_milan +msgid "Milan" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.report_expense_meal_allowance +msgid "Mitchell Admin" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_ru_moscow +msgid "Moscow" +msgstr "" + +#. module: hr_expense_meal_allowance +#. odoo-python +#: code:addons/hr_expense_meal_allowance/models/hr_expense.py:0 +msgid "Multiple currencies found in meal allowance lines." +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_in_mumbai +msgid "Mumbai" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_in_new_delhi +msgid "New Delhi" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_us_new_york_city +msgid "New York City" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense__number_of_days +msgid "Number Of Days" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense__number_of_travel_days +msgid "Number Of Travel Days" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_ca_ottawa +msgid "Ottawa" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_es_palma_de_mallorca +msgid "Palma de Mallorca" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_fr_paris +msgid "Paris" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__percentage_for_breakfast +msgid "Percentage for Breakfast" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__percentage_for_dinner +msgid "Percentage for Dinner" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense_meal_allowance_rate__percentage_for_lunch +msgid "Percentage for Lunch" +msgstr "" + +#. module: hr_expense_meal_allowance +#. odoo-python +#: code:addons/hr_expense_meal_allowance/models/hr_expense.py:0 +#: code:addons/hr_expense_meal_allowance/models/hr_expense_meal_allowance.py:0 +msgid "Please set a timezone in user settings" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.hr_expense_sheet_view_form_extended +msgid "Print Expenses" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense__meal_allowance_rate_id +msgid "Rate" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_br_rio_de_jeneiro +msgid "Rio de Janeiro" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_sa_riyadh +msgid "Riyadh" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_it_rome +msgid "Rome" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_us_san_francisco +msgid "San Francisco" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_br_sao_paulo +msgid "Sao Paulo" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_cn_shanghai +msgid "Shanghai" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_ru_st_petersburg +msgid "St. Petersburg" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_au_sydney +msgid "Sydney" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_jp_tokyo +msgid "Tokyo" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_ca_toronto +msgid "Toronto" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense__travel_begin +msgid "Travel Begin" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,field_description:hr_expense_meal_allowance.field_hr_expense__travel_end +msgid "Travel End" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model_terms:ir.ui.view,arch_db:hr_expense_meal_allowance.hr_expense_sheet_view_form_extended +msgid "Travel Information" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:ir.model.fields,help:hr_expense_meal_allowance.field_hr_expense_meal_allowance__currency_id +msgid "Utility field to express amount currency" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_ca_vancouver +msgid "Vancouver" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:product.template,name:hr_expense_meal_allowance.product_meal_allowance +msgid "Verpflegungsmehraufwand" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_pl_warsaw +msgid "Warsaw" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_us_washington_dc +msgid "Washington D.C." +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_pl_wroclaw +msgid "Wroclaw" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_ru_yekatarinburg +msgid "Yekatarinburg" +msgstr "" + +#. module: hr_expense_meal_allowance +#: model:hr.expense.meal.allowance.rate,city_name:hr_expense_meal_allowance.rate_base_fr_dep_92_94 +msgid "departments 92-94" +msgstr "" diff --git a/hr_expense_meal_allowance/migrations/18.0.1.1.0/post-migration.py b/hr_expense_meal_allowance/migrations/18.0.1.1.0/post-migration.py new file mode 100644 index 00000000..d185fe9d --- /dev/null +++ b/hr_expense_meal_allowance/migrations/18.0.1.1.0/post-migration.py @@ -0,0 +1,11 @@ +from odoo import SUPERUSER_ID, api + + +def migrate(cr, version): + env = api.Environment(cr, SUPERUSER_ID, {}) + + rates = env["hr.expense.meal.allowance.rate"].search([]) + for rate in rates: + rate.percentage_for_breakfast /= 100 + rate.percentage_for_lunch /= 100 + rate.percentage_for_dinner /= 100 diff --git a/hr_expense_meal_allowance/models/__init__.py b/hr_expense_meal_allowance/models/__init__.py new file mode 100644 index 00000000..325aba5f --- /dev/null +++ b/hr_expense_meal_allowance/models/__init__.py @@ -0,0 +1,4 @@ +from . import hr_expense_meal_allowance +from . import hr_expense +from . import hr_expense_meal_allowance_rate +from . import hr_expense_sheet diff --git a/hr_expense_meal_allowance/models/hr_expense.py b/hr_expense_meal_allowance/models/hr_expense.py new file mode 100644 index 00000000..f40a39ed --- /dev/null +++ b/hr_expense_meal_allowance/models/hr_expense.py @@ -0,0 +1,174 @@ +from datetime import date, timedelta + +import pytz + +from odoo import Command, api, fields, models +from odoo.exceptions import UserError + + +class HrExpense(models.Model): + _inherit = "hr.expense" + + travel_begin = fields.Datetime() + travel_end = fields.Datetime() + customer_id = fields.Many2one("res.partner") + meal_allowance_rate_id = fields.Many2one( + "hr.expense.meal.allowance.rate", + string="Rate", + domain="['|', ('expire_on', '=', False),('expire_on', '>=', travel_end)]", + ) + + number_of_days = fields.Integer(compute="_compute_number_of_travel_days") + number_of_travel_days = fields.Integer(compute="_compute_number_of_travel_days") + meal_allowance_ids = fields.One2many( + "hr.expense.meal.allowance", "hr_expense_id", string="Included Meals" + ) + is_meal_allowance = fields.Boolean(compute="_compute_meal_allowance_tag") + + @api.onchange("product_id") + def _compute_meal_allowance_tag(self): + meal_allowance_tag = self.env.ref( + "hr_expense_meal_allowance.product_tag_meal_allowance", False + ) + for record in self: + record.is_meal_allowance = record.meal_allowance_ids or ( + meal_allowance_tag + and meal_allowance_tag in record.product_id.product_tag_ids + ) + + @api.depends("meal_allowance_ids") + def _compute_number_of_travel_days(self): + for record in self: + if not record.meal_allowance_ids or len(record.meal_allowance_ids) == 0: + record.number_of_days = 0 + record.number_of_travel_days = 0 + elif len(record.meal_allowance_ids) == 1: + record.number_of_days = 0 + record.number_of_travel_days = 1 + else: + record.number_of_days = len(record.meal_allowance_ids) - 2 + record.number_of_travel_days = 2 + + @api.onchange("travel_begin", "travel_end", "customer_id") + def _update_meal_lines(self): + for record in self: + if ( + not record.travel_begin + or not record.travel_end + or not record.is_meal_allowance + ): + record.meal_allowance_ids.unlink() + continue + + if record.travel_end: + record.date = record.travel_end.date() + + if record.is_meal_allowance: + # always use the timezone of the employee + timezone = record.employee_id.user_id.tz or self.env.user.tz + if not timezone: + raise UserError( + self.env._("Please set a timezone in user settings") + ) + + # create a line for each day in the timezone of the employee + tz = pytz.timezone(timezone) + local_start_date = record.travel_begin.astimezone(tz).date() + local_end_date = record.travel_end.astimezone(tz).date() + date_range = [ + local_start_date + timedelta(n) + for n in range((local_end_date - local_start_date).days + 1) + ] + + # Map existing lines by date + existing_lines_by_date = { + line.date: line for line in record.meal_allowance_ids + } + + # Prepare new lines, preserving values for overlapping dates + new_entries = [] + for date_ds in date_range: + existing_line = existing_lines_by_date.get(date_ds) + if existing_line: + new_entries.append(Command.link(existing_line.id)) + else: + new_entries.append( + Command.create( + { + "date": date_ds, + "hr_expense_id": record.id, + } + ) + ) + + # Remove all old lines and recreate + for unlink in record.meal_allowance_ids.filtered( + lambda allowance, date_range=date_range: allowance.date + not in date_range + ): + new_entries.append(Command.unlink(unlink.id)) + record.meal_allowance_ids = new_entries + + @api.depends("meal_allowance_ids") + def _compute_total_amount_currency(self): + res = super( + HrExpense, self.filtered(lambda x: not x.is_meal_allowance) + )._compute_total_amount_currency() + + for expense in self.filtered(lambda x: x.is_meal_allowance): + price = sum(map(lambda x: x.expense_for_day, expense.meal_allowance_ids)) + expense.total_amount_currency = price + + currency = expense.meal_allowance_rate_id.currency_id + if len(currency) > 1: + raise UserError( + self.env._("Multiple currencies found in meal allowance lines.") + ) + expense.currency_id = currency + expense._inverse_total_amount_currency() + + return res + + @api.onchange("customer_id", "travel_end") + def _onchange_customer(self): + for record in self: + rates = [] + + if record.customer_id.city and record.customer_id.country_id: + rates = self.env["hr.expense.meal.allowance.rate"].search( + [ + ("country_id", "=", record.customer_id.country_id.id), + ("city_name", "=", record.customer_id.city), + "|", + ("expire_on", "=", False), + ("expire_on", ">=", record.travel_end.date()), + ], + ) + + if not rates and record.customer_id.country_id: + rates = self.env["hr.expense.meal.allowance.rate"].search( + [ + ("country_id", "=", record.customer_id.country_id.id), + ("city_name", "=", ""), + "|", + ("expire_on", "=", False), + ("expire_on", ">=", record.travel_end.date()), + ], + ) + rates = sorted( + rates, + key=lambda r: (r.expire_on is None, r.expire_on or date.max), + ) + + record.meal_allowance_rate_id = rates[0] if rates else False + + def action_print(self): + self.ensure_one() + lang = self.employee_id.lang or self.employee_id.company_id.partner_id.lang + return ( + self.env.ref( + "hr_expense_meal_allowance.action_report_hr_expense_meal_allowance" + ) + .with_context(lang=lang) + .report_action(self) + ) diff --git a/hr_expense_meal_allowance/models/hr_expense_meal_allowance.py b/hr_expense_meal_allowance/models/hr_expense_meal_allowance.py new file mode 100644 index 00000000..19268280 --- /dev/null +++ b/hr_expense_meal_allowance/models/hr_expense_meal_allowance.py @@ -0,0 +1,101 @@ +from datetime import timedelta + +import pytz + +from odoo import api, fields, models +from odoo.exceptions import UserError + + +class HrExpenseMealAllowance(models.Model): + _name = "hr.expense.meal.allowance" + _description = "Expense Meal Allowances for a date." + _order = "date" + + date = fields.Date(required=True) + day = fields.Char(compute="_compute_date") + breakfast_included = fields.Boolean(string="Breakfast included?") + lunch_included = fields.Boolean(string="Lunch included?") + dinner_included = fields.Boolean(string="Dinner included?") + + currency_id = fields.Many2one( + "res.currency", + related="hr_expense_id.currency_id", + readonly=True, + help="Utility field to express amount currency", + ) + expense_for_day = fields.Monetary( + string="Expenses for This Day", + compute="_compute_expense_for_day", + currency_field="currency_id", + ) + hr_expense_id = fields.Many2one("hr.expense", string="Expense", readonly=True) + + employee_id = fields.Many2one(related="hr_expense_id.employee_id") + is_editable = fields.Boolean( + related="hr_expense_id.is_editable", + ) + + @api.depends("date") + def _compute_date(self): + for record in self: + if record.date: + record.day = self.env._(record.date.strftime("%A")) + else: + record.day = "" + + @api.depends( + "date", + "breakfast_included", + "lunch_included", + "dinner_included", + "hr_expense_id.travel_end", + "hr_expense_id.travel_begin", + "hr_expense_id.meal_allowance_rate_id", + ) + def _compute_expense_for_day(self): + for record in self: + # always use the timezone of the employee + timezone = record.employee_id.user_id.tz or self.env.user.tz + if not timezone: + raise UserError(self.env._("Please set a timezone in user settings")) + + expense_for_day = 0 + if ( + record.date + and record.hr_expense_id.travel_end + and record.hr_expense_id.travel_begin + ): + tz = pytz.timezone(timezone) + date_travel_begin = record.hr_expense_id.travel_begin.astimezone( + tz + ).date() + date_travel_end = record.hr_expense_id.travel_end.astimezone(tz).date() + + city = record.hr_expense_id.meal_allowance_rate_id + if date_travel_begin == date_travel_end: + # one day trip + duration = ( + record.hr_expense_id.travel_end + - record.hr_expense_id.travel_begin + ) + if duration > timedelta(hours=8): + expense_for_day = city.daily_rate_8h + + elif record.date in [date_travel_begin, date_travel_end]: + # trip start or end day + expense_for_day = ( + record.hr_expense_id.meal_allowance_rate_id.daily_rate_8h + ) + else: + expense_for_day = ( + record.hr_expense_id.meal_allowance_rate_id.daily_rate_24h + ) + + if record.breakfast_included: + expense_for_day -= city.breakfast_rate + if record.lunch_included: + expense_for_day -= city.lunch_rate + if record.dinner_included: + expense_for_day -= city.dinner_rate + + record.expense_for_day = max(expense_for_day, 0) diff --git a/hr_expense_meal_allowance/models/hr_expense_meal_allowance_rate.py b/hr_expense_meal_allowance/models/hr_expense_meal_allowance_rate.py new file mode 100644 index 00000000..b36b75c8 --- /dev/null +++ b/hr_expense_meal_allowance/models/hr_expense_meal_allowance_rate.py @@ -0,0 +1,68 @@ +from odoo import api, fields, models +from odoo.tools import format_date + + +class HrExpenseMealAllowanceRate(models.Model): + _name = "hr.expense.meal.allowance.rate" + _description = "Expense meal allowances rate for a city or country." + + city_name = fields.Char(translate=True) + country_id = fields.Many2one("res.country", required=True) + daily_rate_24h = fields.Monetary(string="Daily Rate - 24h") + daily_rate_8h = fields.Monetary(string="Daily Rate - 8h") + percentage_for_breakfast = fields.Float( + string="Percentage for Breakfast", default=0.2 + ) + percentage_for_lunch = fields.Float(string="Percentage for Lunch", default=0.4) + percentage_for_dinner = fields.Float(string="Percentage for Dinner", default=0.4) + + breakfast_rate = fields.Monetary(compute="_compute_expense_rate") + lunch_rate = fields.Monetary(compute="_compute_expense_rate") + dinner_rate = fields.Monetary(compute="_compute_expense_rate") + currency_id = fields.Many2one( + "res.currency", + string="Currency", + required=True, + default=lambda self: self.env.ref("base.EUR").id, + ) + expire_on = fields.Date() + + @api.model + def _search_display_name(self, operator, value): + if isinstance(value, str) and value: + domain = [ + "|", + ("country_id.name", operator, value), + ("city_name", operator, value), + ] + return domain + return super()._search_display_name(operator, value) + + @api.depends( + "daily_rate_24h", + "percentage_for_breakfast", + "percentage_for_lunch", + "percentage_for_dinner", + ) + def _compute_expense_rate(self): + for rate in self: + rate.breakfast_rate = rate.daily_rate_24h * rate.percentage_for_breakfast + rate.lunch_rate = rate.daily_rate_24h * rate.percentage_for_lunch + rate.dinner_rate = rate.daily_rate_24h * rate.percentage_for_dinner + + @api.depends("city_name", "country_id") + def _compute_display_name(self): + for rate in self: + display_name = "" + if rate.city_name: + display_name = f"{rate.country_id.name} - {rate.city_name}" + else: + display_name = rate.country_id.name + + if rate.expire_on: + display_name += self.env._( + " (valid until %(expire_on)s)", + expire_on=format_date(self.env, rate.expire_on), + ) + + rate.display_name = display_name diff --git a/hr_expense_meal_allowance/models/hr_expense_sheet.py b/hr_expense_meal_allowance/models/hr_expense_sheet.py new file mode 100644 index 00000000..9025f731 --- /dev/null +++ b/hr_expense_meal_allowance/models/hr_expense_sheet.py @@ -0,0 +1,22 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import models + + +class HrExpenseSheet(models.Model): + _inherit = "hr.expense.sheet" + + def _do_create_moves(self): + for sheet in self: + for expense in sheet.expense_line_ids.filtered( + lambda expense: expense.is_meal_allowance + and not expense.message_attachment_count + ): + lang = ( + self.employee_id.lang or self.employee_id.company_id.partner_id.lang + ) + self.env["ir.actions.report"].with_context(lang=lang)._render_qweb_pdf( + "hr_expense_meal_allowance.action_report_hr_expense_meal_allowance", + expense.id, + ) + return super()._do_create_moves() diff --git a/hr_expense_meal_allowance/pyproject.toml b/hr_expense_meal_allowance/pyproject.toml new file mode 100644 index 00000000..4231d0cc --- /dev/null +++ b/hr_expense_meal_allowance/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/hr_expense_meal_allowance/readme/DESCRIPTION.md b/hr_expense_meal_allowance/readme/DESCRIPTION.md new file mode 100644 index 00000000..74242fa3 --- /dev/null +++ b/hr_expense_meal_allowance/readme/DESCRIPTION.md @@ -0,0 +1,11 @@ +Adds German "Verpflegungsmehraufwände" processing in the expense module. + +When a meal allowance product is selected, the UI is changed as following. +![meal allowance rates](../static/description/expense_1.png) +![meal allowance rates](../static/description/expense_2.png) + +The product tag controls whether the Product is of type meal allowance and controls the UI. +![meal allowance rates](../static/description/product_tag.png) + +The rates are imported by a csv file. When a rate changes for a certain country, create a new csv line and set the expire_on date on the existing line. +![meal allowance rates](../static/description/settings_rates.png) \ No newline at end of file diff --git a/hr_expense_meal_allowance/report/expense_included_meal.xml b/hr_expense_meal_allowance/report/expense_included_meal.xml new file mode 100644 index 00000000..e458de04 --- /dev/null +++ b/hr_expense_meal_allowance/report/expense_included_meal.xml @@ -0,0 +1,193 @@ + + + + diff --git a/hr_expense_meal_allowance/report/expense_included_meal_report.xml b/hr_expense_meal_allowance/report/expense_included_meal_report.xml new file mode 100644 index 00000000..387bbb51 --- /dev/null +++ b/hr_expense_meal_allowance/report/expense_included_meal_report.xml @@ -0,0 +1,19 @@ + + + + Expenses Report + hr.expense + qweb-pdf + hr_expense_meal_allowance.report_expense_meal_allowance + hr_expense_meal_allowance.report_expense_meal_allowance + + report + ((object.name or 'Expenses').replace('/','_')+'.pdf') + + diff --git a/hr_expense_meal_allowance/security/ir.model.access.csv b/hr_expense_meal_allowance/security/ir.model.access.csv new file mode 100644 index 00000000..92404854 --- /dev/null +++ b/hr_expense_meal_allowance/security/ir.model.access.csv @@ -0,0 +1,4 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_user_hr_expense_meal_allowance,hr.expense.meal.allowance,hr_expense_meal_allowance.model_hr_expense_meal_allowance,base.group_user,1,1,1,1 +access_user_hr_expense_meal_allowance_rate,hr.expense.meal.allowance.rate,hr_expense_meal_allowance.model_hr_expense_meal_allowance_rate,base.group_user,1,0,0,0 +access_user_hr_expense_meal_allowance_rate_manager,hr.expense.meal.allowance.rate,hr_expense_meal_allowance.model_hr_expense_meal_allowance_rate,hr_expense.group_hr_expense_manager,1,1,1,1 diff --git a/hr_expense_meal_allowance/security/ir_rule.xml b/hr_expense_meal_allowance/security/ir_rule.xml new file mode 100644 index 00000000..b5b31111 --- /dev/null +++ b/hr_expense_meal_allowance/security/ir_rule.xml @@ -0,0 +1,19 @@ + + + + Manager Expense + + [('employee_id.user_id', '=', user.id), ('state', '!=', 'draft')] + + + + + + diff --git a/hr_expense_meal_allowance/static/description/expense_1.png b/hr_expense_meal_allowance/static/description/expense_1.png new file mode 100644 index 00000000..212aca24 Binary files /dev/null and b/hr_expense_meal_allowance/static/description/expense_1.png differ diff --git a/hr_expense_meal_allowance/static/description/expense_2.png b/hr_expense_meal_allowance/static/description/expense_2.png new file mode 100644 index 00000000..16d89ae7 Binary files /dev/null and b/hr_expense_meal_allowance/static/description/expense_2.png differ diff --git a/hr_expense_meal_allowance/static/description/icon.png b/hr_expense_meal_allowance/static/description/icon.png new file mode 100644 index 00000000..3a0328b5 Binary files /dev/null and b/hr_expense_meal_allowance/static/description/icon.png differ diff --git a/hr_expense_meal_allowance/static/description/index.html b/hr_expense_meal_allowance/static/description/index.html new file mode 100644 index 00000000..ed90a62e --- /dev/null +++ b/hr_expense_meal_allowance/static/description/index.html @@ -0,0 +1,429 @@ + + + + + +Hr Expense Meal Allowance + + + +
+

Hr Expense Meal Allowance

+ + +

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

+

Adds German “Verpflegungsmehraufwände” processing in the expense module.

+

When a meal allowance product is selected, the UI is changed as +following. meal allowance rates image1

+
+
The product tag controls whether the Product is of type meal allowance +and controls the UI.
+
image2
+
+

The rates are imported by a csv file. When a rate changes for a certain +country, create a new csv line and set the expire_on date on the +existing line. image3

+

Table of contents

+ +
+

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

+
    +
  • IFE Gesellschaft für Forschung und Entwicklung
  • +
  • glueckkanja AG
  • +
+
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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

+

Current maintainer:

+

CRogos

+

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

+

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

+
+
+
+ + diff --git a/hr_expense_meal_allowance/static/description/product_tag.png b/hr_expense_meal_allowance/static/description/product_tag.png new file mode 100644 index 00000000..1e7c68b7 Binary files /dev/null and b/hr_expense_meal_allowance/static/description/product_tag.png differ diff --git a/hr_expense_meal_allowance/static/description/settings_rates.png b/hr_expense_meal_allowance/static/description/settings_rates.png new file mode 100644 index 00000000..7d401397 Binary files /dev/null and b/hr_expense_meal_allowance/static/description/settings_rates.png differ diff --git a/hr_expense_meal_allowance/tests/__init__.py b/hr_expense_meal_allowance/tests/__init__.py new file mode 100644 index 00000000..b232a4b9 --- /dev/null +++ b/hr_expense_meal_allowance/tests/__init__.py @@ -0,0 +1,3 @@ +from . import test_hr_expense_meal_allowance +from . import test_hr_expense_meal_allowance_rate +from . import test_hr_expense diff --git a/hr_expense_meal_allowance/tests/test_hr_expense.py b/hr_expense_meal_allowance/tests/test_hr_expense.py new file mode 100644 index 00000000..f263baa9 --- /dev/null +++ b/hr_expense_meal_allowance/tests/test_hr_expense.py @@ -0,0 +1,74 @@ +from datetime import datetime + +from odoo.tests import Form + +from odoo.addons.base.tests.common import BaseCommon + + +class HrExpense(BaseCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.country = cls.env.ref("base.de") + cls.product = cls.env.ref( + "hr_expense_meal_allowance.product_meal_allowance" + ).product_variant_id + cls.customer = cls.env["res.partner"].create( + { + "name": "Test Customer", + "city": "Berlin", + "country_id": cls.country.id, + } + ) + + cls.employee = cls.env.ref("hr.employee_admin") + + cls.rate = cls.env["hr.expense.meal.allowance.rate"].create( + { + "country_id": cls.country.id, + "city_name": "Berlin", + "currency_id": cls.env.ref("base.EUR").id, + "expire_on": datetime(2023, 12, 31).date(), + } + ) + cls.rate_before = cls.env["hr.expense.meal.allowance.rate"].create( + { + "country_id": cls.country.id, + "city_name": "Berlin", + "currency_id": cls.env.ref("base.EUR").id, + "expire_on": datetime(2022, 12, 31).date(), + } + ) + cls.rate_next = cls.env["hr.expense.meal.allowance.rate"].create( + { + "country_id": cls.country.id, + "city_name": "Berlin", + "currency_id": cls.env.ref("base.EUR").id, + "expire_on": False, + } + ) + + def test_rate_display_name(self): + """Test that meal allowance rate display name is correct.""" + # assert + self.assertEqual( + self.rate.display_name, "Germany - Berlin (valid until 12/31/2023)" + ) + self.assertEqual( + self.rate_before.display_name, "Germany - Berlin (valid until 12/31/2022)" + ) + self.assertEqual(self.rate_next.display_name, "Germany - Berlin") + + def test_onchange_customer_with_city_and_country(self): + """Test that meal allowance rate is set to correct year.""" + + # act + with Form(self.env["hr.expense"]) as f: + f.product_id = self.product + f.employee_id = self.employee + f.travel_begin = datetime(2023, 10, 30, 8, 0, 0) + f.travel_end = datetime(2023, 10, 31, 18, 0, 0) + f.customer_id = self.customer + + # assert + self.assertEqual(f.meal_allowance_rate_id, self.rate) diff --git a/hr_expense_meal_allowance/tests/test_hr_expense_meal_allowance.py b/hr_expense_meal_allowance/tests/test_hr_expense_meal_allowance.py new file mode 100644 index 00000000..4e86f58e --- /dev/null +++ b/hr_expense_meal_allowance/tests/test_hr_expense_meal_allowance.py @@ -0,0 +1,56 @@ +from datetime import datetime + +from odoo.addons.base.tests.common import BaseCommon + + +class HrExpenseMealAllowance(BaseCommon): + def setUp(self): + super().setUp() + # Create currency and company + self.currency = self.env.ref("base.USD") + self.company = self.env.ref("base.main_company") + # Create user and employee + self.user = self.env.ref("base.user_admin") + self.employee = self.env.ref("hr.employee_admin") + + # Create city with rates + self.rate_with_city_name = self.env["hr.expense.meal.allowance.rate"].create( + { + "city_name": "Test City", + "country_id": self.env.ref("base.de").id, # Assuming DE as the country + "daily_rate_8h": 50, + "daily_rate_24h": 100, + } + ) + + # Create city with rates + self.rate_without_city_name = self.env["hr.expense.meal.allowance.rate"].create( + { + "country_id": self.env.ref("base.es").id, # Assuming ES as the country + "daily_rate_8h": 100, + "daily_rate_24h": 200, + } + ) + + # Create hr.expense + self.travel_begin = datetime(2024, 6, 1, 8, 0, 0) + self.travel_end = datetime(2024, 6, 1, 18, 30, 0) + self.hr_expense = self.env["hr.expense"].create( + { + "name": "Test Expense", + "employee_id": self.employee.id, + "travel_begin": datetime(2024, 6, 1, 8, 0, 0), + "travel_end": datetime(2024, 6, 1, 18, 30, 0), + "meal_allowance_rate_id": self.rate_with_city_name.id, + "company_id": self.company.id, + } + ) + + def test_compute_day_field(self): + meal = self.env["hr.expense.meal.allowance"].create( + { + "date": "2024-06-01", + "hr_expense_id": self.hr_expense.id, + } + ) + self.assertEqual(meal.day, "Saturday") diff --git a/hr_expense_meal_allowance/tests/test_hr_expense_meal_allowance_rate.py b/hr_expense_meal_allowance/tests/test_hr_expense_meal_allowance_rate.py new file mode 100644 index 00000000..8c298a67 --- /dev/null +++ b/hr_expense_meal_allowance/tests/test_hr_expense_meal_allowance_rate.py @@ -0,0 +1,41 @@ +from odoo.addons.base.tests.common import BaseCommon + + +class HrExpenseMealAllowance(BaseCommon): + def setUp(self): + super().setUp() + self.country = self.env["res.country"].search([], limit=1) + self.city = self.env["hr.expense.meal.allowance.rate"].create( + { + "city_name": "Test City", + "country_id": self.country.id, + "daily_rate_24h": 100.0, + "daily_rate_8h": 50.0, + "percentage_for_breakfast": 0.3, + "percentage_for_lunch": 0.5, + "percentage_for_dinner": 0.2, + } + ) + + def test_breakfast_rate(self): + self.assertAlmostEqual(self.city.breakfast_rate, 30.0) + + def test_lunch_rate(self): + self.assertAlmostEqual(self.city.lunch_rate, 50.0) + + def test_dinner_rate(self): + self.assertAlmostEqual(self.city.dinner_rate, 20.0) + + def test_update_expense_rate_with_zero_percentages(self): + self.city.percentage_for_breakfast = 0 + self.city.percentage_for_lunch = 0 + self.city.percentage_for_dinner = 0 + self.assertEqual(self.city.breakfast_rate, 0.0) + self.assertEqual(self.city.lunch_rate, 0.0) + self.assertEqual(self.city.dinner_rate, 0.0) + + def test_update_expense_rate_with_different_daily_rate(self): + self.city.daily_rate_24h = 200.0 + self.assertAlmostEqual(self.city.breakfast_rate, 60.0) + self.assertAlmostEqual(self.city.lunch_rate, 100.0) + self.assertAlmostEqual(self.city.dinner_rate, 40.0) diff --git a/hr_expense_meal_allowance/views/hr_expense.xml b/hr_expense_meal_allowance/views/hr_expense.xml new file mode 100644 index 00000000..fe9dd6f7 --- /dev/null +++ b/hr_expense_meal_allowance/views/hr_expense.xml @@ -0,0 +1,75 @@ + + + + view.hr.expense.form.extended + hr.expense + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +