diff --git a/README.md b/README.md index 8b10e6960..6864725ce 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# odex25-standard-moduless +# odex25-standard-modules This Repo contains general standard modules for all projects. diff --git a/odex25_accounting/abs_customer_validation/__init__.py b/odex25_accounting/abs_customer_validation/__init__.py new file mode 100644 index 000000000..c48f15af7 --- /dev/null +++ b/odex25_accounting/abs_customer_validation/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +################################################################################# +# +# Odoo, Open Source Management Solution +# Copyright (C) 2022-today Ascetic Business Solution +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################# +from . import models + diff --git a/odex25_accounting/abs_customer_validation/__manifest__.py b/odex25_accounting/abs_customer_validation/__manifest__.py new file mode 100644 index 000000000..fc1146f4c --- /dev/null +++ b/odex25_accounting/abs_customer_validation/__manifest__.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +################################################################################# +# +# Odoo, Open Source Management Solution +# Copyright (C) 2022-today Ascetic Business Solution +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################# +{ + 'name': "Customer duplicate validation", + 'author': 'Ascetic Business Solution', + 'category': 'Odex25-Accounting/Odex25-Accounting', + 'summary': """Notify about duplicate while creating partner""", + 'website': 'http://www.asceticbs.com', + 'license': 'AGPL-3', + 'description': """ +""", + 'version': '14.0', + 'depends': ['base', 'sale'], + 'data': ['security/security.xml'], + 'images': ['static/description/banner.png'], + 'installable': True, + 'application': True, + 'auto_install': False, +} diff --git a/odex25_accounting/abs_customer_validation/models/__init__.py b/odex25_accounting/abs_customer_validation/models/__init__.py new file mode 100644 index 000000000..baed70174 --- /dev/null +++ b/odex25_accounting/abs_customer_validation/models/__init__.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +################################################################################# +# +# Odoo, Open Source Management Solution +# Copyright (C) 2022-today Ascetic Business Solution +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################# +from . import res_partner diff --git a/odex25_accounting/abs_customer_validation/models/res_partner.py b/odex25_accounting/abs_customer_validation/models/res_partner.py new file mode 100644 index 000000000..e3e0ce332 --- /dev/null +++ b/odex25_accounting/abs_customer_validation/models/res_partner.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +################################################################################# +# +# Odoo, Open Source Management Solution +# Copyright (C) 2022-today Ascetic Business Solution +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +################################################################################# +from odoo import api,fields,models,_ +from odoo.exceptions import ValidationError + +class ResPartner(models.Model): + _inherit="res.partner" + + def get_partner_list(self,partner_objs): + partner_list = '' + for partner in partner_objs: + partner_list = partner_list + ' || ' + partner.name + return partner_list + + @api.onchange('name') + def onchange_name(self): + if self.name and self.user_has_groups("abs_customer_validation.group_activate_customer_validation"): + if self.env['res.partner'].search([('name','=',self.name)]): + raise ValidationError(_('The record ' +self.name+' is already exist ')) + + @api.onchange('phone') + def onchange_phonenumber(self): + if self.phone and self.user_has_groups("abs_customer_validation.group_activate_customer_validation"): + partner_objs = self.env['res.partner'].search([('phone','=',self.phone)]) + if self.get_partner_list(partner_objs): + raise ValidationError(_('Phone number '+str(self.phone)+' is already exist in the following records:' + '\n' + self.get_partner_list(partner_objs))) + + @api.onchange('mobile') + def onchange_mobilenumber(self): + if self.mobile and self.user_has_groups("abs_customer_validation.group_activate_customer_validation"): + partner_objs = self.env['res.partner'].search([('mobile','=',self.mobile)]) + if self.get_partner_list(partner_objs): + raise ValidationError(_('Mobile number '+str(self.mobile)+' is already exist in the following records:' + '\n' + self.get_partner_list(partner_objs))) + + @api.onchange('fax') + def onchange_fax(self): + if self.fax and self.user_has_groups("abs_customer_validation.group_activate_customer_validation"): + partner_objs = self.env['res.partner'].search([('fax','=',self.fax)]) + if self.get_partner_list(partner_objs): + raise ValidationError(_('Fax number '+str(self.fax)+' is already exist in the following records:' + '\n' + self.get_partner_list(partner_objs))) + + @api.onchange('email') + def onchange_email(self): + if self.email and self.user_has_groups("abs_customer_validation.group_activate_customer_validation"): + partner_objs = self.env['res.partner'].search([('email','=',self.email)]) + if self.get_partner_list(partner_objs): + raise ValidationError(_('Email number '+str(self.email)+' is already exist in the following records:' + '\n' + self.get_partner_list(partner_objs))) + + @api.onchange('website') + def onchange_website(self): + if self.website and self.user_has_groups("abs_customer_validation.group_activate_customer_validation"): + website_id = "http://"+str(self.website) + partner_objs = self.env['res.partner'].search([('website','=',website_id)]) + if self.get_partner_list(partner_objs): + raise ValidationError(_('Website number '+str(self.website)+' is already exist in the following records:' + '\n' + self.get_partner_list(partner_objs))) + + diff --git a/odex25_accounting/abs_customer_validation/security/security.xml b/odex25_accounting/abs_customer_validation/security/security.xml new file mode 100644 index 000000000..aa7b1fa44 --- /dev/null +++ b/odex25_accounting/abs_customer_validation/security/security.xml @@ -0,0 +1,10 @@ + + + + + Activate customer validation + + + + + diff --git a/odex25_accounting/abs_customer_validation/static/description/banner.png b/odex25_accounting/abs_customer_validation/static/description/banner.png new file mode 100644 index 000000000..c9360f5bd Binary files /dev/null and b/odex25_accounting/abs_customer_validation/static/description/banner.png differ diff --git a/odex25_accounting/abs_customer_validation/static/description/company-logo.png b/odex25_accounting/abs_customer_validation/static/description/company-logo.png new file mode 100644 index 000000000..fee9f34ae Binary files /dev/null and b/odex25_accounting/abs_customer_validation/static/description/company-logo.png differ diff --git a/odex25_accounting/abs_customer_validation/static/description/icon.png b/odex25_accounting/abs_customer_validation/static/description/icon.png new file mode 100644 index 000000000..97c2198db Binary files /dev/null and b/odex25_accounting/abs_customer_validation/static/description/icon.png differ diff --git a/odex25_accounting/abs_customer_validation/static/description/index.html b/odex25_accounting/abs_customer_validation/static/description/index.html new file mode 100644 index 000000000..3b5d081c4 --- /dev/null +++ b/odex25_accounting/abs_customer_validation/static/description/index.html @@ -0,0 +1,60 @@ + + + +
+
+
+

Notify about duplicate while creating partner

+
+
+

+ This module will help you to activate the validation on the partner. Check 'Activate customer validation' access group from the user. This validation helps to take preventive steps to stop creating the duplicate partners. Odoo will notify the user instantly with the list of records which are potentially duplicate while they are adding information (like Name, Phone, Mobile, Fax, Email, Website) on the customer. Please note, this moduel is not to stop creating duplicate partner but notify the user so they should be aware about possible duplication while creating the partner. +

+ +
+
+
+ +
+ +

Need help?

+ +
+

+ Contact this module maintainer for any question, need support or request for the new feature :
+ * Riken Bhorania +91 9427425799, riken.bhorania, riken.bhorania@asceticbs.com
+ * Bhaumin Chorera +91 8530000384, bhaumin.chorera, bhaumin.chorera@asceticbs.com
+

+
+ + + +
+ +
+ +
+ + + + +
+ + +
+ + + diff --git a/odex25_accounting/account_bank_statement_import_excel/README.rst b/odex25_accounting/account_bank_statement_import_excel/README.rst new file mode 100644 index 000000000..843543097 --- /dev/null +++ b/odex25_accounting/account_bank_statement_import_excel/README.rst @@ -0,0 +1,66 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :alt: License: AGPL-3 + +========================= +Import OFX Bank Statement +========================= + +This module adds support for the import of bank statements in `OFX format `_. + +Bank Statements may be generated containing a subset of the OFX information (only those transaction lines that are required for the +creation of the Financial Accounting records). + +Installation +============ + +The module requires one additional python lib: + +* `ofxparse `_ + +Usage +===== + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/174/11.0 + +Known issues / Roadmap +====================== + +* None + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smashing it by providing a detailed and welcomed feedback. + +Credits +======= + +Contributors +------------ + +* Odoo SA +* Alexis de Lattre +* Laurent Mignon +* Ronald Portier +* Sylvain LE GAL +* Nicolas JEUDY + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +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. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/odex25_accounting/account_bank_statement_import_excel/__init__.py b/odex25_accounting/account_bank_statement_import_excel/__init__.py new file mode 100644 index 000000000..a22f9844c --- /dev/null +++ b/odex25_accounting/account_bank_statement_import_excel/__init__.py @@ -0,0 +1,3 @@ +from . import models +from . import wizard + diff --git a/odex25_accounting/account_bank_statement_import_excel/__manifest__.py b/odex25_accounting/account_bank_statement_import_excel/__manifest__.py new file mode 100644 index 000000000..305ef5193 --- /dev/null +++ b/odex25_accounting/account_bank_statement_import_excel/__manifest__.py @@ -0,0 +1,21 @@ +{ + 'name': 'Import Excel Bank Statement', + 'license': 'AGPL-3', + 'author': "Expert Co. Ltd.", + 'website': "http://www.exp-sa.com", + 'category': 'Odex25-Accounting/Odex25-Accounting', + 'version': '0.1', + 'depends': [ + 'odex25_account_bank_statement_import', + ], + 'data': [ + 'security/ir.model.access.csv', + 'views/view_account_bank_statement_import.xml', + 'views/excel_dimensions_views.xml', + 'data/excel.dimensions.csv' + ], + 'external_dependencies': { + 'python': ['xlrd'], + }, + 'installable': True, +} diff --git a/odex25_accounting/account_bank_statement_import_excel/data/excel.dimensions.csv b/odex25_accounting/account_bank_statement_import_excel/data/excel.dimensions.csv new file mode 100644 index 000000000..84d0e2c7f --- /dev/null +++ b/odex25_accounting/account_bank_statement_import_excel/data/excel.dimensions.csv @@ -0,0 +1,4 @@ +id,name,details_only,account_number_col,account_number_row,balance_col,company_id/id,credit_col,currency_col,currency_row,date_col,date_period_col,date_period_row,debit_col,details_row,balance_end_col,balance_end_row,note_col,balance_start_col,balance_start_row,type_col,date_format,debit_sign +excel_dimensions_rajhi,Al Rajhi Bank,,10,8,6,,8,10,9,11,10,10,7,16,10,13,10,10,12,9,%d/%m/%Y,0 +excel_dimensions_inma,Inma Bank,,4,5,0,,4,0,5,15,0,2,5,17,9,7,6,0,7,0,%m/%d/%Y,1 +excel_dimensions_albilad,Albilad Bank,1,,,4,,3,,,0,,,2,1,,,5,,,,%d/%m/%Y,0 diff --git a/odex25_accounting/account_bank_statement_import_excel/i18n/ar.po b/odex25_accounting/account_bank_statement_import_excel/i18n/ar.po new file mode 100644 index 000000000..88962f664 --- /dev/null +++ b/odex25_accounting/account_bank_statement_import_excel/i18n/ar.po @@ -0,0 +1,278 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_bank_statement_import_excel +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0+e-20210105\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-05-18 03:19+0000\n" +"PO-Revision-Date: 2021-05-18 03:19+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: account_bank_statement_import_excel +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_excel.excel_dimensions_view_form +msgid "%B - Full month name.\"" +msgstr "%B - اسم الشهر بالكامل.\"" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_excel.excel_dimensions_view_form +msgid "%Y - Year with century.\"" +msgstr "%Y - السنة كاملة بالقرن.\"" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_excel.excel_dimensions_view_form +msgid "%b - Abbreviated month name." +msgstr "%b - اسم الشهر المختصر" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_excel.excel_dimensions_view_form +msgid "%d - Day of the month [01,31].\"" +msgstr "%d - اليوم من الشهر [01,31].\"" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_excel.excel_dimensions_view_form +msgid "%m - Month number [01,12].\"" +msgstr "%m - رقم الشهر [01,12].\"" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_excel.excel_dimensions_view_form +msgid "%y - Year without century [00,99].\"" +msgstr "%y - السنة مختصرة بدون القرن [00,99].\"" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_excel.excel_dimensions_view_form +msgid "1. %b, %B ==> Dec, December" +msgstr "1. %b, %B ==> ديسمبر" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_excel.excel_dimensions_view_form +msgid "3. %y, %Y ==> 08, 2008" +msgstr "3. %y, %Y ==> 08, 2008" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_excel.excel_dimensions_view_form +msgid "4. %d, %m ==> 05, 12" +msgstr "4. %d, %m ==> 05, 12" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.actions.act_window,name:account_bank_statement_import_excel.excel_dimensions_action +#: model_terms:ir.ui.menu,name:account_bank_statement_import_excel.bank_statement_excel_dimensions_menu_categ +msgid "Bank Statement Excel Dimensions" +msgstr "ابعاد ملف الاكسل" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model,name:account_bank_statement_import_excel.model_account_bank_statement_line +msgid "Bank Statement Line" +msgstr "بند كشف حساب المصرف" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_create_uid +msgid "Created by" +msgstr "أنشئ بواسطة" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_create_date +msgid "Created on" +msgstr "أنشئ في" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_date_format +msgid "Date Format" +msgstr "تنسيق التاريخ" + +#. module: account_bank_statement_import_excel +#: code:addons/account_bank_statement_import_excel/wizard/account_bank_statement_import.py:127 +#, python-format +msgid "Determine excel dimension for this journal. " +msgstr "الرجاء تحديد ابعاد ملف الاكسل الخاص بدفتر اليومية. " + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_display_name +msgid "Display Name" +msgstr "الاسم المعروض" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_excel.excel_dimensions_view_form +msgid "Examples" +msgstr "أمثلة" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_account_journal_excel_dimension +msgid "Excel Dimension" +msgstr "أبعاد ملف الاكسل" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_excel.excel_dimensions_view_form +msgid "Excel Dimensions" +msgstr "أبعاد ملف الاكسل" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_excel.view_account_bank_statement_import_form +msgid "Excel files (xLS, XLSX)" +msgstr "ملف اكسل" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_id +msgid "ID" +msgstr "المعرف" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model,name:account_bank_statement_import_excel.model_account_bank_statement_import +msgid "Import Bank Statement" +msgstr "استيراد كشف الحساب" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model,name:account_bank_statement_import_excel.model_account_journal +msgid "Journal" +msgstr "دفتر اليومية" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions___last_update +msgid "Last Modified on" +msgstr "آخر تعديل على" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_write_uid +msgid "Last Updated by" +msgstr "آخر تعديل بواسطة" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_write_date +msgid "Last Updated on" +msgstr "آخر تعديل على" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_excel.excel_dimensions_view_form +msgid "Legends for supported Date Formats" +msgstr "تنسيقات التاريخ المدعومة" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_excel.excel_dimensions_view_form +msgid "Details" +msgstr "تفاصيل المطابقة" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_details_only +msgid "Details Only" +msgstr "التفاصيل فقط" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_name +msgid "Name" +msgstr "الاسم" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model,name:account_bank_statement_import_excel.model_excel_dimensions +msgid "The Dimensions of the excel file used in bank statement import" +msgstr "تستخدم أبعاد ملف الاكسل عند استيراد المطابقة البنكية" + +#. module: account_bank_statement_import_excel +#: code:addons/account_bank_statement_import_excel/wizard/account_bank_statement_import.py:136 +#, python-format +msgid "The following problem occurred during import. The file might not be valid.\n" +"\n" +" %s" +msgstr "لا يمكن استيراد الملف نسبا لظهور المشكلة ادناه.\n" +"\n" +" %s" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_account_number_col +msgid "account number column" +msgstr "عمود رقم الحساب" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_account_number_row +msgid "account number row" +msgstr "صف رقم الحساب" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_balance_col +msgid "balance column" +msgstr "عمود الرصيد" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_company_id +msgid "company" +msgstr "الشركة" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_credit_col +msgid "credit column" +msgstr "عمود الدائن" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_currency_col +msgid "currency column" +msgstr "عمود العملة" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_currency_row +msgid "currency row" +msgstr "صف العملة" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_date_col +msgid "date column" +msgstr "عمود التاريخ" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_date_period_col +msgid "date period column" +msgstr "عمود تاريخ الفترة" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_date_period_row +msgid "date period row" +msgstr "صف تاريخ الفترة" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_debit_col +msgid "debit column" +msgstr "عمود المدين" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_details_row +msgid "details row" +msgstr "صف التفاصيل" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_balance_end_col +msgid "ending balance column" +msgstr "عمود الرصيد الختامي" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_balance_end_row +msgid "ending balance row" +msgstr "صف الرصيد الختامي" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_note_col +msgid "note column" +msgstr "عمود الملاحظات" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_balance_start_col +msgid "starting balance column" +msgstr "عمود الرصيد الإفتتاحي" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_balance_start_row +msgid "starting balance row" +msgstr "صف الرصيد الإفتتاحي" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_type_col +msgid "type column" +msgstr "عمود النوع" + +#. module: account_bank_statement_import_excel +#: model_terms:ir.model.fields,field_description:account_bank_statement_import_excel.field_excel_dimensions_debit_sign +msgid "Revert Debit Sign" +msgstr "عكس اشارة المدين" diff --git a/odex25_accounting/account_bank_statement_import_excel/models/__init__.py b/odex25_accounting/account_bank_statement_import_excel/models/__init__.py new file mode 100644 index 000000000..eceffdcd1 --- /dev/null +++ b/odex25_accounting/account_bank_statement_import_excel/models/__init__.py @@ -0,0 +1 @@ +from . import excel_dimensions \ No newline at end of file diff --git a/odex25_accounting/account_bank_statement_import_excel/models/excel_dimensions.py b/odex25_accounting/account_bank_statement_import_excel/models/excel_dimensions.py new file mode 100644 index 000000000..9df72b67f --- /dev/null +++ b/odex25_accounting/account_bank_statement_import_excel/models/excel_dimensions.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- + +from odoo import fields, models + + +class ExcelDimensions(models.Model): + _name = 'excel.dimensions' + _description = 'The Dimensions of the excel file used in bank statement import' + + name = fields.Char(string='Name') + + company_id = fields.Many2one(comodel_name='res.company', string='Company') + + details_only = fields.Boolean() + + account_number_row = fields.Integer(string='Account Number Row') + account_number_col = fields.Integer(string='Account Number Column') + + currency_row = fields.Integer(string='Currency Row') + currency_col = fields.Integer(string='Currency Column') + + balance_start_row = fields.Integer(string='Starting Balance Row') + balance_start_col = fields.Integer(string='Starting BalanceColumn') + + balance_end_row = fields.Integer(string='Ending Balance Row') + balance_end_col = fields.Integer(string='Ending Balance Column') + + date_period_row = fields.Integer(string='Date Period Row') + date_period_col = fields.Integer(string='Date Period Column') + + details_row = fields.Integer(string='Details Row') + + debit_col = fields.Integer(string='Debit Column') + + credit_col = fields.Integer(string='Credit Column') + + balance_col = fields.Integer(string='Balance Column') + + type_col = fields.Integer(string='Type Column') + + note_col = fields.Integer(string='Note Column') + + date_col = fields.Integer(string='Date Column') + date_format = fields.Char() + + debit_sign = fields.Boolean('Revert Debit Sign') + + +class AccountJournal(models.Model): + _inherit = 'account.journal' + + excel_dimension = fields.Many2one('excel.dimensions') + + def _get_bank_statements_available_import_formats(self): + rslt = super(AccountJournal, self)._get_bank_statements_available_import_formats() + rslt.append('XLS') + return rslt \ No newline at end of file diff --git a/odex25_accounting/account_bank_statement_import_excel/security/ir.model.access.csv b/odex25_accounting/account_bank_statement_import_excel/security/ir.model.access.csv new file mode 100644 index 000000000..7dfcad28d --- /dev/null +++ b/odex25_accounting/account_bank_statement_import_excel/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_excel_dimension,excel.dimensions,model_excel_dimensions,account.group_account_readonly,1,0,0,0 +access_excel_dimension_manager,excel.dimensions,model_excel_dimensions,account.group_account_manager,1,1,1,1 \ No newline at end of file diff --git a/odex25_accounting/account_bank_statement_import_excel/static/description/icon.png b/odex25_accounting/account_bank_statement_import_excel/static/description/icon.png new file mode 100644 index 000000000..4141f52da Binary files /dev/null and b/odex25_accounting/account_bank_statement_import_excel/static/description/icon.png differ diff --git a/odex25_accounting/account_bank_statement_import_excel/static/fonts/ae_AlMohanad.ttf b/odex25_accounting/account_bank_statement_import_excel/static/fonts/ae_AlMohanad.ttf new file mode 100644 index 000000000..bdd7360e1 Binary files /dev/null and b/odex25_accounting/account_bank_statement_import_excel/static/fonts/ae_AlMohanad.ttf differ diff --git a/odex25_accounting/account_bank_statement_import_excel/static/src/css/website_rtl.css b/odex25_accounting/account_bank_statement_import_excel/static/src/css/website_rtl.css new file mode 100644 index 000000000..85347c670 --- /dev/null +++ b/odex25_accounting/account_bank_statement_import_excel/static/src/css/website_rtl.css @@ -0,0 +1,22 @@ +@media (min-width: 768px){ + .rtl .navbar-right{ + float: left !important; + } + .rtl .navbar-right .dropdown .dropdown-menu{ + right: auto !important; + left: 0 !important; + } + .rtl .navbar-left{ + float: right !important; + } + .rtl .navbar-left .dropdown .dropdown-menu{ + left: auto !important; + right: 0 !important; + } + .navbar-nav.navbar-right:last-child{ + margin-left: auto; + } + .rtl .pull-left{ + float: right !important; + } +} diff --git a/odex25_accounting/account_bank_statement_import_excel/tests/__init__.py b/odex25_accounting/account_bank_statement_import_excel/tests/__init__.py new file mode 100644 index 000000000..bb3456ae9 --- /dev/null +++ b/odex25_accounting/account_bank_statement_import_excel/tests/__init__.py @@ -0,0 +1 @@ +from . import test_import_bank_statement diff --git a/odex25_accounting/account_bank_statement_import_excel/tests/test_import_bank_statement.py b/odex25_accounting/account_bank_statement_import_excel/tests/test_import_bank_statement.py new file mode 100644 index 000000000..895ef09d2 --- /dev/null +++ b/odex25_accounting/account_bank_statement_import_excel/tests/test_import_bank_statement.py @@ -0,0 +1,86 @@ +from odoo.tests.common import TransactionCase +from odoo.modules.module import get_module_resource +import base64 + + +class TestOfxFile(TransactionCase): + """Tests for import bank statement ofx file format + (account.bank.statement.import) + """ + + def setUp(self): + super(TestOfxFile, self).setUp() + self.absi_model = self.env['account.bank.statement.import'] + self.abs_model = self.env['account.bank.statement'] + self.j_model = self.env['account.journal'] + self.absl_model = self.env['account.bank.statement.line'] + cur = self.env.ref('base.USD') + self.env.ref('base.main_company').currency_id = cur.id + bank = self.env['res.partner.bank'].create({ + 'acc_number': '123456', + 'partner_id': self.env.ref('base.main_partner').id, + 'company_id': self.env.ref('base.main_company').id, + 'bank_id': self.env.ref('base.res_bank_1').id, + }) + self.env['account.journal'].create({ + 'name': 'Bank Journal TEST OFX', + 'code': 'BNK12', + 'type': 'bank', + 'bank_account_id': bank.id, + }) + + bank_iban_ofx = self.env['res.partner.bank'].create({ + 'acc_number': 'FR7630001007941234567890185', + 'partner_id': self.env.ref('base.main_partner').id, + 'company_id': self.env.ref('base.main_company').id, + 'bank_id': self.env.ref('base.res_bank_1').id, + }) + + self.env['account.journal'].create({ + 'name': 'FR7630001007941234567890185', + 'code': 'BNK13', + 'type': 'bank', + 'bank_account_id': bank_iban_ofx.id, + }) + + def test_wrong_ofx_file_import(self): + ofx_file_path = get_module_resource( + 'account_bank_statement_import_excel', + 'tests/test_ofx_file/', 'test_ofx_wrong.ofx') + ofx_file_wrong = base64.b64encode(open(ofx_file_path, 'rb').read()) + bank_statement = self.absi_model.create( + dict(data_file=ofx_file_wrong)) + self.assertFalse(bank_statement._check_ofx(data_file=ofx_file_wrong)) + + def test_ofx_file_import(self): + ofx_file_path = get_module_resource( + 'account_bank_statement_import_excel', + 'tests/test_ofx_file/', 'test_ofx.ofx') + ofx_file = base64.b64encode(open(ofx_file_path, 'rb').read()) + bank_statement = self.absi_model.create( + dict(data_file=ofx_file)) + bank_statement.import_file() + bank_st_record = self.abs_model.search( + [('name', 'like', '123456')])[0] + self.assertEqual(bank_st_record.balance_start, 2516.56) + self.assertEqual(bank_st_record.balance_end_real, 2156.56) + + line = self.absl_model.search([ + ('name', '=', 'Agrolait'), + ('statement_id', '=', bank_st_record.id)])[0] + self.assertEquals(line.ref, '219378') + self.assertEquals(line.date, '2013-08-24') + + def test_check_journal_bank_account(self): + ofx_file_path = get_module_resource( + 'account_bank_statement_import_excel', + 'tests/test_ofx_file/', 'test_ofx_iban.ofx') + ofx_file = base64.b64encode(open(ofx_file_path, 'rb').read()) + bank_st = self.absi_model.create( + dict(data_file=ofx_file)) + journal_iban_ofx = self.j_model.search([ + ('name', '=', 'FR7630001007941234567890185')]) + res = bank_st._check_journal_bank_account(journal_iban_ofx, + '12345678901') + self.assertTrue(res) + bank_st.with_context(journal_id=journal_iban_ofx.id).import_file() diff --git a/odex25_accounting/account_bank_statement_import_excel/tests/test_ofx_file/test_ofx.ofx b/odex25_accounting/account_bank_statement_import_excel/tests/test_ofx_file/test_ofx.ofx new file mode 100644 index 000000000..37df4d0c9 --- /dev/null +++ b/odex25_accounting/account_bank_statement_import_excel/tests/test_ofx_file/test_ofx.ofx @@ -0,0 +1,100 @@ + + + + + + + 0 + INFO + + 20130831165153.000[-8:PST] + ENG + + + + + 0 + + 0 + INFO + + + USD + + 000000123 + 123456 + CHECKING + + + 20130801 + 20130831165153.000[-8:PST] + + POS + 20130824080000 + -80 + 219378 + Agrolait + + + + 20130801 + 20130831165153.000[-8:PST] + + POS + 20130824080000 + -90 + 219379 + China Export + + + + 20130801 + 20130831165153.000[-8:PST] + + POS + 20130824080000 + -100 + 219380 + Axelor Scuba + + + + 20130801 + 20130831165153.000[-8:PST] + + POS + 20130824080000 + -90 + 219381 + China Scuba + + + + 2156.56 + 20130831165153 + + + + + + + 0 + + 0 + INFO + + + USD + + 123412341234 + + + + + -562.00 + 20130831165153 + + + + + diff --git a/odex25_accounting/account_bank_statement_import_excel/tests/test_ofx_file/test_ofx_iban.ofx b/odex25_accounting/account_bank_statement_import_excel/tests/test_ofx_file/test_ofx_iban.ofx new file mode 100644 index 000000000..99c01618f --- /dev/null +++ b/odex25_accounting/account_bank_statement_import_excel/tests/test_ofx_file/test_ofx_iban.ofx @@ -0,0 +1,101 @@ + + + + + + + 0 + INFO + + 20130831165153.000[-8:PST] + ENG + + + + + 0 + + 0 + INFO + + + USD + + 30001 + 00794 + 12345678901 + CHECKING + + + 20130801 + 20130831165153.000[-8:PST] + + POS + 20130824080000 + -80 + 219378 + Agrolait + + + + 20130801 + 20130831165153.000[-8:PST] + + POS + 20130824080000 + -90 + 219379 + China Export + + + + 20130801 + 20130831165153.000[-8:PST] + + POS + 20130824080000 + -100 + 219380 + Axelor Scuba + + + + 20130801 + 20130831165153.000[-8:PST] + + POS + 20130824080000 + -90 + 219381 + China Scuba + + + + 2156.56 + 20130831165153 + + + + + + + 0 + + 0 + INFO + + + USD + + 123412341234 + + + + + -562.00 + 20130831165153 + + + + + diff --git a/odex25_accounting/account_bank_statement_import_excel/tests/test_ofx_file/test_ofx_wrong.ofx b/odex25_accounting/account_bank_statement_import_excel/tests/test_ofx_file/test_ofx_wrong.ofx new file mode 100644 index 000000000..b9e64a391 --- /dev/null +++ b/odex25_accounting/account_bank_statement_import_excel/tests/test_ofx_file/test_ofx_wrong.ofx @@ -0,0 +1,100 @@ + + + + + + + 0 + INFO + + 20130831165153.000[-8:PST] + ENG + + + + + 0 + + 0 + INFO + + + + + 20130801 + 20130831165153.000[-8:PST] + + POS + 20130824080000 + -80 + 219378 + Agrolait + + + + 20130801 + 20130831165153.000[-8:PST] + + POS + + China Export + + + + 20130801 + 20130831165153.000[-8:PST] + + POS + 20130824080000 + -100 + 219380 + Axelor Scuba + + + + 20130801 + 20130831165153.000[-8:PST] + + POS + 20130824080000 + -90 + 219381 + China Scuba + + + + 2156.56 + 20130831165153 + + + + + + + 0 + + 0 + INFO + + + USD + + 123412341234 + + + + + -562.00 + 20130831165153 + + + + + diff --git a/odex25_accounting/account_bank_statement_import_excel/views/excel_dimensions_views.xml b/odex25_accounting/account_bank_statement_import_excel/views/excel_dimensions_views.xml new file mode 100644 index 000000000..911c31b27 --- /dev/null +++ b/odex25_accounting/account_bank_statement_import_excel/views/excel_dimensions_views.xml @@ -0,0 +1,133 @@ + + + + + + excel.dimensions.view.form + excel.dimensions + +
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
%b - Abbreviated month name.
+
%B - Full month name."
+
%d - Day of the month [01,31]."
+
%y - Year without century [00,99]."
+
%Y - Year with century."
+
%m - Month number [01,12]."
+
+ +
1. %b, %B ==> Dec, December
+
3. %y, %Y ==> 08, 2008
+
4. %d, %m ==> 05, 12
+
+
+
+
+
+ + + + Bank Statement Excel Dimensions + ir.actions.act_window + excel.dimensions + tree,form + +

+ +

+ +

+
+
+ + + + + + account.journal.form + account.journal + + + + + + + +
+
\ No newline at end of file diff --git a/odex25_accounting/account_bank_statement_import_excel/views/view_account_bank_statement_import.xml b/odex25_accounting/account_bank_statement_import_excel/views/view_account_bank_statement_import.xml new file mode 100644 index 000000000..9e52aa2d7 --- /dev/null +++ b/odex25_accounting/account_bank_statement_import_excel/views/view_account_bank_statement_import.xml @@ -0,0 +1,12 @@ + + + + account.bank.statement.import + + + +
  • Excel files (XLS, XLSX)
  • +
    +
    +
    +
    diff --git a/odex25_accounting/account_bank_statement_import_excel/wizard/__init__.py b/odex25_accounting/account_bank_statement_import_excel/wizard/__init__.py new file mode 100644 index 000000000..7dafcd167 --- /dev/null +++ b/odex25_accounting/account_bank_statement_import_excel/wizard/__init__.py @@ -0,0 +1 @@ +from . import account_bank_statement_import diff --git a/odex25_accounting/account_bank_statement_import_excel/wizard/account_bank_statement_import.py b/odex25_accounting/account_bank_statement_import_excel/wizard/account_bank_statement_import.py new file mode 100644 index 000000000..1a8edfde1 --- /dev/null +++ b/odex25_accounting/account_bank_statement_import_excel/wizard/account_bank_statement_import.py @@ -0,0 +1,278 @@ +import logging +import re +from odoo import api, models, _ +from odoo.exceptions import UserError +from odoo.addons.base_iban.models.res_partner_bank import _map_iban_template +from odoo.addons.base_iban.models.res_partner_bank import validate_iban +from odoo.tools import float_compare, float_round, float_repr + +from datetime import date, datetime, timedelta + +_logger = logging.getLogger(__name__) + +try: + import xlrd +except ImportError: + _logger.debug("xlrd not found.") + + +class AccountBankStatementImport(models.TransientModel): + _inherit = 'account.bank.statement.import' + + def _check_journal_bank_account(self, journal, account_number): + return journal.bank_account_id.sanitized_acc_number == account_number + + res = super( + AccountBankStatementImport, self + )._check_journal_bank_account(journal, account_number) + if not res: + e_acc_num = journal.bank_account_id.sanitized_acc_number + e_acc_num = e_acc_num.replace(" ", "") + validate_iban(e_acc_num) + country_code = e_acc_num[:2].lower() + iban_template = _map_iban_template[country_code].replace( + " ", "") + e_acc_num = "".join( + [c for c, t in zip(e_acc_num, iban_template) if t == "C"]) + res = (e_acc_num == account_number) + return res + + @api.model + def _check_excel(self, data_file): + try: + excel = xlrd.open_workbook(file_contents=data_file) + except Exception as e: + _logger.debug(e) + return False + return excel + + @api.model + def _prepare_ofx_transaction_line(self, transaction): + # Since ofxparse doesn't provide account numbers, + # we cannot provide the key 'bank_account_id', + # nor the key 'account_number' + # If you read odoo10/addons/account_bank_statement_import/ + # account_bank_statement_import.py, it's the only 2 keys + # we can provide to match a partner. + vals = { + 'date': transaction.date, + 'name': transaction.payee + ( + transaction.memo and ': ' + transaction.memo or ''), + 'ref': transaction.id, + 'amount': float(transaction.amount), + 'unique_import_id': transaction.id, + } + return vals + + def _get_excel_data(self, excel_file, excel_conf): + xl_sheet = excel_file.sheet_by_index(0) + journal = self.env['account.journal'].browse(self.env.context.get('journal_id', [])) + currency = journal.currency_id.name + + account_number = not excel_conf.details_only and \ + xl_sheet.cell(excel_conf.account_number_row, excel_conf.account_number_col).value or \ + journal.bank_account_id.acc_number + # got to fix currency problem but for now gonna use company currency + + start = not excel_conf.details_only and \ + xl_sheet.cell(excel_conf.balance_start_row, excel_conf.balance_start_col).value or 0 + + balance_start = isinstance(start, str) and float(re.sub('[^.\-\d]', '', start.split()[0])) or start + + end = not excel_conf.details_only and \ + xl_sheet.cell(excel_conf.balance_end_row, excel_conf.balance_end_col).value or 0 + + balance_end = isinstance(start, str) and float(re.sub('[^.\-\d]', '', end.split()[0])) or end + + lines = [] + + details_row = excel_conf.details_row + total_amt = 0.0 + + while True: + try: + debit = float(xl_sheet.cell(details_row, excel_conf.debit_col).value or 0) + credit = float(xl_sheet.cell(details_row, excel_conf.credit_col).value or 0) + # balance = float(xl_sheet.cell(details_row, excel_conf.balance_col).value or 0) + + type = xl_sheet.cell(details_row, excel_conf.type_col).value + note = xl_sheet.cell(details_row, excel_conf.note_col).value + date = xl_sheet.cell(details_row, excel_conf.date_col).value + date = datetime.strptime(date, excel_conf.date_format or "%d/%m/%Y") + amount = credit and credit or (excel_conf.debit_sign and -1 * debit or debit) + total_amt += amount + lines.append({'amount': amount, + # 'balance': balance, + 'payment_ref': type + ' ' + note, + 'date': date}) + details_row += 1 + except: + break + vals_bank_statement = { + 'name': account_number, + 'transactions': lines, + 'balance_start': balance_start, + 'balance_end_real': balance_end, + } + return (currency, account_number, [vals_bank_statement]) + + def _parse_file(self, data_file): + excel = self._check_excel(data_file) + if not excel: + return super(AccountBankStatementImport, self)._parse_file( + data_file) + + transactions = [] + total_amt = 0.00 + try: + journal = self.env['account.journal'].browse(self.env.context.get('journal_id', [])) + if not journal.excel_dimension: + raise UserError(_("Determine excel dimension for this journal. ")) + excel_data = self._get_excel_data(excel, journal.excel_dimension) + return excel_data + # for transaction in ofx.account.statement.transactions: + # vals = self._prepare_ofx_transaction_line(transaction) + # if vals: + # transactions.append(vals) + # total_amt += vals['amount'] + except Exception as e: + raise UserError(_( + "The following problem occurred during import. " + "The file might not be valid.\n\n %s") % e) + + # balance = float(ofx.account.statement.balance) + # vals_bank_statement = { + # 'name': ofx.account.number, + # 'transactions': transactions, + # 'balance_start': balance - total_amt, + # 'balance_end_real': balance, + # } + return ofx.account.statement.currency, ofx.account.number, [vals_bank_statement] + + +class AccountBankStatementLine(models.Model): + _inherit = "account.bank.statement.line" + + def get_reconciliation_proposition(self, excluded_ids=None): + """ Returns move lines that constitute the best guess to reconcile a statement line + Note: it only looks for move lines in the same currency as the statement line. + """ + self.ensure_one() + if not excluded_ids: + excluded_ids = [] + amount = self.amount_currency or self.amount + company_currency = self.journal_id.company_id.currency_id + st_line_currency = self.currency_id or self.journal_id.currency_id + currency = (st_line_currency and st_line_currency != + company_currency) and st_line_currency.id or False + precision = st_line_currency and st_line_currency.decimal_places or company_currency.decimal_places + params = {'company_id': self.env.user.company_id.id, + 'account_payable_receivable': (self.journal_id.default_credit_account_id.id, self.journal_id.default_debit_account_id.id), + 'amount': float_repr(float_round(amount, precision_digits=precision), precision_digits=precision), + 'partner_id': self.partner_id.id, + 'excluded_ids': tuple(excluded_ids), + 'ref': self.name, + } + # Look for structured communication match + if self.name: + add_to_select = ", CASE WHEN aml.ref = %(ref)s THEN 1 ELSE 2 END as temp_field_order " + add_to_from = " JOIN account_move m ON m.id = aml.move_id " + select_clause, from_clause, where_clause = self._get_common_sql_query( + overlook_partner=True, excluded_ids=excluded_ids, split=True) + sql_query = select_clause + add_to_select + from_clause + add_to_from + where_clause + sql_query += " AND (aml.ref= %(ref)s or m.name = %(ref)s) \ + ORDER BY temp_field_order, date_maturity desc, aml.id desc" + self.env.cr.execute(sql_query, params) + results = self.env.cr.fetchone() + if results: + return self.env['account.move.line'].browse(results[0]) + + # Look for a single move line with the same amount + field = currency and 'amount_residual_currency' or 'amount_residual' + liquidity_field = currency and 'amount_currency' or amount > 0 and 'aml.debit' or 'aml.credit' + liquidity_amt_clause = currency and '%(amount)s::numeric' or 'abs(%(amount)s::numeric)' + sql_query = self._get_common_sql_query(excluded_ids=excluded_ids) + \ + " AND (" + field + " = %(amount)s::numeric OR (acc.internal_type = 'liquidity' AND " + liquidity_field + " = " + liquidity_amt_clause + ")) \ + ORDER BY date_maturity desc, aml.id desc LIMIT 1" + self.env.cr.execute(sql_query, params) + results = self.env.cr.fetchone() + if results: + return self.env['account.move.line'].browse(results[0]) + + return self.env['account.move.line'] + + def auto_reconcile(self): + """ Try to automatically reconcile the statement.line ; return the counterpart journal entry/ies if the automatic reconciliation succeeded, False otherwise. + TODO : this method could be greatly improved and made extensible + """ + self.ensure_one() + match_recs = self.env['account.move.line'] + + amount = self.amount_currency or self.amount + company_currency = self.journal_id.company_id.currency_id + st_line_currency = self.currency_id or self.journal_id.currency_id + currency = (st_line_currency and st_line_currency != + company_currency) and st_line_currency.id or False + precision = st_line_currency and st_line_currency.decimal_places or company_currency.decimal_places + params = {'company_id': self.env.user.company_id.id, + 'account_payable_receivable': (self.journal_id.default_credit_account_id.id, self.journal_id.default_debit_account_id.id), + 'amount': float_round(amount, precision_digits=precision), + 'partner_id': self.partner_id.id, + 'ref': self.name, + } + field = currency and 'amount_residual_currency' or 'amount_residual' + liquidity_field = currency and 'amount_currency' or amount > 0 and 'aml.debit' or 'aml.credit' + # Look for structured communication match + if self.name: + sql_query = self._get_common_sql_query() + " AND aml.ref = %(ref)s AND (" + field + \ + " = %(amount)s OR (acc.internal_type = 'liquidity' AND " + liquidity_field + " = %(amount)s)) \ + ORDER BY date_maturity asc, aml.id asc" + self.env.cr.execute(sql_query, params) + match_recs = self.env.cr.dictfetchall() + if len(match_recs) > 1: + return False + + # Look for a single move line with the same partner, the same amount + if not match_recs: + if self.partner_id: + sql_query = self._get_common_sql_query( + ) + " AND (" + field + " = %(amount)s OR (acc.internal_type = 'liquidity' AND " + liquidity_field + " = %(amount)s)) \ + ORDER BY date_maturity asc, aml.id asc" + self.env.cr.execute(sql_query, params) + match_recs = self.env.cr.dictfetchall() + if len(match_recs) > 1: + return False + + if not match_recs: + return False + + match_recs = self.env['account.move.line'].browse([aml.get('id') for aml in match_recs]) + # Now reconcile + counterpart_aml_dicts = [] + payment_aml_rec = self.env['account.move.line'] + for aml in match_recs: + if aml.account_id.internal_type == 'liquidity': + payment_aml_rec = (payment_aml_rec | aml) + else: + amount = aml.currency_id and aml.amount_residual_currency or aml.amount_residual + counterpart_aml_dicts.append({ + 'name': aml.name if aml.name != '/' else aml.move_id.name, + 'debit': amount < 0 and -amount or 0, + 'credit': amount > 0 and amount or 0, + 'move_line': aml + }) + + try: + with self._cr.savepoint(): + counterpart = self.process_reconciliation( + counterpart_aml_dicts=counterpart_aml_dicts, + payment_aml_rec=payment_aml_rec) + return counterpart + except UserError: + # A configuration / business logic error that makes it impossible to auto-reconcile should not be raised + # since automatic reconciliation is just an amenity and the user will get the same exception when manually + # reconciling. Other types of exception are (hopefully) programmation errors and should cause a stacktrace. + self.invalidate_cache() + self.env['account.move'].invalidate_cache() + self.env['account.move.line'].invalidate_cache() + return False diff --git a/odex25_accounting/account_budget_custom/__init__.py b/odex25_accounting/account_budget_custom/__init__.py new file mode 100644 index 000000000..ade901eae --- /dev/null +++ b/odex25_accounting/account_budget_custom/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + +from . import models +from . import reports + diff --git a/odex25_accounting/account_budget_custom/__manifest__.py b/odex25_accounting/account_budget_custom/__manifest__.py new file mode 100644 index 000000000..d516d42f5 --- /dev/null +++ b/odex25_accounting/account_budget_custom/__manifest__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +{ + 'name': "Custom Budget", + 'description': """ + Add new features to budget : + - Budget Increase/Decrease & Transfer operation. + - Budget Confirmation. + """, + 'author': "Expert Co. Ltd.", + 'website': "http://www.exp-sa.com", + 'category': 'Odex25-Accounting/Odex25-Accounting', + # any module necessary for this one to work correctly + 'depends': ['base','odex25_account_budget', 'odex25_account_reports', 'report_xlsx'], + # always loaded + 'data': [ + 'data/budget_operation_data.xml', + 'security/budget_groups.xml', + 'security/ir.model.access.csv', + 'views/account_budget_views.xml', + 'views/budget_operations_view.xml', + 'views/budget_confirmation_view.xml', + 'views/menus.xml', + 'reports/reports.xml' + ], +} diff --git a/odex25_accounting/account_budget_custom/data/budget_operation_data.xml b/odex25_accounting/account_budget_custom/data/budget_operation_data.xml new file mode 100644 index 000000000..eb9af85c9 --- /dev/null +++ b/odex25_accounting/account_budget_custom/data/budget_operation_data.xml @@ -0,0 +1,15 @@ + + + + + Budget Operation Sequence + budget_operation.seq + BO/%(range_year)s/ + + + + + 6 + + + \ No newline at end of file diff --git a/odex25_accounting/account_budget_custom/i18n/ar.po b/odex25_accounting/account_budget_custom/i18n/ar.po new file mode 100644 index 000000000..7b7d5bb3c --- /dev/null +++ b/odex25_accounting/account_budget_custom/i18n/ar.po @@ -0,0 +1,797 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_budget_custom +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0+e-20210105\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-05-30 05:25+0000\n" +"PO-Revision-Date: 2021-05-30 05:25+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: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__account_id +msgid "Account" +msgstr "البند" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__percentage +msgid "Achievement" +msgstr "الإنجاز" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_needaction +msgid "Action Needed" +msgstr "إجراء مطلوب" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/budget_confirmation.py:0 +#, python-format +msgid "All lines should have accounts" +msgstr "" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__total_amount +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__amount +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__amount +msgid "Amount" +msgstr "مبلغ" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_form +msgid "Approve" +msgstr "موافقة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_attachment_count +msgid "Attachment Count" +msgstr "عدد المرفقات" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__beneficiary_id +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_search +msgid "Beneficiary" +msgstr "المستفيد" + +#. module: account_budget_custom +#: model:ir.model,name:account_budget_custom.model_crossovered_budget +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__from_crossovered_budget_id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__to_crossovered_budget_id +msgid "Budget" +msgstr "الموازنة" + +#. module: account_budget_custom +#: model:ir.model,name:account_budget_custom.model_budget_confirmation +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__confirmation_id +msgid "Budget Confirmation" +msgstr "تصديق الموازنة" + +#. module: account_budget_custom +#: model:ir.model,name:account_budget_custom.model_budget_confirmation_line +msgid "Budget Confirmation details" +msgstr "تفاصيل تصديق الموازنة" + +#. module: account_budget_custom +#: model:ir.actions.act_window,name:account_budget_custom.action_budget_confirmation_form +#: model:ir.ui.menu,name:account_budget_custom.menu_budget_confirmation +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_form +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_tree +msgid "Budget Confirmations" +msgstr "التحقق من الارتباط" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.crossovered_budget_view_form +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_crossovered_budget_line_tree +msgid "Budget Confirmed Amount" +msgstr "مبلغ الموازنة المصدق" + +#. module: account_budget_custom +#: model:ir.model,name:account_budget_custom.model_crossovered_budget_lines +msgid "Budget Line" +msgstr "خط الموازنة" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_crossovered_budget_line_graph +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_crossovered_budget_line_pivot +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_crossovered_budget_line_tree +#, python-format +msgid "Budget Lines" +msgstr "خطوط الموازنة" + +#. module: account_budget_custom +#: model:ir.actions.act_window,name:account_budget_custom.open_budget_operations +#: model:ir.ui.menu,name:account_budget_custom.menu_budget_operations_form +msgid "Budget Operation" +msgstr "عمليات الموازنة" + +#. module: account_budget_custom +#: model:ir.ui.menu,name:account_budget_custom.menu_budget_operations +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_search +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_tree +msgid "Budget Operations" +msgstr "عمليات الموازنة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__from_budget_post_id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__to_budget_post_id +msgid "Budget Post" +msgstr "البند" + +#. module: account_budget_custom +#: model:ir.actions.report,name:account_budget_custom.action_report_budget_xlsx +msgid "Budget XLSX" +msgstr "الموازنة (اكسل)" + +#. module: account_budget_custom +#: model:ir.ui.menu,name:account_budget_custom.main_budgets_menu +msgid "Budgets" +msgstr "الموازنات" + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_confirmation__state__cancel +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_form +msgid "Cancel" +msgstr "إلغاء" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_form +msgid "Check Budget" +msgstr "التحقق من الارتباط" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__company_id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__company_id +msgid "Company" +msgstr "مؤسسة" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_crossovered_budget_lines__percentage +msgid "" +"Comparison between practical and theoretical amount. This measure tells you " +"if you are below or over budget." +msgstr "" +"المقارنة بين القيمة الفعلية والنظرية. تحدد نسبة الانحراف في الإيرادات أو " +"المصروفات في الموازنة." + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations +msgid "Confirm" +msgstr "تأكيد" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__budget_confirm_amount +msgid "Confirmation Amount" +msgstr "مبلغ التصديق" + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_operations__state__confirmed +msgid "Confirmed" +msgstr "مؤكد" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__analytic_account_id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__analytic_account_id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__budget_line_id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__from_budget_line_id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__to_budget_line_id +msgid "Cost Center" +msgstr "مركز التكلفة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__create_uid +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__create_uid +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__create_uid +msgid "Created by" +msgstr "أنشئ بواسطة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__create_date +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__create_date +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__create_date +msgid "Created on" +msgstr "أنشئ في" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__currency_id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__currency_id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__currency_id +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget__currency_id +msgid "Currency" +msgstr "العملة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__date +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__date +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__date +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_search +msgid "Date" +msgstr "التاريخ" + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_operations__operation_type__decrease +msgid "Decrease" +msgstr "تخفيض" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__department_id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__department_id +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_search +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_search +msgid "Department" +msgstr "القسم" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__description +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__description +msgid "Description" +msgstr "الوصف" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__lines_ids +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_form +msgid "Details" +msgstr "تفاصيل المطابقة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__display_name +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__display_name +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__display_name +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget__display_name +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__display_name +#: model:ir.model.fields,field_description:account_budget_custom.field_report_account_budget_custom_budget_report__display_name +#: model:ir.model.fields,field_description:account_budget_custom.field_report_account_budget_custom_budget_xslx_report__display_name +msgid "Display Name" +msgstr "الاسم المعروض" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__res_id +msgid "Document ID" +msgstr "معرف المستند" + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_confirmation__state__draft +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_operations__state__draft +msgid "Draft" +msgstr "مسودة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_follower_ids +msgid "Followers" +msgstr "المتابعون" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_channel_ids +msgid "Followers (Channels)" +msgstr "المتابعون (القنوات)" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_partner_ids +msgid "Followers (Partners)" +msgstr "المتابعون (الشركاء)" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations +msgid "From" +msgstr "من" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_search +msgid "From Budget" +msgstr "من موازنة" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_search +msgid "From Cost Center" +msgstr "من مركز التكلفة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__id +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget__id +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__id +#: model:ir.model.fields,field_description:account_budget_custom.field_report_account_budget_custom_budget_report__id +#: model:ir.model.fields,field_description:account_budget_custom.field_report_account_budget_custom_budget_xslx_report__id +msgid "ID" +msgstr "المُعرف" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation__message_needaction +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation__message_unread +msgid "If checked, new messages require your attention." +msgstr "إذا كان محددًا، فهناك رسائل جديدة تحتاج لرؤيتها." + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation__message_has_error +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation__message_has_sms_error +msgid "If checked, some messages have a delivery error." +msgstr "إذا كان محددًا، فقد حدث خطأ في تسليم بعض الرسائل." + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_operations__operation_type__increase +msgid "Increase" +msgstr "تعزيز" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_is_follower +msgid "Is Follower" +msgstr "متابع" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation____last_update +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line____last_update +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations____last_update +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget____last_update +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines____last_update +#: model:ir.model.fields,field_description:account_budget_custom.field_report_account_budget_custom_budget_report____last_update +#: model:ir.model.fields,field_description:account_budget_custom.field_report_account_budget_custom_budget_xslx_report____last_update +msgid "Last Modified on" +msgstr "آخر تعديل في" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__write_uid +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__write_uid +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__write_uid +msgid "Last Updated by" +msgstr "آخر تحديث بواسطة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__write_date +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__write_date +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__write_date +msgid "Last Updated on" +msgstr "آخر تحديث في" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_main_attachment_id +msgid "Main Attachment" +msgstr "المرفق الرئيسي" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_has_error +msgid "Message Delivery error" +msgstr "خطأ في تسليم الرسائل" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_ids +msgid "Messages" +msgstr "الرسائل" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__name +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__name +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_search +msgid "Name" +msgstr "الاسم" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__new_balance +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation_line__new_balance +msgid "New Balance" +msgstr "المبلغ بعد الخصم" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/budget_confirmation.py:0 +#, python-format +msgid "No budget for " +msgstr "لا يوجد موازنة ل " + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/budget_confirmation.py:0 +#, python-format +msgid "No enough budget for " +msgstr "متبقي الموازنة لا يغطي " + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_needaction_counter +msgid "Number of Actions" +msgstr "عدد الإجراءات" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_has_error_counter +msgid "Number of errors" +msgstr "عدد الاخطاء" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation__message_needaction_counter +msgid "Number of messages which requires an action" +msgstr "عدد الرسائل التي تتطلب إجراء" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "عدد الرسائل الحادث بها خطأ في التسليم" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation__message_unread_counter +msgid "Number of unread messages" +msgstr "عدد الرسائل الجديدة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__operation_type +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_search +msgid "Operation Type" +msgstr "نوع العملية" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__practical_amount +msgid "Practical Amount" +msgstr "المبلغ الفعلي" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__provide +msgid "Provide" +msgstr "الدعومات" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.crossovered_budget_view_form +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_crossovered_budget_line_tree +msgid "Provided Amount" +msgstr "مبلغ الدعم" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__pull_out +msgid "Pull Out" +msgstr "المبلغ المحجوز/التخصيص" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.crossovered_budget_view_form +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_crossovered_budget_line_tree +msgid "Pull Out Amount" +msgstr "مبلغ السحب" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__ref +msgid "Reference" +msgstr "المرجع" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__res_model +msgid "Related Document Model Name" +msgstr "اسم كائن المستند المرتبط" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__remain +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__remain +msgid "Remain" +msgstr "المبلغ المتبقي" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.crossovered_budget_view_form +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_crossovered_budget_line_tree +msgid "Remain Amount" +msgstr "المبلغ المتاح" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation_line__remain +msgid "Remain in services budget for this cost center" +msgstr "المبلغ قبل الخصم لهذه الخدمات على هذه المراكز" + +#. module: account_budget_custom +#: model:ir.ui.menu,name:account_budget_custom.budget_reporting_menu +msgid "Reports" +msgstr "التقارير" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__user_id +msgid "Request user" +msgstr "المستخدم الطالب" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__from_reserved +msgid "Reserve?" +msgstr "محجوز؟" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__reserved_amount +msgid "Reserved Amount" +msgstr "المبلغ المحجوز" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget__reserved_percent +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__reserved_percent +msgid "Reserved Percent" +msgstr "نسبة الحجز" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.crossovered_budget_view_form +msgid "Reserved Percent %" +msgstr "نسبة المحجوز %" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_has_sms_error +msgid "SMS Delivery error" +msgstr "خطأ في تسليم الرسائل القصيرة" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#, python-format +msgid "Sorry, No data to Print" +msgstr "لا يوجد بيانات ليتم طباعتها" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_search +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_search +msgid "State" +msgstr "المحافظة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__state +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__state +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__state +msgid "Status" +msgstr "الحالة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__theoritical_amount +msgid "Theoretical Amount" +msgstr "القيمة النظرية" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations +msgid "To" +msgstr "ألى" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_search +msgid "To Budget" +msgstr "إلى موازنة" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_search +msgid "To Cost Center" +msgstr "إلى مركز التكلفة" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations +msgid "To Draft" +msgstr "الرجوع الي مبدئي" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation__total_amount +msgid "Total amount" +msgstr "إجمالي المبلغ" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation_line__amount +msgid "Total amount in services request line" +msgstr "المبلغ" + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_operations__operation_type__transfer +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_operations__type__transfer +msgid "Transfer" +msgstr "تحويل" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_search +msgid "Type" +msgstr "النوع" + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_operations__type__unlock +msgid "Unlock" +msgstr "إعادة الفتح" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_unread +msgid "Unread Messages" +msgstr "الرسائل الجديدة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_unread_counter +msgid "Unread Messages Counter" +msgstr "عدد الرسائل الجديدة" + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_confirmation__state__confirmed +msgid "Waiting Financial Controller" +msgstr "في إنتظار المدير المالي" + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_confirmation__state__done +msgid "Waiting Payment" +msgstr "في إنتظار الدفع" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__website_message_ids +msgid "Website Messages" +msgstr "رسائل الموقع" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation__website_message_ids +msgid "Website communication history" +msgstr "سجل تواصل الموقع" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/account_budget.py:0 +#, python-format +msgid "You can not take more than the remaining amount" +msgstr "لا يمكن أخذ أكثر من المبلغ المتبقي" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/account_budget.py:0 +#, python-format +msgid "You can not take more than the reserved amount." +msgstr "لا يمكن أخذ اكثر من المبلغ المحجوز" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/budget_confirmation.py:0 +#, python-format +msgid "You cannot copy a budget confirmation ." +msgstr "لا يمكن نسخ تصديق الموازنة" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/budget_confirmation.py:0 +#, python-format +msgid "You cannot delete a budget confirmation not in cancel state." +msgstr "لا يمكن حذف تصديق موازنة غير ملغى" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_search +msgid "budget.confirmation" +msgstr "" + +#. module: account_budget_custom +#: model:ir.model,name:account_budget_custom.model_budget_operations +msgid "budget.operations" +msgstr "" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/account_budget.py:0 +#, python-format +msgid "remaining" +msgstr "المتبقى" + +#. module: account_budget_custom +#: model:ir.model,name:account_budget_custom.model_report_account_budget_custom_budget_report +msgid "report.account_budget_custom.budget_report" +msgstr "" + +#. module: account_budget_custom +#: model:ir.model,name:account_budget_custom.model_report_account_budget_custom_budget_xslx_report +msgid "report.account_budget_custom.budget_xslx_report" +msgstr "" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_search +msgid "state" +msgstr "الحالة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__type +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__type +msgid "type" +msgstr "النوع" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#, python-format +msgid "الإنجاز" +msgstr "" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#, python-format +msgid "المبلغ الفعلى" +msgstr "" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#, python-format +msgid "المبلغ المخطط" +msgstr "" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#, python-format +msgid "المبلغ النظرية" +msgstr "" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#, python-format +msgid "المـوازنـة" +msgstr "" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#, python-format +msgid "الموازنات" +msgstr "" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#, python-format +msgid "تاريخ الإنتهاء" +msgstr "" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#, python-format +msgid "تاريخ البدء" +msgstr "" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#, python-format +msgid "وضع المـوازنـة" +msgstr "" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__exceed_budget +msgid "Allow Exceed Budget" +msgstr "السماح بتخطي الموازنة" + + +#. module: account_budget_custom +#: model:ir.model,name:account_budget_custom.model_report_account_budget_custom_budget_report +msgid "Budget Report" +msgstr "" + +#. module: account_budget_custom +#: model:res.groups,name:account_budget_custom.group_budget_user +msgid "Budget User" +msgstr "مسستخدم الموازنة" + +#. module: account_budget_custom +#: model:res.groups,name:account_budget_custom.group_manager_budget +msgid "Manager of Budget" +msgstr "مدير الموازنة" + + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.reject_wizard +msgid "Close" +msgstr "إلغاء" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_reject_wizard__origin +msgid "Origin" +msgstr "المصدر" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_reject_wizard__origin_name +msgid "Origin Name" +msgstr "الإسم المصدر" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.reject_wizard +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_form +msgid "Reject" +msgstr "رفض" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__reject_reason +msgid "Reject Reason" +msgstr "سبب الرفض" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_reject_wizard__reject_reason +msgid "Reject Reson" +msgstr "سبب الرفض" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_search +msgid "budget.confirmation" +msgstr "تصديق الموازنة" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.reject_wizard +msgid "or" +msgstr "أو" + +#. module: account_budget_custom +#: model:ir.model,name:account_budget_custom.model_reject_wizard +msgid "reject.wizard" +msgstr "" + + diff --git a/odex25_accounting/account_budget_custom/i18n/ar_001.po b/odex25_accounting/account_budget_custom/i18n/ar_001.po new file mode 100644 index 000000000..a9845b10e --- /dev/null +++ b/odex25_accounting/account_budget_custom/i18n/ar_001.po @@ -0,0 +1,992 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_budget_custom +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-05-08 11:11+0000\n" +"PO-Revision-Date: 2024-05-08 11:11+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: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__account_id +msgid "Account" +msgstr "الحساب" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__percentage +msgid "Achievement" +msgstr "نسبة الصرف" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_needaction +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__message_needaction +msgid "Action Needed" +msgstr "إجراء مطلوب" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__activity_ids +msgid "Activities" +msgstr "الأنشطة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__activity_exception_decoration +msgid "Activity Exception Decoration" +msgstr "ترتيب استثناء النشاط" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__activity_state +msgid "Activity State" +msgstr "حالة النشاط" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__activity_type_icon +msgid "Activity Type Icon" +msgstr "أيقونة نوع النشاط" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/budget_confirmation.py:0 +#, python-format +msgid "All lines should have accounts" +msgstr "يجب أن تحتوي جميع الأسطر على حسابات" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__exceed_budget +msgid "Allow Exceed Budget" +msgstr "السماح بتخطي الموازنة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__total_amount +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__amount +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__amount +msgid "Amount" +msgstr "مبلغ" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_form +msgid "Approve" +msgstr "موافقة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_attachment_count +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__message_attachment_count +msgid "Attachment Count" +msgstr "عدد المرفقات" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__beneficiary_id +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_search +msgid "Beneficiary" +msgstr "المستفيد" + +#. module: account_budget_custom +#: model:ir.model,name:account_budget_custom.model_crossovered_budget +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__from_crossovered_budget_id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__to_crossovered_budget_id +msgid "Budget" +msgstr "الموازنة" + +#. module: account_budget_custom +#: model:ir.model,name:account_budget_custom.model_budget_confirmation +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__confirmation_id +msgid "Budget Confirmation" +msgstr "تعميد الموازنة" + +#. module: account_budget_custom +#: model:ir.model,name:account_budget_custom.model_budget_confirmation_line +msgid "Budget Confirmation details" +msgstr "تفاصيل تصديق الموازنة" + +#. module: account_budget_custom +#: model:ir.actions.act_window,name:account_budget_custom.action_budget_confirmation_form +#: model:ir.ui.menu,name:account_budget_custom.menu_budget_confirmation +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_form +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_tree +msgid "Budget Confirmations" +msgstr "تحقق الموازنة" + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_confirmation__state__bdgt_dep_mngr +#: model:res.groups,name:account_budget_custom.group_department_manager_budget +msgid "Budget Department Manager" +msgstr "مدير إدارة الميزانية" + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_confirmation__state__confirmed +#: model:res.groups,name:account_budget_custom.group_manager_budget +msgid "Budget Executive Director" +msgstr "المدير التنفيذي للإدارة المالية" + +#. module: account_budget_custom +#: model:ir.model,name:account_budget_custom.model_crossovered_budget_lines +msgid "Budget Line" +msgstr "بند الموازنة" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_crossovered_budget_line_graph +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_crossovered_budget_line_pivot +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_crossovered_budget_line_tree +#, python-format +msgid "Budget Lines" +msgstr "خطوط الموازنة" + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_confirmation__state__draft +msgid "Budget Officer " +msgstr "موظف الميزانية " + +#. module: account_budget_custom +#: model:ir.actions.act_window,name:account_budget_custom.open_budget_operations +#: model:ir.ui.menu,name:account_budget_custom.menu_budget_operations_form +msgid "Budget Operation" +msgstr "عمليات الموازنة" + +#. module: account_budget_custom +#: model:ir.model,name:account_budget_custom.model_budget_operations +#: model:ir.ui.menu,name:account_budget_custom.menu_budget_operations +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_search +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_transfer_tree +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_tree +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_unlock_tree +msgid "Budget Operations" +msgstr "عمليات الموازنة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__from_budget_post_id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__to_budget_post_id +msgid "Budget Post" +msgstr "البند" + +#. module: account_budget_custom +#: model:ir.model,name:account_budget_custom.model_report_account_budget_custom_budget_report +msgid "Budget Report" +msgstr "تقرير الموازنة" + +#. module: account_budget_custom +#: model:ir.actions.act_window,name:account_budget_custom.open_budget_operations_transfer +msgid "Budget Transfer" +msgstr "مناقله بين الموازنات" + +#. module: account_budget_custom +#: model:ir.actions.act_window,name:account_budget_custom.open_budget_unlock_restriction +#: model:ir.ui.menu,name:account_budget_custom.menu_budget_unlock_restriction_form +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_unlock_restriction +msgid "Budget Unlock Restriction" +msgstr "إلغاء حجز الموازنة" + +#. module: account_budget_custom +#: model:res.groups,name:account_budget_custom.group_budget_user +msgid "Budget User" +msgstr "مسستخدم الموازنة" + +#. module: account_budget_custom +#: model:ir.actions.report,name:account_budget_custom.action_report_budget_xlsx +msgid "Budget XLSX" +msgstr "الموازنة (اكسل)" + +#. module: account_budget_custom +#: model:ir.model,name:account_budget_custom.model_report_account_budget_custom_budget_xslx_report +msgid "Budget XLSX Report" +msgstr "تقرير الموازنة (اكسل)" + +#. module: account_budget_custom +#: model:ir.model,name:account_budget_custom.model_account_budget_post +msgid "Budgetary Position" +msgstr "بند الموازنة" + +#. module: account_budget_custom +#: model:ir.ui.menu,name:account_budget_custom.main_budgets_menu +msgid "Budgets" +msgstr "الموازنات" + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_confirmation__state__cancel +msgid "Cancel" +msgstr "إلغاء" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.reject_wizard +msgid "Close" +msgstr "إلغاء" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__company_id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__company_id +msgid "Company" +msgstr "المؤسسة" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_crossovered_budget_lines__percentage +msgid "" +"Comparison between practical and theoretical amount. This measure tells you " +"if you are below or over budget." +msgstr "" +"المقارنة بين القيمة الفعلية والنظرية. تحدد نسبة الانحراف في الإيرادات أو " +"المصروفات في الموازنة." + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_unlock_restriction +msgid "Confirm" +msgstr "تأكيد" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__confirm +msgid "Confirm Amount" +msgstr "المبلغ المصدق" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__budget_confirm_amount +msgid "Confirmation Amount" +msgstr "مبلغ التصديق" + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_operations__state__confirmed +msgid "Confirmed" +msgstr "مؤكد" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__analytic_account_id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__analytic_account_id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__budget_line_id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__from_budget_line_id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__to_budget_line_id +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__to_operation_ids +msgid "Cost Center" +msgstr "الحساب التحليلي (بند الموازنة)" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__create_uid +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__create_uid +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__create_uid +#: model:ir.model.fields,field_description:account_budget_custom.field_reject_wizard__create_uid +msgid "Created by" +msgstr "أنشئ بواسطة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__create_date +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__create_date +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__create_date +#: model:ir.model.fields,field_description:account_budget_custom.field_reject_wizard__create_date +msgid "Created on" +msgstr "أنشئ في" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__currency_id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__currency_id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__currency_id +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget__currency_id +msgid "Currency" +msgstr "العملة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__date +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__date +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__date +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_search +msgid "Date" +msgstr "التاريخ" + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_operations__operation_type__decrease +msgid "Decrease" +msgstr "تخفيض" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__department_id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__department_id +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_search +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_search +msgid "Department" +msgstr "القسم" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__description +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__description +msgid "Description" +msgstr "الوصف" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__lines_ids +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_form +msgid "Details" +msgstr "تفاصيل المطابقة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__display_name +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__display_name +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__display_name +#: model:ir.model.fields,field_description:account_budget_custom.field_reject_wizard__display_name +#: model:ir.model.fields,field_description:account_budget_custom.field_report_account_budget_custom_budget_report__display_name +#: model:ir.model.fields,field_description:account_budget_custom.field_report_account_budget_custom_budget_xslx_report__display_name +msgid "Display Name" +msgstr "الاسم المعروض" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__res_id +msgid "Document ID" +msgstr "معرف المستند" + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_confirmation__state__done +msgid "Done" +msgstr "تم التعميد" + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_operations__state__draft +msgid "Draft" +msgstr "موظف الميزانية" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__final_amount +#: model_terms:ir.ui.view,arch_db:account_budget_custom.crossovered_budget_view_form +msgid "Final Amount" +msgstr "المبلغ النهائي" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_follower_ids +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__message_follower_ids +msgid "Followers" +msgstr "المتابعون" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_channel_ids +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__message_channel_ids +msgid "Followers (Channels)" +msgstr "المتابعون (القنوات)" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_partner_ids +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__message_partner_ids +msgid "Followers (Partners)" +msgstr "المتابعون (الشركاء)" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_operations__activity_type_icon +msgid "Font awesome icon e.g. fa-tasks" +msgstr "" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations +msgid "From" +msgstr "من" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_search +msgid "From Budget" +msgstr "من موازنة" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_search +msgid "From Cost Center" +msgstr "من الحساب التحليلي (بند الموازنة)" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__from_operation_ids +msgid "From Operation" +msgstr "من العملية" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__id +#: model:ir.model.fields,field_description:account_budget_custom.field_reject_wizard__id +#: model:ir.model.fields,field_description:account_budget_custom.field_report_account_budget_custom_budget_report__id +#: model:ir.model.fields,field_description:account_budget_custom.field_report_account_budget_custom_budget_xslx_report__id +msgid "ID" +msgstr "المرجع" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__activity_exception_icon +msgid "Icon" +msgstr "" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_operations__activity_exception_icon +msgid "Icon to indicate an exception activity." +msgstr "" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation__message_needaction +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation__message_unread +#: model:ir.model.fields,help:account_budget_custom.field_budget_operations__message_needaction +#: model:ir.model.fields,help:account_budget_custom.field_budget_operations__message_unread +msgid "If checked, new messages require your attention." +msgstr "إذا كان محددًا، فهناك رسائل جديدة تحتاج لرؤيتها." + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation__message_has_error +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation__message_has_sms_error +#: model:ir.model.fields,help:account_budget_custom.field_budget_operations__message_has_error +#: model:ir.model.fields,help:account_budget_custom.field_budget_operations__message_has_sms_error +msgid "If checked, some messages have a delivery error." +msgstr "إذا كان محددًا، فقد حدث خطأ في تسليم بعض الرسائل." + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_operations__operation_type__increase +msgid "Increase" +msgstr "تعزيز" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_is_follower +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__message_is_follower +msgid "Is Follower" +msgstr "متابع" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__is_transfered +msgid "Is Transfered" +msgstr "" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation____last_update +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line____last_update +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations____last_update +#: model:ir.model.fields,field_description:account_budget_custom.field_reject_wizard____last_update +#: model:ir.model.fields,field_description:account_budget_custom.field_report_account_budget_custom_budget_report____last_update +#: model:ir.model.fields,field_description:account_budget_custom.field_report_account_budget_custom_budget_xslx_report____last_update +msgid "Last Modified on" +msgstr "آخر تعديل في" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__write_uid +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__write_uid +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__write_uid +#: model:ir.model.fields,field_description:account_budget_custom.field_reject_wizard__write_uid +msgid "Last Updated by" +msgstr "آخر تحديث بواسطة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__write_date +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__write_date +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__write_date +#: model:ir.model.fields,field_description:account_budget_custom.field_reject_wizard__write_date +msgid "Last Updated on" +msgstr "آخر تحديث في" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_main_attachment_id +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__message_main_attachment_id +msgid "Main Attachment" +msgstr "المرفق الرئيسي" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_has_error +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__message_has_error +msgid "Message Delivery error" +msgstr "خطأ في تسليم الرسائل" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_ids +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__message_ids +msgid "Messages" +msgstr "الرسائل" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__my_activity_date_deadline +msgid "My Activity Deadline" +msgstr "نهاية الوقت المعين للنشاط" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__name +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__name +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_search +msgid "Name" +msgstr "الاسم" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__new_balance +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation_line__new_balance +msgid "New Balance" +msgstr "المبلغ بعد الخصم" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__activity_date_deadline +msgid "Next Activity Deadline" +msgstr "الموعد النهائي للنشاط التالي" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__activity_summary +msgid "Next Activity Summary" +msgstr "ملخص النشاط التالي" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__activity_type_id +msgid "Next Activity Type" +msgstr "نوع النشاط التالي" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/budget_confirmation.py:0 +#, python-format +msgid "No budget for " +msgstr "لا يوجد موازنة ل " + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/budget_confirmation.py:0 +#, python-format +msgid "No enough budget for " +msgstr "متبقي الموازنة لا يغطي " + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_needaction_counter +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__message_needaction_counter +msgid "Number of Actions" +msgstr "عدد الإجراءات" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_has_error_counter +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__message_has_error_counter +msgid "Number of errors" +msgstr "عدد الاخطاء" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation__message_needaction_counter +#: model:ir.model.fields,help:account_budget_custom.field_budget_operations__message_needaction_counter +msgid "Number of messages which requires an action" +msgstr "عدد الرسائل التي تتطلب إجراء" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation__message_has_error_counter +#: model:ir.model.fields,help:account_budget_custom.field_budget_operations__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "عدد الرسائل الحادث بها خطأ في التسليم" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation__message_unread_counter +#: model:ir.model.fields,help:account_budget_custom.field_budget_operations__message_unread_counter +msgid "Number of unread messages" +msgstr "عدد الرسائل الجديدة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__operation_type +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_search +msgid "Operation Type" +msgstr "نوع العملية" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_reject_wizard__origin +msgid "Origin" +msgstr "المصدر" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_reject_wizard__origin_name +msgid "Origin Name" +msgstr "الإسم المصدر" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__practical_amount +msgid "Practical Amount" +msgstr "المبلغ الفعلي" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__provide +msgid "Provide" +msgstr "الدعومات" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.crossovered_budget_view_form +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_crossovered_budget_line_tree +msgid "Provided Amount" +msgstr "مبلغ الدعم" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__pull_out +msgid "Pull Out" +msgstr "تخفيض" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.crossovered_budget_view_form +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_crossovered_budget_line_tree +msgid "Pull Out Amount" +msgstr "مبلغ السحب" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__purchase_remain +msgid "Purchase Remain" +msgstr "المتبقي من التعميد" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__purchase_remind +msgid "Purchase Remind" +msgstr "المتبقي من التعميد" + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_confirmation__type__purchase_request +msgid "Purchase Request" +msgstr "طلب شراء" + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_confirmation__type__purchase_order +msgid "Purchase Requisition" +msgstr "" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__reason +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__reason +msgid "Reason/Justification" +msgstr "السببظ المبرر" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__ref +msgid "Reference" +msgstr "المرجع" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.reject_wizard +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_form +msgid "Reject" +msgstr "رفض" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__reject_reason +#: model:ir.model.fields,field_description:account_budget_custom.field_reject_wizard__reject_reason +msgid "Reject Reason" +msgstr "سبب الرفض" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__res_model +msgid "Related Document Model Name" +msgstr "اسم كائن المستند المرتبط" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__remain +msgid "Remain" +msgstr "الباقي" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.crossovered_budget_view_form +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_crossovered_budget_line_tree +msgid "Remain Amount" +msgstr "المبلغ المتاح" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation_line__remain +msgid "Remain in services budget for this cost center" +msgstr "المبلغ قبل الخصم لهذه الخدمات على هذه المراكز" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__remain +msgid "Remain of Christening" +msgstr "" + +#. module: account_budget_custom +#: model:ir.ui.menu,name:account_budget_custom.budget_reporting_menu +msgid "Reports" +msgstr "التقارير" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__user_id +msgid "Request user" +msgstr "المستخدم الطالب" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__reserve +#: model_terms:ir.ui.view,arch_db:account_budget_custom.crossovered_budget_view_form +msgid "Reserve Amount" +msgstr "المبلغ المحجوز" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__from_reserved +msgid "Reserve?" +msgstr "محجوز؟" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__reserved_amount +msgid "Reserved Amount" +msgstr "المبلغ المحجوز" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget__reserved_percent +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__reserved_percent +msgid "Reserved Percent" +msgstr "نسبة الحجز" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.crossovered_budget_view_form +msgid "Reserved Percent %" +msgstr "نسبة المحجوز %" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__activity_user_id +msgid "Responsible User" +msgstr "المستخدم المسؤول" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_has_sms_error +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__message_has_sms_error +msgid "SMS Delivery error" +msgstr "خطأ في تسليم الرسائل القصيرة" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/budget_confirmation.py:0 +#, python-format +msgid "Sorry This object have no field named Selection Reason" +msgstr "" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#, python-format +msgid "Sorry, No data to Print" +msgstr "لا يوجد بيانات ليتم طباعتها" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/budget_confirmation.py:0 +#, python-format +msgid "Specify Reject Reason" +msgstr "تحديد سبب الرفض" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_search +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_search +msgid "State" +msgstr "الحالة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__state +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation_line__state +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__state +msgid "Status" +msgstr "الحالة" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_operations__activity_state +msgid "" +"Status based on activities\n" +"Overdue: Due date is already passed\n" +"Today: Activity date is today\n" +"Planned: Future activities." +msgstr "" +"الحالة على أساس الأنشطة\n" +"المتأخرة: تاريخ الاستحقاق مر\n" +"اليوم: تاريخ النشاط هو اليوم\n" +"المخطط: الأنشطة المستقبلية." + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__theoritical_amount +msgid "Theoretical Amount" +msgstr "القيمة النظرية" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/account_budget.py:0 +#, python-format +msgid "This position can not be deleted" +msgstr "لا يمكن حذف مركز موازنة" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations +msgid "To" +msgstr "ألى" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_search +msgid "To Budget" +msgstr "إلى موازنة" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_search +msgid "To Cost Center" +msgstr "إلى الحساب التحليلي" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_unlock_restriction +msgid "To Draft" +msgstr "الرجوع الي مبدئي" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation__total_amount +msgid "Total amount" +msgstr "إجمالي المبلغ" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation_line__amount +msgid "Total amount in services request line" +msgstr "المبلغ" + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_operations__operation_type__transfer +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_operations__type__transfer +#: model_terms:ir.ui.view,arch_db:account_budget_custom.crossovered_budget_view_form +msgid "Transfer" +msgstr "تحويل" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_search +msgid "Type" +msgstr "النوع" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_operations__activity_exception_decoration +msgid "Type of the exception activity on record." +msgstr "نوع النشاط الاستثنائي المسجل." + +#. module: account_budget_custom +#: model:ir.model.fields.selection,name:account_budget_custom.selection__budget_operations__type__unlock +msgid "Unlock" +msgstr "إعادة الفتح" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_unread +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__message_unread +msgid "Unread Messages" +msgstr "الرسائل الجديدة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__message_unread_counter +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__message_unread_counter +msgid "Unread Messages Counter" +msgstr "عدد الرسائل الجديدة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__website_message_ids +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__website_message_ids +msgid "Website Messages" +msgstr "رسائل الموقع" + +#. module: account_budget_custom +#: model:ir.model.fields,help:account_budget_custom.field_budget_confirmation__website_message_ids +#: model:ir.model.fields,help:account_budget_custom.field_budget_operations__website_message_ids +msgid "Website communication history" +msgstr "سجل تواصل الموقع" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_crossovered_budget_lines__year_end +msgid "Year End" +msgstr "نهاية السنة" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/budget_operations.py:0 +#, python-format +msgid "You can transfer to approved budget only" +msgstr "" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/account_budget.py:0 +#, python-format +msgid "You can not delete budget not in draft state" +msgstr "لا يمكن حذف موازنة ليست في مرحلة مسودة" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/account_budget.py:0 +#, python-format +msgid "You can not take more than the remaining amount" +msgstr "لا يمكن أخذ أكثر من المبلغ المتبقي" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/account_budget.py:0 +#, python-format +msgid "You can not take more than the remaining amount.." +msgstr "لا يمكن أخذ أكثر من المبلغ المتبقي" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/account_budget.py:0 +#, python-format +msgid "You can not take more than the reserved amount." +msgstr "لا يمكن أخذ اكثر من المبلغ المحجوز" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/budget_confirmation.py:0 +#, python-format +msgid "You cannot copy a budget confirmation ." +msgstr "لا يمكن نسخ تصديق الموازنة" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/budget_confirmation.py:0 +#, python-format +msgid "You cannot delete a budget confirmation not in cancel state." +msgstr "لا يمكن حذف تصديق موازنة غير ملغى" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_confirmation_search +msgid "budget.confirmation" +msgstr "تعميد الموازنة" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.reject_wizard +msgid "or" +msgstr "أو" + +#. module: account_budget_custom +#: model:ir.model,name:account_budget_custom.model_reject_wizard +msgid "reject.wizard" +msgstr "رفض المعالج" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/account_budget.py:0 +#, python-format +msgid "remaining" +msgstr "المتبقى" + +#. module: account_budget_custom +#: model_terms:ir.ui.view,arch_db:account_budget_custom.view_budget_operations_search +msgid "state" +msgstr "الحالة" + +#. module: account_budget_custom +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_confirmation__type +#: model:ir.model.fields,field_description:account_budget_custom.field_budget_operations__type +msgid "type" +msgstr "النوع" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#, python-format +msgid "الإنجاز" +msgstr "" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#, python-format +msgid "المبلغ الفعلى" +msgstr "" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#, python-format +msgid "المبلغ المخطط" +msgstr "" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#, python-format +msgid "المبلغ النظرية" +msgstr "المبلغ النظري" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#, python-format +msgid "المـوازنـة" +msgstr "" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#, python-format +msgid "الموازنات" +msgstr "" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#, python-format +msgid "تاريخ الإنتهاء" +msgstr "" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#, python-format +msgid "تاريخ البدء" +msgstr "" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/reports/budget_report_xlsx.py:0 +#, python-format +msgid "وضع المـوازنـة" +msgstr "" \ No newline at end of file diff --git a/odex25_accounting/account_budget_custom/models/__init__.py b/odex25_accounting/account_budget_custom/models/__init__.py new file mode 100644 index 000000000..1da94e009 --- /dev/null +++ b/odex25_accounting/account_budget_custom/models/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + +from . import account_budget +from . import budget_operations +from . import budget_confirmation diff --git a/odex25_accounting/account_budget_custom/models/account_budget.py b/odex25_accounting/account_budget_custom/models/account_budget.py new file mode 100644 index 000000000..7738d5e91 --- /dev/null +++ b/odex25_accounting/account_budget_custom/models/account_budget.py @@ -0,0 +1,234 @@ +from odoo import api, fields, models, _ +from odoo.exceptions import UserError, ValidationError + + +class AccountBudgetPost(models.Model): + _inherit = "account.budget.post" + + def unlink(self): + raise ValidationError(_('This position can not be deleted')) + # return super(AccountBudgetPost, self).unlink() + + +class CrossoveredBudget(models.Model): + _inherit = "crossovered.budget" + _order = "create_date desc" + + reserved_percent = fields.Float(string='Reserved Percent') + currency_id = fields.Many2one('res.currency', string='Currency', + readonly=True, required=True, + default=lambda self: self.env.user.company_id.currency_id.id) + + def unlink(self): + for budget in self: + if budget.state not in 'draft': + raise UserError(_('You can not delete budget not in draft state')) + return super(CrossoveredBudget, self).unlink() + + +class CrossoveredBudgetLines(models.Model): + _inherit = "crossovered.budget.lines" + + reserved_percent = fields.Float(related='crossovered_budget_id.reserved_percent', string='Reserved Percent') + reserved_amount = fields.Float(string='Reserved Amount', readonly=True, compute='_compute_reserved_amount') + # pull_out = fields.Float(string='Pull Out', compute='_compute_operations_amount', store=True, tracking=True) + pull_out = fields.Monetary(string='Pull Out') + + provide = fields.Float(string='Provide', compute='_compute_operations_amount', store=True) + remain = fields.Float(string='Remain of Christening', compute='_compute_operations_amount') + budget_confirm_amount = fields.Float(string='Confirmation Amount', compute='_compute_operations_amount') + purchase_remain = fields.Float(store=True) + practical_amount = fields.Float(compute='_compute_practical_amount', string='Practical Amount', digits=0, + store=False) + theoritical_amount = fields.Float(compute='_compute_theoritical_amount', string='Theoretical Amount', digits=0, + store=True) + percentage = fields.Float(compute='_compute_percentage', string='Achievement', store=False, digits=(16, 4)) + from_operation_ids = fields.One2many('budget.operations', 'from_budget_line_id', string='From Operation') + to_operation_ids = fields.One2many('budget.operations', 'to_budget_line_id', string='Cost Center') + reserve = fields.Float(string='Last Reserve Amount') + confirm = fields.Float(string='Confirm Amount') + year_end = fields.Boolean(compute="get_year_end") + is_transfered = fields.Boolean(default=False) + final_amount = fields.Float(compute='_compute_final_amount') + + @api.depends('planned_amount', 'pull_out', 'provide') + def _compute_final_amount(self): + for line in self: + line.final_amount = line.planned_amount + line.provide - line.pull_out + + def get_year_end(self): + for rec in self: + date = fields.Date.today() + if rec.crossovered_budget_id.date_to <= date and rec.purchase_remain > 0: + rec.year_end = True + else: + rec.year_end = False + + def transfer_budget_action(self): + formview_ref = self.env.ref('account_budget_custom.view_budget_operations', False) + return { + 'name': ("Budget Transfer"), + 'view_mode': ' form', + 'view_id': False, + 'view_type': 'form', + 'res_model': 'budget.operations', + 'type': 'ir.actions.act_window', + 'target': 'new', + 'views': [(formview_ref and formview_ref.id or False, 'form')], + 'context': { + 'default_operation_type': 'transfer', + 'default_from_budget_post_id': self.general_budget_id.id, + 'default_from_crossovered_budget_id': self.crossovered_budget_id.id, + 'default_from_budget_line_id': self.id, + 'default_purchase_remind': self.purchase_remain, + 'default_date': fields.Date.today(), + } + } + + @api.depends('from_operation_ids', 'to_operation_ids') + def _compute_operations_amount(self): + if not self.ids: return + for line in self: + pull_out = provide = budget_confirm_amount = purchase_remind = reserve_amount = 0.0 + date_to = self.env.context.get('wizard_date_to') or line.date_to + date_from = self.env.context.get( + 'wizard_date_from') or line.date_from + + if line.analytic_account_id.id: + if 'reserved' not in self.env.context: + self.env.cr.execute(""" + SELECT SUM(amount) + FROM budget_operations + WHERE from_budget_line_id=%s + AND (date between %s AND %s) + AND state='confirmed'""", + (line._origin.id, date_from, date_to,)) + pull_out = self.env.cr.fetchone()[0] or 0.0 + + if 'reserved' in self.env.context: + self.env.cr.execute(""" + SELECT SUM(amount) + FROM budget_operations + WHERE from_budget_line_id=%s + AND (date between %s AND %s) + AND state='confirmed' + AND from_reserved=%s""", + (line._origin.id, date_from, date_to, self.env.context['reserved'])) + pull_out = self.env.cr.fetchone()[0] or 0.0 + + self.env.cr.execute(""" + SELECT SUM(amount) + FROM budget_operations + WHERE to_budget_line_id=%s + AND (date between %s AND %s) + AND state='confirmed'""", + (line._origin.id, date_from, date_to,)) + provide = self.env.cr.fetchone()[0] or 0.0 + + self.env.cr.execute(""" + SELECT SUM(purchase_remind) + FROM budget_operations + WHERE to_budget_line_id=%s + AND (date between %s AND %s) + AND state='confirmed'""", + (line._origin.id, date_from, date_to,)) + reserve_amount = self.env.cr.fetchone()[0] or 0.0 + + self.env.cr.execute(""" + SELECT SUM(amount) + FROM budget_confirmation_line + WHERE budget_line_id=%s + AND (date between %s AND %s) + AND state='done'""", + (line._origin.id, date_from, date_to,)) + budget_confirm_amount = self.env.cr.fetchone()[0] or 0.0 + + line.provide = provide + line.budget_confirm_amount = budget_confirm_amount + # line.remain = line.planned_amount + provide + line.pull_out - line.practical_amount + line.reserve + line.purchase_remain + line.remain = line.final_amount - line.practical_amount + + @api.depends('analytic_account_id', 'planned_amount', 'practical_amount') + def name_get(self): + result = [] + + for line in self: + name = '' + name += line.analytic_account_id and line.analytic_account_id.name or '' + ' ' + _('remaining') + ' ' + + # check if reserved is needed + if self.env.context.get('reserved', False): + name += str(line.reserved_amount) + + if not self.env.context.get('reserved', False): + name += str(line.remain) + + result.append((line.id, name)) + return result + + # @api.depends('crossovered_budget_id.reserved_percent') + def _compute_reserved_amount(self): + for line in self: + reserved_amount = line.crossovered_budget_id.reserved_percent * \ + line.planned_amount / 100.0 + if reserved_amount: + reserved_amount -= line.with_context({'reserved': True}).pull_out + line.reserved_amount = reserved_amount + + def _compute_practical_amount(self): + for line in self: + result = 0.0 + acc_ids = line.general_budget_id.account_ids.ids + date_to = self.env.context.get('wizard_date_to') or line.date_to + date_from = self.env.context.get( + 'wizard_date_from') or line.date_from + if line.analytic_account_id.id: + analytic_ids = self.env['account.analytic.account'].search( + ['|', ('id', '=', line.analytic_account_id.id), + ('parent_id', 'child_of', line.analytic_account_id.id)]) + self.env.cr.execute( + """ + SELECT SUM(amount) + FROM account_analytic_line + WHERE account_id IN %s + AND (date between %s AND %s) + AND general_account_id=ANY(%s)""", + (tuple(analytic_ids.ids), date_from, date_to, acc_ids,)) + result = self.env.cr.fetchone()[0] or 0.0 + line.practical_amount = result + else: + + aml_obj = self.env['account.move.line'] + domain = [('account_id', 'in', + line.general_budget_id.account_ids.ids), + ('date', '>=', date_from), + ('date', '<=', date_to), + ('move_id.state', '=', 'posted') + ] + where_query = aml_obj._where_calc(domain) + aml_obj._apply_ir_rules(where_query, 'read') + from_clause, where_clause, where_clause_params = where_query.get_sql() + select = "SELECT sum(credit)-sum(debit) from " + from_clause + " where " + where_clause + + self.env.cr.execute(select, where_clause_params) + line.practical_amount = self.env.cr.fetchone()[0] or 0.0 + + def _check_amount(self, amount=0, purchase_remind=0, transfer=False): + for obj in self: + if self.from_operation_ids.operation_type=='transfer' and self.from_operation_ids.purchase_remind>obj.final_amount: + raise ValidationError(_('''You can not take more than the remaining amount..''')) + # if obj.purchase_remain> + + reserved_amount = obj.crossovered_budget_id.reserved_percent * \ + obj.planned_amount / 100.0 + if obj.with_context({'reserved': True}).pull_out > reserved_amount: + raise ValidationError( + _('''You can not take more than the reserved amount.''')) + if obj.planned_amount < 0: + if transfer and obj.purchase_remain != purchase_remind: + raise ValidationError(_('''You can not take more than the remaining amount..''')) + else: + + if abs(obj.remain) < amount or obj.purchase_remain < purchase_remind: + raise ValidationError( + _('''You can not take more than the remaining amount''')) diff --git a/odex25_accounting/account_budget_custom/models/budget_confirmation.py b/odex25_accounting/account_budget_custom/models/budget_confirmation.py new file mode 100644 index 000000000..d02406d9f --- /dev/null +++ b/odex25_accounting/account_budget_custom/models/budget_confirmation.py @@ -0,0 +1,248 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Expert Co. Ltd. +# Copyright (C) 2018 (). +# +############################################################################## + + +from odoo import api, fields, models, _ +from odoo.exceptions import Warning, ValidationError + + +class BudgetConfirmation(models.Model): + _name = 'budget.confirmation' + _inherit = ['mail.thread'] + _description = 'Budget Confirmation' + _order = "create_date desc" + + name = fields.Char(string='Name') + + date = fields.Date(string='Date', required=True) + + beneficiary_id = fields.Many2one(comodel_name='res.partner', + required=False, string='Beneficiary') + + department_id = fields.Many2one( + comodel_name='hr.department', string='Department') + + analytic_account_id = fields.Many2one( + comodel_name='account.analytic.account', + string='Cost Center') + + type = fields.Selection(string='type', selection=[('purchase.order', 'Purchase Requisition'), ('purchase.request', 'Purchase Request')]) + + ref = fields.Char(string='Reference') + + res_model = fields.Char( + 'Related Document Model Name') + res_id = fields.Integer('Document ID') + + description = fields.Text(string='Description') + + total_amount = fields.Monetary( + string='Amount', + help="Total amount") + + state = fields.Selection( + [('draft', 'Budget Officer '), + ('bdgt_dep_mngr', 'Budget Department Manager'), + ('confirmed', 'Budget Executive Director'), + ('done', 'Done'), + ('cancel', 'Cancel')], + default='draft', string='Status', readonly=True, tracking=True) + + lines_ids = fields.One2many(comodel_name='budget.confirmation.line', + inverse_name='confirmation_id', string='Details', required=True) + + user_id = fields.Many2one(comodel_name='res.users', string='Request user', + required=False, default=lambda self: self.env.user) + + company_id = fields.Many2one(string='Company', comodel_name='res.company', + default=lambda self: self.env.user.company_id) + + currency_id = fields.Many2one( + 'res.currency', string='Currency', required=True, readonly=True, + states={'draft': [('readonly', False)]}, + default=lambda self: self.env.user.company_id.currency_id.id) + + exceed_budget = fields.Boolean(default=False, string='Allow Exceed Budget') + reject_reason = fields.Char('Reject Reason') + + + def reject(self): + action_name = _('Specify Reject Reason') + return { + 'type': 'ir.actions.act_window', + 'name': action_name, + 'res_model': 'reject.wizard', + 'view_type': 'form', + 'view_mode': 'form', + 'target': 'new', + 'context': {'default_origin': self.id, 'default_origin_name': self._name} + } + + def confirm(self): + """ + change state to confirm and check budget + """ + for rec in self: + for line in rec.lines_ids: + line.sudo().check_budget() + + self.write({'state': 'confirmed'}) + + def done(self): + """ + change state to done and do specific action depend on operation type + """ + self.write({'state': 'done'}) + + + def bdgt_dep_mngr(self): + """ + change state to bdgt_dep_mngr and do specific action depend on operation type + """ + self.write({'state': 'bdgt_dep_mngr'}) + + def cancel(self): + """ + change state to cancel + """ + self.write({'state': 'cancel'}) + + def to_draft(self): + """ + change state to draft + """ + self.write({'state': 'draft'}) + + def unlink(self): + """ + Delete budget confirmation, but they must be in cancel state. + :return: + """ + for rec in self: + if rec.state != 'cancel': + raise ValidationError( + _('You cannot delete a budget confirmation not in cancel state.')) + return super(BudgetConfirmation, self).unlink() + + def copy(self): + """ + prevent copy of budget confirmation. + :return: + """ + raise ValidationError( + _('You cannot copy a budget confirmation .')) + + +class BudgetConfirmationLine(models.Model): + _name = 'budget.confirmation.line' + _description = 'Budget Confirmation details' + + confirmation_id = fields.Many2one( + comodel_name='budget.confirmation', + string='Budget Confirmation', + ondelete='cascade', index=True + ) + account_id = fields.Many2one( + comodel_name='account.account', + string='Account' + ) + amount = fields.Float( + string='Amount', + digits='Product Price', + help="Total amount in services request line" + ) + remain = fields.Float( + string='Remain', + digits='Product Price', + help="Remain in services budget for this cost center" + ) + new_balance = fields.Float( + string='New Balance', + digits='Product Price', + help="New Balance" + ) + analytic_account_id = fields.Many2one( + comodel_name='account.analytic.account', + string='Cost Center', + required=True + ) + date = fields.Date( + related='confirmation_id.date', + string='Date', store=True, + readonly=True, related_sudo=False + ) + state = fields.Selection( + default='draft', string='Status', + readonly=True, related='confirmation_id.state', + store=True, related_sudo=False + ) + budget_line_id = fields.Many2one( + comodel_name='crossovered.budget.lines', + string='Cost Center' + ) + company_id = fields.Many2one( + comodel_name='res.company', string='Company', + related='confirmation_id.company_id', store=True, + readonly=True, related_sudo=False + ) + currency_id = fields.Many2one( + comodel_name='res.currency', + related='confirmation_id.currency_id', + store=True, related_sudo=False + ) + description = fields.Text( + string='Description' + ) + + def check_budget(self): + """ + check the available budget for given service and analytic amount + in defined period of time + :return: + """ + self.ensure_one() + if not self.account_id: + raise ValidationError(_('''All lines should have accounts''')) + analytic_account_id = self.analytic_account_id + date = self.date + date = fields.Date.from_string(date) + budget_post = self.env['account.budget.post'].search([]).filtered(lambda x: self.account_id in x.account_ids) + + budget_lines = analytic_account_id.crossovered_budget_line.filtered( + lambda x: x.general_budget_id in budget_post and + x.crossovered_budget_id.state == 'done' and + x.date_from <= date <= x.date_to) + + if budget_lines: + remain = abs(budget_lines[0].remain) + if remain >= self.confirmation_id.total_amount: + return True + + name = self.account_id.name + if not budget_lines: + raise ValidationError(_('''No budget for ''') + name) + if not self.confirmation_id.exceed_budget: + raise ValidationError(_('''No enough budget for ''') + name) + else: + pass + + +class RejectWizard(models.TransientModel): + _name = 'reject.wizard' + + origin = fields.Integer('') + reject_reason = fields.Text(string='Reject Reason') + origin_name = fields.Char('') + + def action_reject(self): + origin_rec = self.env[self.origin_name].sudo().browse(self.origin) + if dict(self._fields).get('reject_reason') is None: + raise ValidationError(_('Sorry This object have no field named Selection Reason')) + else: + origin_rec.write({'reject_reason': self.reject_reason}) + return origin_rec.with_context({'reject_reason': self.reject_reason}).cancel() \ No newline at end of file diff --git a/odex25_accounting/account_budget_custom/models/budget_operations.py b/odex25_accounting/account_budget_custom/models/budget_operations.py new file mode 100644 index 000000000..27a793e67 --- /dev/null +++ b/odex25_accounting/account_budget_custom/models/budget_operations.py @@ -0,0 +1,142 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Expert Co. Ltd. +# Copyright (C) 2018 (). +# +############################################################################## + +from odoo import api, fields, models, _ +from odoo.exceptions import ValidationError + + +class BudgetOperations(models.Model): + """ + this model used to make operations on budget + """ + _name = 'budget.operations' + _description = 'Budget Operations' + _inherit = ['mail.thread', 'mail.activity.mixin'] + + name = fields.Char(string='Name', default='/') + department_id = fields.Many2one(comodel_name='hr.department', string='Department') + from_crossovered_budget_id = fields.Many2one(comodel_name='crossovered.budget', string='Budget', tracking=True) + from_budget_line_id = fields.Many2one(comodel_name='crossovered.budget.lines', string='Cost Center', tracking=True) + to_crossovered_budget_id = fields.Many2one(comodel_name='crossovered.budget', string='Budget', tracking=True) + to_budget_line_id = fields.Many2one(comodel_name='crossovered.budget.lines', string='Cost Center', tracking=True) + amount = fields.Monetary(string='Amount', tracking=True) + currency_id = fields.Many2one(comodel_name='res.currency', string='Currency', readonly=True, required=True, + default=lambda self: self.env.user.company_id.currency_id.id) + state = fields.Selection(selection=[('draft', 'Draft'), ('confirmed', 'Confirmed')], + default='draft', string='Status', readonly=True, tracking=True) + type = fields.Selection(selection=[('unlock', 'Unlock'), ('transfer', 'Transfer')], default='transfer', + string='type', readonly=True, tracking=True) + date = fields.Date() + from_reserved = fields.Boolean(string='Reserve?', tracking=True) + from_budget_post_id = fields.Many2one(comodel_name='account.budget.post', string='Budget Post', tracking=True) + to_budget_post_id = fields.Many2one(comodel_name='account.budget.post', string='Budget Post', tracking=True) + operation_type = fields.Selection( + selection=[('transfer', 'Transfer'), ('increase', 'Increase'), ('decrease', 'Decrease')], + default='transfer', string='Operation Type', required=True, tracking=True) + purchase_remind = fields.Monetary(string='Purchase Remind', tracking=True) + + @api.onchange('from_crossovered_budget_id', 'operation_type') + def get_budget_domain_year(self): + for rec in self: + domain = [('id', '=', False)] + if rec.operation_type == 'transfer' and rec.from_crossovered_budget_id: + date_to = rec.from_crossovered_budget_id.date_to + record = rec.env['crossovered.budget'].sudo().search([('date_to', '>', str(date_to))]) + if record: + domain = [('id', 'in', record.mapped('crossovered_budget_line.general_budget_id').ids)] + else: + domain = [('id', 'in', rec.env['account.budget.post'].sudo().search([]).ids)] + return {'domain': {'to_budget_post_id': domain}} + + @api.model + def create(self, values): + sequence_code = 'budget_operation.seq' + values['name'] = self.env['ir.sequence'].with_context( + ir_sequence_date=values['date']).next_by_code(sequence_code) + return super(BudgetOperations, self).create(values) + + @api.onchange('operation_type') + def _onchange_operation_type(self): + if self.operation_type == 'increase': + self.from_crossovered_budget_id = False + self.from_budget_line_id = False + self.from_budget_post_id = False + self.from_reserved = False + + @api.onchange('from_budget_post_id') + def _onchange_from_budget_post(self): + domain = [('id', 'in', [])] + if self.from_budget_post_id: + budget_line_obj = self.env['crossovered.budget.lines'] + budget_line = budget_line_obj.read_group([('general_budget_id', '=', self.from_budget_post_id.id)], + ['crossovered_budget_id'], ['crossovered_budget_id']) + domain = [('id', 'in', [bl['crossovered_budget_id'][0] for bl in budget_line])] + self.from_crossovered_budget_id = False + self.from_budget_line_id = False + return {'domain': {'from_crossovered_budget_id': domain}} + + @api.onchange('to_budget_post_id') + def _onchange_to_budget_post(self): + domain = [('id', 'in', [])] + if self.to_budget_post_id: + budget_line_obj = self.env['crossovered.budget.lines'] + search_domain = [('general_budget_id', '=', self.to_budget_post_id.id)] + if self.operation_type == 'transfer' and self.from_crossovered_budget_id: + search_domain += [('date_to', '>', str(self.from_crossovered_budget_id.date_to))] + budget_line = budget_line_obj.search(search_domain) + domain = [('id', 'in', budget_line.mapped('crossovered_budget_id').ids)] + self.to_crossovered_budget_id = False + self.to_budget_line_id = False + return {'domain': {'to_crossovered_budget_id': domain}} + + @api.onchange('from_crossovered_budget_id') + def _onchange_from_crossovered_budget(self): + return { + 'domain': { + 'from_budget_line_id': + [('crossovered_budget_id', '=', self.from_crossovered_budget_id.id), + ('general_budget_id', 'in', [self.from_budget_post_id.id])] + } + } + + @api.onchange('to_crossovered_budget_id') + def _onchange_to_crossovered_budget(self): + return { + 'domain': { + 'to_budget_line_id': + [('crossovered_budget_id', '=', self.to_crossovered_budget_id.id), + ('general_budget_id', 'in', [self.to_budget_post_id.id])] + } + } + + def to_draft(self): + self.state = 'draft' + + def confirm(self): + """ + """ + if self.date and self.to_crossovered_budget_id: + + budget_start_date = self.to_crossovered_budget_id.date_from + budget_end_date = self.to_crossovered_budget_id.date_to + + + if self.date < budget_start_date or self.date > budget_end_date: + raise ValidationError(_('The operation date must be within the budget duration.')) + if self.to_crossovered_budget_id and self.to_crossovered_budget_id.state != 'done': + raise ValidationError( + _('You can transfer to approved budget only')) + self.to_budget_line_id.pull_out = self.purchase_remind + transfer = True if self.operation_type == 'transfer' else False + self.from_budget_line_id._check_amount(self.amount, self.purchase_remind, transfer) + # self.from_budget_line_id.is_transfered = True + if self.type == 'unlock': + self.from_reserved = True + self.to_crossovered_budget_id = self.from_crossovered_budget_id.id + self.to_budget_line_id = self.from_budget_line_id.id + self.state = 'confirmed' diff --git a/odex25_accounting/account_budget_custom/reports/__init__.py b/odex25_accounting/account_budget_custom/reports/__init__.py new file mode 100644 index 000000000..522499f4b --- /dev/null +++ b/odex25_accounting/account_budget_custom/reports/__init__.py @@ -0,0 +1 @@ +from . import budget_report_xlsx diff --git a/odex25_accounting/account_budget_custom/reports/budget_report_xlsx.py b/odex25_accounting/account_budget_custom/reports/budget_report_xlsx.py new file mode 100644 index 000000000..c85bd4e67 --- /dev/null +++ b/odex25_accounting/account_budget_custom/reports/budget_report_xlsx.py @@ -0,0 +1,111 @@ +# -*- coding: utf-8 -*- +from datetime import datetime + +from odoo import models, api, _ +from odoo.exceptions import ValidationError + + +class ReportSponsorPdf(models.AbstractModel): + _name = 'report.account_budget_custom.budget_report' + _description = 'Budget Report' + + @api.model + def get_report_values(self, docids, data=None): + docs = [] + title = _("Budget Lines") + release_date = datetime.now().date() + seq = self.env['ir.actions.report'].get_report_sequence('account_budget_custom.budget_report')['seq'] + + lines = self.env['crossovered.budget.lines'].search([('id', 'in', data['records'])]) + for i in lines: + docs.append({ + 'crossovered_budget_id': i.crossovered_budget_id.id, + 'general_budget_id': i.general_budget_id.id, + 'date_from': datetime.strptime(i.date_from, '%Y-%m-%d %H:%M:%S').date(), + 'date_to': datetime.strptime(i.date_to, '%Y-%m-%d %H:%M:%S').date(), + 'planned_amount': i.planned_amount, + 'practical_amount': i.practical_amount, + 'theoritical_amount': i.theoritical_amount, + 'percentage': i.percentage + }) + + if docs: + return { + 'doc_ids': docids, + 'doc_model': self.env['crossovered.budget.lines'], + 'date': release_date, + 'seq': seq, + 'title': title, + 'docs': docs, + } + else: + raise ValidationError(_("Sorry, No data to Print")) + + def get_result(self, data=None): + res = [] + labels = [ + [_("المـوازنـة"), _("وضع المـوازنـة"), _("تاريخ البدء"), _("تاريخ الإنتهاء"), _("المبلغ المخطط"), + _("المبلغ الفعلى"), _("المبلغ النظرية"), _("الإنجاز")]] + + budget_lines = self.env['crossovered.budget.lines'].search([]) + for i in budget_lines: + res.append({ + 'crossovered_budget_id': i.crossovered_budget_id.name, + 'general_budget_id': i.general_budget_id.name, + 'date_from': i.date_from, + 'date_to': i.date_to, + 'planned_amount': i.planned_amount, + 'practical_amount': i.practical_amount, + 'theoritical_amount': i.theoritical_amount, + 'percentage': i.percentage, + 'labels': labels + }) + return res + + +class InstitutionXlsxReport(models.AbstractModel): + _name = 'report.account_budget_custom.budget_xslx_report' + _inherit = 'report.report_xlsx.abstract' + _description = 'Budget XLSX Report' + + @api.model + def generate_xlsx_report(self, workbook, data, objs): + docs = self.env['report.account_budget_custom.budget_report'].get_result(data) + if docs: + title = _("الموازنات") + sheet = workbook.add_worksheet('الموازنات') + sheet.right_to_left() + format1 = workbook.add_format( + {'bottom': True, 'right': True, 'left': True, 'top': True, 'align': 'center', }) + format2 = workbook.add_format( + {'font_size': 14, 'bottom': True, 'right': True, 'left': True, 'top': True, 'align': 'center', + 'bold': True}) + format5 = workbook.add_format( + {'font_size': 14, 'bottom': True, 'right': True, 'left': True, 'top': True, 'align': 'center', + 'bold': True, 'fg_color': '#dcdcdc'}) + format2.set_align('center') + sheet.set_column('C:L', 15) + row = 10 + i, n, c = 1, 1, 1 + for line in docs: + clm = 2 + for le in line['labels'][0]: + if i > 1: + break + else: + clm += 1 + sheet.write(row, clm, le, format5) + c += 1 + i += 1 + row += 1 + clm = 2 + sheet.write(row, clm + 1, line['crossovered_budget_id'], format1) + sheet.write(row, clm + 2, line['general_budget_id'], format1) + sheet.write(row, clm + 3, line['date_from'], format1) + sheet.write(row, clm + 4, line['date_to'], format1) + sheet.write(row, clm + 5, line['planned_amount'], format1) + sheet.write(row, clm + 6, line['practical_amount'], format1) + sheet.write(row, clm + 7, line['theoritical_amount'], format1) + sheet.write(row, clm + 8, line['percentage'], format1) + + n += 1 diff --git a/odex25_accounting/account_budget_custom/reports/reports.xml b/odex25_accounting/account_budget_custom/reports/reports.xml new file mode 100644 index 000000000..d6d9eb532 --- /dev/null +++ b/odex25_accounting/account_budget_custom/reports/reports.xml @@ -0,0 +1,10 @@ + + + + diff --git a/odex25_accounting/account_budget_custom/security/budget_groups.xml b/odex25_accounting/account_budget_custom/security/budget_groups.xml new file mode 100644 index 000000000..80ba9d059 --- /dev/null +++ b/odex25_accounting/account_budget_custom/security/budget_groups.xml @@ -0,0 +1,26 @@ + + + + + Budget User + + + + + + Budget Department Manager + + + + + + + + Budget Executive Director + + + + + + diff --git a/odex25_accounting/account_budget_custom/security/ir.model.access.csv b/odex25_accounting/account_budget_custom/security/ir.model.access.csv new file mode 100644 index 000000000..943ee9b75 --- /dev/null +++ b/odex25_accounting/account_budget_custom/security/ir.model.access.csv @@ -0,0 +1,9 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_account_budget_confirmation,account.budget.confirmation,model_budget_confirmation,account.group_account_readonly,1,0,0,0 +access_account_budget_confirmation_accountant,account.budget.confirmation accountant,model_budget_confirmation,account.group_account_user,1,1,1,1 +access_account_budget_confirmation_line,account.budget.confirmation.line,model_budget_confirmation_line,account.group_account_readonly,1,0,0,0 +access_account_budget_confirmation_line_accountant,account.budget.confirmation.line accountant,model_budget_confirmation_line,account.group_account_user,1,1,1,1 +access_account_budget_operation,account.budget.operation,model_budget_operations,account.group_account_readonly,1,0,0,0 +access_account_budget_operation_accountant,account.budget.operation accountant,model_budget_operations,account.group_account_user,1,1,1,1 + +access_reject_wizard_user,reject.wizard group_account_user,model_reject_wizard,account.group_account_user,1,1,1,1 \ No newline at end of file diff --git a/odex25_accounting/account_budget_custom/static/description/icon.png b/odex25_accounting/account_budget_custom/static/description/icon.png new file mode 100644 index 000000000..4141f52da Binary files /dev/null and b/odex25_accounting/account_budget_custom/static/description/icon.png differ diff --git a/odex25_accounting/account_budget_custom/static/fonts/ae_AlMohanad.ttf b/odex25_accounting/account_budget_custom/static/fonts/ae_AlMohanad.ttf new file mode 100644 index 000000000..bdd7360e1 Binary files /dev/null and b/odex25_accounting/account_budget_custom/static/fonts/ae_AlMohanad.ttf differ diff --git a/odex25_accounting/account_budget_custom/static/src/css/website_rtl.css b/odex25_accounting/account_budget_custom/static/src/css/website_rtl.css new file mode 100644 index 000000000..85347c670 --- /dev/null +++ b/odex25_accounting/account_budget_custom/static/src/css/website_rtl.css @@ -0,0 +1,22 @@ +@media (min-width: 768px){ + .rtl .navbar-right{ + float: left !important; + } + .rtl .navbar-right .dropdown .dropdown-menu{ + right: auto !important; + left: 0 !important; + } + .rtl .navbar-left{ + float: right !important; + } + .rtl .navbar-left .dropdown .dropdown-menu{ + left: auto !important; + right: 0 !important; + } + .navbar-nav.navbar-right:last-child{ + margin-left: auto; + } + .rtl .pull-left{ + float: right !important; + } +} diff --git a/odex25_accounting/account_budget_custom/views/account_budget_views.xml b/odex25_accounting/account_budget_custom/views/account_budget_views.xml new file mode 100644 index 000000000..285c6ffed --- /dev/null +++ b/odex25_accounting/account_budget_custom/views/account_budget_views.xml @@ -0,0 +1,114 @@ + + + + crossovered.budget.view.inherit.form + crossovered.budget + + + + + + + + + + {'required':True} + + + {'required':True} + + + 1 + + + 1 + + + + + + + + + + + + + + + + + + + +
    + +
    + + - + + +
    + + + + + + + + + + + + + + + + + + + + +
    + + + hr_expense_petty_cash.group_assets_manager + + + hr_expense_petty_cash.group_assets_manager + + + hr_expense_petty_cash.group_assets_manager + + + hr_expense_petty_cash.group_assets_manager + + + + + + + + + + + + + + + +
    + + + +
    +
    +
    +
    + + + account.asset.asset.inherit.kanban + account.asset + 1 + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + + + + + +
    +
    +
    + +
    +
    + + + + + +
    +
    + + + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + + + account.asset.inherit.tree + account.asset + 1 + + + + + + + + + + + + + Assets + account.asset + [('asset_type', '=', 'purchase'), ('state', '!=', 'model'), ('parent_id', '=', False)] + + {'asset_type': 'purchase', 'default_asset_type': 'purchase'} + + + + + + account.asset.pivot + account.asset + + + + + + + + + + + + account.asset.graph + account.asset + + + + + + + + + + + + Assets Analysis + graph,pivot + + account.asset + + + + + account.asset.depreciation.pivot + account.move + + + + + + + + + + + account.asset.graph + account.move + + + + + + + + + + + Depreciation Analysis + graph,pivot + + account.move + [('asset_id', '!=', False)] + +
    diff --git a/odex25_accounting/exp_asset_base/views/asset_modify_views.xml b/odex25_accounting/exp_asset_base/views/asset_modify_views.xml new file mode 100644 index 000000000..905e4d886 --- /dev/null +++ b/odex25_accounting/exp_asset_base/views/asset_modify_views.xml @@ -0,0 +1,81 @@ + + + + + account.asset.modify.tree + account.asset.modify + + + + + + + + + + + + + account.asset.modify.form + account.asset.modify + +
    +
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + +
    +
    + + + +
    +
    +
    +
    + + + Asset Modification + account.asset.modify + tree,form + + + + +
    diff --git a/odex25_accounting/exp_asset_base/views/asset_pause_views.xml b/odex25_accounting/exp_asset_base/views/asset_pause_views.xml new file mode 100644 index 000000000..7efcef39f --- /dev/null +++ b/odex25_accounting/exp_asset_base/views/asset_pause_views.xml @@ -0,0 +1,56 @@ + + + + + asset.pause.tree + asset.pause + + + + + + + + + + + asset.pause.form + asset.pause + +
    +
    +
    + + + + + + + + +
    + + + +
    +
    +
    +
    + + + Asset Pause + asset.pause + tree,form + + + + +
    diff --git a/odex25_accounting/exp_asset_base/views/asset_sell_views.xml b/odex25_accounting/exp_asset_base/views/asset_sell_views.xml new file mode 100644 index 000000000..f3264b72e --- /dev/null +++ b/odex25_accounting/exp_asset_base/views/asset_sell_views.xml @@ -0,0 +1,65 @@ + + + + + asset.sell.tree + asset.sell + + + + + + + + + + + asset.sell.form + asset.sell + +
    +
    +
    + + + + + + + + + + + + + + + + + +
    + + + +
    +
    +
    +
    + + + Asset Sell + asset.sell + tree,form + + + + +
    diff --git a/odex25_accounting/exp_asset_base/views/menus.xml b/odex25_accounting/exp_asset_base/views/menus.xml new file mode 100644 index 000000000..f0fffe2ea --- /dev/null +++ b/odex25_accounting/exp_asset_base/views/menus.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/odex25_accounting/exp_asset_custody/__init__.py b/odex25_accounting/exp_asset_custody/__init__.py new file mode 100644 index 000000000..fca4a5f23 --- /dev/null +++ b/odex25_accounting/exp_asset_custody/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# © Copyright (C) 2021 Expert Co. Ltd() + +from . import models \ No newline at end of file diff --git a/odex25_accounting/exp_asset_custody/__manifest__.py b/odex25_accounting/exp_asset_custody/__manifest__.py new file mode 100644 index 000000000..62cb593a2 --- /dev/null +++ b/odex25_accounting/exp_asset_custody/__manifest__.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# © 2016 ACSONE SA/NV () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +{ + 'name': 'Asset Custody Management', + 'summary': 'Custody Operations for Asset', + 'description': ''' +Manage Assets transfer between locations, departments and employees + ''', + 'version': '1.0.0', + 'category': 'Odex25-Accounting/Odex25-Accounting', + 'author': 'Expert Co. Ltd.', + 'website': 'http://www.exp-sa.com', + 'license': 'AGPL-3', + 'application': False, + 'installable': True, + 'depends': [ + 'exp_asset_base' + ], + 'data': [ + 'data/asset_data.xml', + 'security/ir.model.access.csv', + 'views/account_asset_view.xml', + 'views/account_asset_adjustment_view.xml', + 'views/account_asset_custody_multi_operation.xml', + 'views/account_asset_custody_operation_view.xml', + 'reports/asset_adjustment_report.xml', + 'views/menus.xml' + ], +} diff --git a/odex25_accounting/exp_asset_custody/data/asset_data.xml b/odex25_accounting/exp_asset_custody/data/asset_data.xml new file mode 100644 index 000000000..efe41aa57 --- /dev/null +++ b/odex25_accounting/exp_asset_custody/data/asset_data.xml @@ -0,0 +1,34 @@ + + + + + Asset Operation Sequence + asset.operation.seq + ASS OP/%(range_year)s/ + + + + + 6 + + + Asset Multi Operation Sequence + asset.multi.operation.seq + ASS MOP/%(range_year)s/ + + + + + 6 + + + good + + + scarp + + + available + + + \ No newline at end of file diff --git a/odex25_accounting/exp_asset_custody/i18n/ar.po b/odex25_accounting/exp_asset_custody/i18n/ar.po new file mode 100644 index 000000000..471aba82a --- /dev/null +++ b/odex25_accounting/exp_asset_custody/i18n/ar.po @@ -0,0 +1,878 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * exp_asset_custody +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0+e-20210105\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-05-19 04:38+0000\n" +"PO-Revision-Date: 2021-05-19 04:38+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: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__asset_operation_count +msgid "# Done Operations" +msgstr "العمليات المعتمدة" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_needaction +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_needaction +msgid "Action Needed" +msgstr "إجراء مطلوب" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_ids +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_ids +msgid "Activities" +msgstr "الأنشطة" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_exception_decoration +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_exception_decoration +msgid "Activity Exception Decoration" +msgstr "زخرفة استثناء النشاط" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_state +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_state +msgid "Activity State" +msgstr "حالة النشاط" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_type_icon +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_type_icon +msgid "Activity Type Icon" +msgstr "أيقونة نوع النشاط" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__amount +msgid "Amount" +msgstr "المبلغ" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__asset_id +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search +msgid "Asset" +msgstr "الأصل" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search +msgid "Asset Account" +msgstr "حساب الأصل" + +#. module: exp_asset_custody +#: model:ir.actions.report,name:exp_asset_custody.action_asset_adjustment_report +#: model:ir.model,name:exp_asset_custody.model_account_asset_adjustment +msgid "Asset Adjustment" +msgstr "جرد الأصول" + +#. module: exp_asset_custody +#: model:ir.model,name:exp_asset_custody.model_account_asset_multi_operation +msgid "Asset Multi Operation" +msgstr "العمليات المتعددة" + +#. module: exp_asset_custody +#: code:addons/exp_asset_custody/models/account_asset.py:0 +#, python-format +msgid "Asset Operations" +msgstr "عمليات الأصول" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search +msgid "Asset Operations in done state" +msgstr "العمليات المعتمدة" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__asset_status +msgid "Asset Status" +msgstr "حالة العهد" + +#. module: exp_asset_custody +#: model:ir.model,name:exp_asset_custody.model_account_asset +msgid "Asset/Revenue Recognition" +msgstr "أصل/ إيرادات مقدمة" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report +msgid "Assets Adjustment Report" +msgstr "تقرير جرد الأصول" + +#. module: exp_asset_custody +#: model:ir.actions.act_window,name:exp_asset_custody.action_account_asset_assignment +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_assignment_form +msgid "Assets Assignment" +msgstr "إسناد عهدة" + +#. module: exp_asset_custody +#: model:ir.ui.menu,name:exp_asset_custody.menu_account_asset_operation_main +msgid "Assets Operations" +msgstr "عمليات الأصول" + +#. module: exp_asset_custody +#: model:ir.actions.act_window,name:exp_asset_custody.action_account_asset_release +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form +msgid "Assets Release" +msgstr "إرجاع عهدة" + +#. module: exp_asset_custody +#: model:ir.actions.act_window,name:exp_asset_custody.action_account_asset_transfer +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_transfer_form +msgid "Assets Transfer" +msgstr "نقل العهدة" + +#. module: exp_asset_custody +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset__status__assigned +msgid "Assigned" +msgstr "مسند" + +#. module: exp_asset_custody +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_multi_operation__type__assignment +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__type__assignment +#: model:ir.ui.menu,name:exp_asset_custody.menu_account_asset_assignment +#: model:ir.ui.menu,name:exp_asset_custody.menu_account_multi_asset_assignment +msgid "Assignment" +msgstr "أسناد" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_assignment_form +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form +msgid "Assignment Info" +msgstr "معلومات الإسناد" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_attachment_count +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_attachment_count +msgid "Attachment Count" +msgstr "عدد المرفقات" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__barcode +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__barcode +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search +msgid "Barcode" +msgstr "باركود" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation___barcode_scanned +msgid "Barcode Scanned" +msgstr "باركود" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_assignment_form +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_transfer_form +msgid "Barcode..." +msgstr "الباركود..." + +#. module: exp_asset_custody +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_adjustment__type__department +msgid "By Department" +msgstr "الإدارة" + +#. module: exp_asset_custody +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_adjustment__type__employee +msgid "By Employee" +msgstr "الموظف" + +#. module: exp_asset_custody +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_adjustment__type__location +msgid "By Location" +msgstr "الموقع" + +#. module: exp_asset_custody +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_multi_operation__state__cancel +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__state__cancel +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_assignment_tree +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_release_tree +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_transfer_tree +msgid "Cancel" +msgstr "إلغاء" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_assignment_tree +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_assignment_form +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_transfer_form +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_release_tree +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_transfer_tree +msgid "Confirm" +msgstr "تأكيد" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__create_uid +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__create_uid +msgid "Created by" +msgstr "أنشئ بواسطة" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__create_date +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__create_date +msgid "Created on" +msgstr "أنشئ في" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form +msgid "Current" +msgstr "الحالي" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__department_id +msgid "Current Department" +msgstr "الإدارة الحالية" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__employee_id +msgid "Current Employee" +msgstr "الموظف الحالي" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form +msgid "Current Info" +msgstr "المعلومات الحالية" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_form +msgid "Custody Info" +msgstr "معلومات العهدة" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__custody_period +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__custody_period +msgid "Custody Period" +msgstr "فترة العهدة" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__custody_type +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__custody_type +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_search +msgid "Custody Type" +msgstr "نوع العهدة" + +#. module: exp_asset_custody +#: model:ir.ui.menu,name:exp_asset_custody.menu_account_asset_custody_operation +msgid "Custody operations" +msgstr "عمليات العهد" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__date +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__date +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search +msgid "Date" +msgstr "التاريخ" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report +msgid "Date:" +msgstr "التاريخ:" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_adjustment__department_id +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__new_department_id +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__current_department_id +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__new_department_id +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_search +msgid "Department" +msgstr "الإدارة" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report +msgid "Description:" +msgstr "الوصف:" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__display_name +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_adjustment__display_name +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__display_name +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__display_name +msgid "Display Name" +msgstr "الاسم المعروض" + +#. module: exp_asset_custody +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_multi_operation__state__done +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__state__done +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search +msgid "Done" +msgstr "المنتهية" + +#. module: exp_asset_custody +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_multi_operation__state__draft +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__state__draft +msgid "Draft" +msgstr "مسودة" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_adjustment__employee_id +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__new_employee_id +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__current_employee_id +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__new_employee_id +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_search +msgid "Employee" +msgstr "الموظف" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_follower_ids +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_follower_ids +msgid "Followers" +msgstr "المتابعون" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_channel_ids +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_channel_ids +msgid "Followers (Channels)" +msgstr "المتابعون (القنوات)" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_partner_ids +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_partner_ids +msgid "Followers (Partners)" +msgstr "المتابعون (الشركاء)" + +#. module: exp_asset_custody +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__activity_type_icon +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__activity_type_icon +msgid "Font awesome icon e.g. fa-tasks" +msgstr "" + +#. module: exp_asset_custody +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset__custody_type__general +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__custody_type__general +msgid "General" +msgstr "عام" + +#. module: exp_asset_custody +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__asset_status__good +msgid "Good" +msgstr "جيد" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search +msgid "Group By..." +msgstr "تجميع بـ..." + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__id +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_adjustment__id +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__id +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__id +msgid "ID" +msgstr "المُعرف" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_exception_icon +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_exception_icon +msgid "Icon" +msgstr "الأيقونة" + +#. module: exp_asset_custody +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__activity_exception_icon +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__activity_exception_icon +msgid "Icon to indicate an exception activity." +msgstr "الأيقونة للإشارة إلى استثناء النشاط" + +#. module: exp_asset_custody +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__message_needaction +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__message_unread +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__message_needaction +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__message_unread +msgid "If checked, new messages require your attention." +msgstr "إذا كان محددًا، فهناك رسائل جديدة تحتاج لرؤيتها." + +#. module: exp_asset_custody +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__message_has_error +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__message_has_sms_error +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__message_has_error +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__message_has_sms_error +msgid "If checked, some messages have a delivery error." +msgstr "إذا كان محددًا، فقد حدث خطأ في تسليم بعض الرسائل." + +#. module: exp_asset_custody +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_multi_operation__state__in_progress +msgid "In Progress" +msgstr "جاري" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_is_follower +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_is_follower +msgid "Is Follower" +msgstr "متابع" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset____last_update +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_adjustment____last_update +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation____last_update +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation____last_update +msgid "Last Modified on" +msgstr "آخر تعديل في" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__write_uid +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__write_uid +msgid "Last Updated by" +msgstr "آخر تحديث بواسطة" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__write_date +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__write_date +msgid "Last Updated on" +msgstr "آخر تحديث في" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_adjustment__location_id +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__new_location_id +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__current_location_id +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__new_location_id +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_search +msgid "Location" +msgstr "الموقع" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_main_attachment_id +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_main_attachment_id +msgid "Main Attachment" +msgstr "المرفقات" + +#. module: exp_asset_custody +#: code:addons/exp_asset_custody/models/account_asset_multi_operation.py:0 +#, python-format +msgid "Make sure you choose an asset in all operation line." +msgstr "" + +#. module: exp_asset_custody +#: code:addons/exp_asset_custody/models/account_asset_multi_operation.py:0 +#, python-format +msgid "Make sure you choose custody period for all operation lines." +msgstr "الرجاء التاكد من إدخال فترة العهدة في جميع العمليات." + +#. module: exp_asset_custody +#: code:addons/exp_asset_custody/models/account_asset_multi_operation.py:0 +#, python-format +msgid "Make sure you choose custody type for all operation lines." +msgstr "الرجاء التاكد من إدخال نوع العهدة في جميع العمليات." + +#. module: exp_asset_custody +#: code:addons/exp_asset_custody/models/account_asset_multi_operation.py:0 +#, python-format +msgid "Make sure you enter the return date for all temporary custodies." +msgstr "الرجاء التاكد من إدخال تاريخ الإرجاع للعهد المؤقتة." + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__manual +msgid "Manual" +msgstr "يدوي" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_has_error +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_has_error +msgid "Message Delivery error" +msgstr "خطأ في تسليم الرسائل" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_ids +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_ids +msgid "Messages" +msgstr "الرسائل" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report +msgid "Missing Assets:" +msgstr "الأصول المفقودة:" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__model_id +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search +msgid "Model" +msgstr "النموذج" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__multi_operation_id +msgid "Multi Operation" +msgstr "العمليات المتعددة" + +#. module: exp_asset_custody +#: model:ir.actions.act_window,name:exp_asset_custody.action_multi_asset_assignment +msgid "Multiple Assignment" +msgstr "إسناد العهد" + +#. module: exp_asset_custody +#: model:ir.actions.act_window,name:exp_asset_custody.action_multi_asset_release +msgid "Multiple Release" +msgstr "إرجاع العهد" + +#. module: exp_asset_custody +#: model:ir.actions.act_window,name:exp_asset_custody.action_multi_asset_transfer +msgid "Multiple Transfer" +msgstr "نقل العهد" + +#. module: exp_asset_custody +#: model:ir.ui.menu,name:exp_asset_custody.menu_account_asset_multi_operation +msgid "Multiple operations" +msgstr "العمليات المتعددة" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__name +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__name +msgid "Name" +msgstr "الإسم" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_transfer_form +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form +msgid "New" +msgstr "جديد" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_transfer_tree +msgid "New Department" +msgstr "الإدارة الجديدة" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_transfer_tree +msgid "New Employee" +msgstr "الموظف الجديد" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_transfer_tree +msgid "New Location" +msgstr "الموقع الجديد" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_date_deadline +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_date_deadline +msgid "Next Activity Deadline" +msgstr "الموعد النهائي للنشاط التالي" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_summary +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_summary +msgid "Next Activity Summary" +msgstr "ملخص النشاط التالي" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_type_id +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_type_id +msgid "Next Activity Type" +msgstr "نوع النشاط التالي" + +#. module: exp_asset_custody +#: code:addons/exp_asset_custody/models/account_asset_multi_operation.py:0 +#, python-format +msgid "No asset found with the selected barcode" +msgstr "لم يتم العثور على أصل لهذا الباركود" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__note +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__note +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form +msgid "Note" +msgstr "ملاحظة" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_needaction_counter +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_needaction_counter +msgid "Number of Actions" +msgstr "عدد الإجراءات" + +#. module: exp_asset_custody +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset__asset_operation_count +msgid "Number of done asset operations" +msgstr "" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_has_error_counter +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_has_error_counter +msgid "Number of errors" +msgstr "عدد الاخطاء" + +#. module: exp_asset_custody +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__message_needaction_counter +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__message_needaction_counter +msgid "Number of messages which requires an action" +msgstr "عدد الرسائل التي تتطلب إجراء" + +#. module: exp_asset_custody +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__message_has_error_counter +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "عدد الرسائل الحادث بها خطأ في التسليم" + +#. module: exp_asset_custody +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__message_unread_counter +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__message_unread_counter +msgid "Number of unread messages" +msgstr "عدد الرسائل الجديدة" + +#. module: exp_asset_custody +#: code:addons/exp_asset_custody/models/account_asset_operation.py:0 +#, python-format +msgid "Only draft operations can be deleted." +msgstr "لا يمكن حذف العملية الا في الحالة مبدئية" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__operation_ids +msgid "Operation" +msgstr "عملية" + +#. module: exp_asset_custody +#: model:ir.actions.act_window,name:exp_asset_custody.action_account_asset_operation_analysis +#: model:ir.ui.menu,name:exp_asset_custody.menu_account_operation_graph +msgid "Operation Analysis" +msgstr "تحليل العمليات" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_form +msgid "Operations" +msgstr "العمليات" + +#. module: exp_asset_custody +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__state__pending +msgid "Pending" +msgstr "معلق" + +#. module: exp_asset_custody +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset__custody_period__permanent +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__custody_period__permanent +msgid "Permanent" +msgstr "دائمة" + +#. module: exp_asset_custody +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset__custody_type__personal +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__custody_type__personal +msgid "Personal" +msgstr "شخصية" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__product_id +msgid "Product" +msgstr "المنتج" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__purpose +msgid "Purpose" +msgstr "الغرض" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_assignment_form +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_transfer_form +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form +msgid "Reject" +msgstr "رفض" + +#. module: exp_asset_custody +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_multi_operation__type__release +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__type__release +#: model:ir.ui.menu,name:exp_asset_custody.menu_account_asset_release +#: model:ir.ui.menu,name:exp_asset_custody.menu_account_multi_asset_release +msgid "Release" +msgstr "إرجاع" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form +msgid "Release Info" +msgstr "معلومات الإرجاع" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_release_tree +msgid "Release Location" +msgstr "موقع الإرجاع" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__user_id +msgid "Responsible" +msgstr "المسئول" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__responsible_department_id +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__department_id +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search +msgid "Responsible Department" +msgstr "الإدارة المسئولة" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_user_id +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__responsible_user_id +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_user_id +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search +msgid "Responsible User" +msgstr "الموظف المسئول" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__return_date +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__return_date +msgid "Return Date" +msgstr "تاريخ الإرجاع" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_has_sms_error +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_has_sms_error +msgid "SMS Delivery error" +msgstr "خطأ في تسليم الرسائل القصيرة" + +#. module: exp_asset_custody +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset__status__scrap +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__asset_status__scrap +msgid "Scrap" +msgstr "تالف" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report +msgid "Serial No" +msgstr "المتسلسل" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_assignment_tree +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_assignment_form +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_transfer_form +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_release_tree +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_transfer_tree +msgid "Set to Draft" +msgstr "تعيين كمسودة" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_assignment_tree +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_release_tree +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_transfer_tree +msgid "Setup" +msgstr "الإعداد" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report +msgid "Signatures:" +msgstr "" + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_assignment_form +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_transfer_form +msgid "Start" +msgstr "بدأ" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__state +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__state +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search +msgid "State" +msgstr "الحالة" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__status +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report +msgid "Status" +msgstr "الحالة" + +#. module: exp_asset_custody +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__activity_state +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__activity_state +msgid "" +"Status based on activities\n" +"Overdue: Due date is already passed\n" +"Today: Activity date is today\n" +"Planned: Future activities." +msgstr "الأنشطة المستقبيلة" + +#. module: exp_asset_custody +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__state__submit +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_assignment_tree +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form +msgid "Submit" +msgstr "إرسال" + +#. module: exp_asset_custody +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset__custody_period__temporary +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__custody_period__temporary +msgid "Temporary" +msgstr "مؤقتة" + +#. module: exp_asset_custody +#: code:addons/exp_asset_custody/models/account_asset.py:0 +#, python-format +msgid "The period of %s is finished %s." +msgstr "فترة %s قد إنتهت %s." + +#. module: exp_asset_custody +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_multi_operation__type__transfer +#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__type__transfer +#: model:ir.ui.menu,name:exp_asset_custody.menu_account_asset_transfer +#: model:ir.ui.menu,name:exp_asset_custody.menu_account_multi_asset_transfer +msgid "Transfer" +msgstr "نقل" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_adjustment__type +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__type +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__type +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search +msgid "Type" +msgstr "النوع" + +#. module: exp_asset_custody +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__activity_exception_decoration +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__activity_exception_decoration +msgid "Type of the exception activity on record." +msgstr "نوع النشاط الاستثنائي المسجل." + +#. module: exp_asset_custody +#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report +msgid "Type:" +msgstr "النوع:" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_unread +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_unread +msgid "Unread Messages" +msgstr "الرسائل الجديدة" + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_unread_counter +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_unread_counter +msgid "Unread Messages Counter" +msgstr "عدد الرسائل الجديدة" + +#. module: exp_asset_custody +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation___barcode_scanned +msgid "Value of the last barcode scanned." +msgstr "قيمة آخر باركود ممسوح ضوئيًا." + +#. module: exp_asset_custody +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__website_message_ids +#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__website_message_ids +msgid "Website Messages" +msgstr "رسائل الموقع" + +#. module: exp_asset_custody +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__website_message_ids +#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__website_message_ids +msgid "Website communication history" +msgstr "سجل تواصل الموقع" + +#. module: exp_asset_custody +#: code:addons/exp_asset_custody/models/account_asset_multi_operation.py:0 +#, python-format +msgid "You can not confirm operation without lines." +msgstr "لا يمكن تأكيد العملية دون إدخال التفاصيل" + +#. module: exp_asset_custody +#: model:ir.model,name:exp_asset_custody.model_account_asset_operation +msgid "account.asset.operation" +msgstr "" diff --git a/odex25_accounting/exp_asset_custody/models/__init__.py b/odex25_accounting/exp_asset_custody/models/__init__.py new file mode 100644 index 000000000..0cdea784a --- /dev/null +++ b/odex25_accounting/exp_asset_custody/models/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +# © Copyright (C) 2021 Expert Co. Ltd() + +from . import account_asset +from . import account_asset_operation +from . import account_asset_adjustment +from . import account_asset_multi_operation \ No newline at end of file diff --git a/odex25_accounting/exp_asset_custody/models/account_asset.py b/odex25_accounting/exp_asset_custody/models/account_asset.py new file mode 100644 index 000000000..0b946b9f4 --- /dev/null +++ b/odex25_accounting/exp_asset_custody/models/account_asset.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +# © Copyright (C) 2021 Expert Co. Ltd() + +from odoo import models, fields, api, _ + + +class AccountAssetAsset(models.Model): + _inherit = 'account.asset' + + custody_type = fields.Selection( + selection=[('personal', 'Personal'), ('general', 'General')], + ) + custody_period = fields.Selection( + selection=[('temporary', 'Temporary'), ('permanent', 'Permanent')], + ) + purpose = fields.Html() + return_date = fields.Date() + department_id = fields.Many2one( + comodel_name='hr.department', + string='Current Department' + ) + employee_id = fields.Many2one( + comodel_name='hr.employee', + string='Current Employee' + ) + status = fields.Selection( + selection_add=[('assigned', 'Assigned'), ('scrap', 'Scrap')] + ) + asset_operation_count = fields.Integer( + compute='_asset_operation_count', + string='# Done Operations', + help="Number of done asset operations" + ) + + def _asset_operation_count(self): + for asset in self: + asset.asset_operation_count = len( + self.env['account.asset.operation'].search([('asset_id', '=', asset.id), ('state', '=', 'done')])) + + def open_asset_operation(self): + return { + 'name': _('Asset Operations'), + 'view_type': 'form', + 'view_mode': 'tree,form', + 'res_model': 'account.asset.operation', + 'type': 'ir.actions.act_window', + 'domain': [('asset_id', '=', self.id)], + 'view_id': self.env.ref('exp_asset_custody.view_account_asset_operation_tree').id, + 'views': [(self.env.ref('exp_asset_custody.view_account_asset_operation_tree').id, 'tree'), + (self.env.ref('exp_asset_custody.view_account_asset_operation_form').id, 'form')], + 'context': {'active_model': False, 'search_default_done': True}, + 'flags': {'search_view': True, 'action_buttons': False}, + } + + @api.model + def _asset_cron(self): + super(AccountAssetAsset, self)._asset_cron() + today = fields.Date.today() + for asset in self.search([('return_date', '=', today)]): + self.env['mail.activity'].sudo().create({ + 'res_model_id': self.env.ref('account_asset.model_account_asset_asset').id, + 'res_id': asset.id, + 'user_id': asset.responsible_user_id.id, + 'activity_type_id': self.env.ref('mail.mail_activity_data_todo').id, + 'summary': _('The period of %s is finished %s.') % (asset.name, asset.return_date), + 'date_deadline': asset.return_date, + }) \ No newline at end of file diff --git a/odex25_accounting/exp_asset_custody/models/account_asset_adjustment.py b/odex25_accounting/exp_asset_custody/models/account_asset_adjustment.py new file mode 100644 index 000000000..3978758f4 --- /dev/null +++ b/odex25_accounting/exp_asset_custody/models/account_asset_adjustment.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# © Copyright (C) 2021 Expert Co. Ltd() + +from odoo import api, fields, models, exceptions, _ + + +class AccountAssetAdjustment(models.Model): + _inherit = 'account.asset.adjustment' + + type = fields.Selection( + selection_add=[('department', 'By Department'), + ('employee', 'By Employee'), + ('location', 'By Location')], + states={'draft': [('readonly', False)]}, + readonly=True, + ) + department_id = fields.Many2one( + comodel_name='hr.department', + states={'draft': [('readonly', False)]}, + readonly=True, + ) + employee_id = fields.Many2one( + comodel_name='hr.employee', + states={'draft': [('readonly', False)]}, + readonly=True, + ) + location_id = fields.Many2one( + comodel_name='account.asset.location', + states={'draft': [('readonly', False)]}, + readonly=True, + ) + + def build_domain(self): + return self.type == 'employee' and [('employee_id', '=', self.employee_id.id)] or \ + (self.type == 'department' and [('department_id', '=', self.department_id.id)]) or \ + (self.type == 'location' and [('location_id', '=', self.location_id.id)]) or \ + super(AccountAssetAdjustment, self).build_domain() + + @api.onchange('type') + def onchange_type(self): + self.employee_id = False + self.department_id = False + self.location_id = False + super(AccountAssetAdjustment, self).onchange_type() diff --git a/odex25_accounting/exp_asset_custody/models/account_asset_multi_operation.py b/odex25_accounting/exp_asset_custody/models/account_asset_multi_operation.py new file mode 100644 index 000000000..2d45e740a --- /dev/null +++ b/odex25_accounting/exp_asset_custody/models/account_asset_multi_operation.py @@ -0,0 +1,150 @@ +# -*- coding: utf-8 -*- +# © Copyright (C) 2021 Expert Co. Ltd() + +from odoo import models, fields, api, exceptions, _ + +class AccountAssetMultiOperation(models.Model): + _name = 'account.asset.multi.operation' + _description = 'Asset Multi Operation' + _inherit = ['mail.thread', 'mail.activity.mixin', 'barcodes.barcode_events_mixin'] + + name = fields.Char( + states={'draft': [('readonly', False)]}, + default='/', readonly=True + ) + date = fields.Date( + default=fields.Date.context_today, + index=True, copy=False, readonly=True, required=True, + states={'draft': [('readonly', False)]} + ) + type = fields.Selection( + selection=[('assignment', 'Assignment'), + ('release', 'Release'), + ('transfer', 'Transfer')], + states={'draft': [('readonly', False)]}, + readonly=True, required=True + ) + barcode = fields.Char( + states={'in_progress': [('readonly', False)]}, + readonly=True, + ) + responsible_user_id = fields.Many2one( + comodel_name='res.users', + default=lambda self: self.env.user, + states={'draft': [('readonly', False)]}, + readonly=True, required=True + ) + responsible_department_id = fields.Many2one( + comodel_name='hr.department', + ) + new_employee_id = fields.Many2one( + comodel_name='hr.employee', + states={'draft': [('readonly', False)]}, + readonly=True, string='Employee', + ) + new_department_id = fields.Many2one( + comodel_name='hr.department', + states={'draft': [('readonly', False)]}, + readonly=True, string='Department', + ) + new_location_id = fields.Many2one( + comodel_name='account.asset.location', + states={'draft': [('readonly', False)]}, + readonly=True, string='Location', + ) + manual = fields.Boolean() + note = fields.Text( + states={'draft': [('readonly', False)]}, + readonly=True, required=True + ) + state = fields.Selection( + selection=[('draft', 'Draft'), + ('in_progress', 'In Progress'), + ('done', 'Done'), + ('cancel', 'Cancel')], + required=True, default='draft' + ) + operation_ids = fields.One2many( + 'account.asset.operation', 'multi_operation_id', + states={'in_progress': [('readonly', False)]}, + readonly=False, + ) + + @api.model + def create(self, values): + values['name'] = self.env['ir.sequence'].with_context( + ir_sequence_date=values['date']).next_by_code('asset.multi.operation.seq') + return super(AccountAssetMultiOperation, self).create(values) + + def act_progress(self): + self.state = 'in_progress' + + def act_confirm(self): + if not self.operation_ids: + raise exceptions.Warning(_('You can not confirm operation without lines.')) + for opt in self.operation_ids: + self.check_required_fields(opt) + opt.act_confirm() + self.state = 'done' + + def act_reject(self): + self.state = 'cancel' + + def act_draft(self): + self.state = 'draft' + + def get_asset_domain(self): + if self.type == 'assignment': + return [('status', 'in', ['new','available'])] + elif self.type in ['transfer', 'release']: + return [('status', 'in', ['assigned'])] + return [('status', 'in', ['new', 'available', 'assigned', 'scrap'])] + + @api.onchange('new_employee_id') + def onchange_new_employee(self): + self.new_department_id = self.new_employee_id.department_id.id + + @api.onchange('barcode') + def onchange_barcode(self): + self.on_barcode_scanned(self.barcode) + + def on_barcode_scanned(self, barcode): + if barcode: + operation_vals = self.get_operation_vals() + domain = self.get_asset_domain() + assets = self.barcode and self.env['account.asset'].search(domain + [('barcode', '=', barcode)]) + self.barcode = False + if not assets: + raise exceptions.Warning(_('No asset found with the selected barcode')) + for s in assets: + operation_vals.update({ + 'asset_id': s.id, + 'current_employee_id': s.employee_id.id, + 'current_department_id': s.department_id.id, + 'current_location_id': s.location_id.id, + #'state': 'submit', + }) + self.operation_ids = [(0, 0, operation_vals)] + + def get_operation_vals(self): + return { + 'state': 'draft', + 'type': self.type, + 'date': self.date, + 'note': self.note, + 'multi_operation_id': self.id, + 'user_id': self.responsible_user_id.id, + 'new_employee_id': self.new_employee_id.id, + 'new_department_id': self.new_department_id.id, + 'new_location_id': self.new_location_id.id, + } + + def check_required_fields(self, operation): + if not operation.asset_id: + raise exceptions.Warning(_('Make sure you choose an asset in all operation line.')) + elif not operation.return_date and operation.custody_period == 'temporary': + raise exceptions.Warning(_('Make sure you enter the return date for all temporary custodies.')) + elif not operation.custody_type and operation.type in ['assignment', 'transfer']: + raise exceptions.Warning(_('Make sure you choose custody type for all operation lines.')) + elif not operation.custody_period and operation.type in ['assignment', 'transfer']: + raise exceptions.Warning(_('Make sure you choose custody period for all operation lines.')) \ No newline at end of file diff --git a/odex25_accounting/exp_asset_custody/models/account_asset_operation.py b/odex25_accounting/exp_asset_custody/models/account_asset_operation.py new file mode 100644 index 000000000..8cca74dfa --- /dev/null +++ b/odex25_accounting/exp_asset_custody/models/account_asset_operation.py @@ -0,0 +1,150 @@ +# -*- coding: utf-8 -*- +# © Copyright (C) 2021 Expert Co. Ltd() + +from odoo import models, fields, api, exceptions, _ + + +class AccountAssetOperation(models.Model): + _name = 'account.asset.operation' + _description = 'Asset Operation' + _inherit = ['mail.thread', 'mail.activity.mixin'] + + multi_operation_id = fields.Many2one(comodel_name='account.asset.multi.operation') + name = fields.Char(required=True, default='/') + type = fields.Selection(selection=[('assignment', 'Assignment'), ('release', 'Release'), + ('transfer', 'Transfer')], required=True) + date = fields.Date(default=fields.Date.context_today, index=True, copy=False, readonly=True, required=True, + states={'draft': [('readonly', False)]}) + user_id = fields.Many2one(comodel_name='res.users',default=lambda self: self.env.user, + states={'draft': [('readonly', False)]},string='Responsible',readonly=True) + asset_id = fields.Many2one(comodel_name='account.asset') + statea = fields.Selection(related='asset_id.status') + barcode = fields.Char(compute="_compute_related_fields", store=True) + department_id = fields.Many2one(comodel_name='hr.department',string='Responsible Department', + compute="_compute_related_fields", store=True) + model_id = fields.Many2one(comodel_name='account.asset',compute="_compute_related_fields",store=True) + state = fields.Selection(selection=[('draft', 'Draft'),('submit', 'Submit'),('done', 'Done'),('pending', 'Pending') + ,('cancel', 'Cancel')],required=True, default='draft') + note = fields.Text(states={'draft': [('readonly', False)]},readonly=True,) + # Asset Custody Operation + custody_type = fields.Selection(selection=[('personal', 'Personal'), ('general', 'General')], + states={'draft': [('readonly', False)]},readonly=True,) + custody_period = fields.Selection(selection=[('temporary', 'Temporary'), ('permanent', 'Permanent')], + states={'draft': [('readonly', False)]},readonly=True) + return_date = fields.Date(states={'draft': [('readonly', False)]},readonly=True) + current_employee_id = fields.Many2one(comodel_name='hr.employee', + states={'draft': [('readonly', False)]},readonly=True, string='Employee') + current_department_id = fields.Many2one(comodel_name='hr.department',states={'draft': [('readonly', False)]}, + readonly=True, string='Department', ) + current_location_id = fields.Many2one(comodel_name='account.asset.location',states={'draft': [('readonly', False)]}, + readonly=True, string='Location') + new_employee_id = fields.Many2one(comodel_name='hr.employee', string='Employee') + new_department_id = fields.Many2one(comodel_name='hr.department', string='Department', ) + new_location_id = fields.Many2one(comodel_name='account.asset.location', string='Location') + amount = fields.Float(states={'draft': [('readonly', False)]}, readonly=True, ) + asset_status = fields.Selection(selection=[('good', 'Good'), ('scrap', 'Scrap')], + states={'draft': [('readonly', False)]}, readonly=True, ) + asset_statuso = fields.Selection(related='asset_id.status') + asset_status2 = fields.Many2one( + comodel_name='asset.states', + string='Asset Status',states={'draft': [('readonly', False)]}) + product_id = fields.Many2one(comodel_name='product.product', + domain=[('property_account_expense_id.can_create_asset', '=', True), + ('property_account_expense_id.user_type_id.internal_group', '=', 'asset')], + states={'draft': [('readonly', False)]}, readonly=True) + + def action_read_operation(self): + self.ensure_one() + return { + 'name': self.display_name, + 'type': 'ir.actions.act_window', + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': 'account.asset.operation', + 'res_id': self.id, + } + + @api.depends('asset_id', 'asset_id.model_id', 'asset_id.responsible_dept_id', 'asset_id.barcode') + def _compute_related_fields(self): + for operation in self: + operation.barcode = operation.asset_id.barcode + operation.model_id = operation.asset_id.model_id.id + operation.department_id = operation.asset_id.responsible_dept_id.id + + @api.model + def create(self, values): + values['name'] = self.env['ir.sequence'].with_context( + ir_sequence_date=values['date']).next_by_code('asset.operation.seq') + return super(AccountAssetOperation, self).create(values) + + def unlink(self): + if self.search([('state', '!=', 'draft'), ('id', 'in', self.ids)]): + raise exceptions.Warning(_('Only draft operations can be deleted.')) + return super(AccountAssetOperation, self).unlink() + + @api.model + def _get_tracked_fields(self): + fields = self.fields_get() + dels = [f for f in fields if f in models.LOG_ACCESS_COLUMNS or f.startswith('_') or f == 'id'] + for x in dels: + del fields[x] + return set(fields) + + @api.onchange('new_employee_id') + def onchange_new_employee(self): + self.new_department_id = self.new_employee_id.department_id.id + + @api.onchange('asset_id') + def onchange_asset(self): + self.current_employee_id = self.asset_id.employee_id.id + self.current_department_id = self.asset_id.department_id.id + self.current_location_id = self.asset_id.location_id.id + + def act_submit(self): + self.state = 'submit' + + def act_confirm(self): + if not self.asset_id: + raise exceptions.Warning(_('Asset is required to confirm this operation.')) + if self.type in ('assignment', 'release', 'transfer'): + self.custody_confirm() + self.state = 'done' + + def act_reject(self): + self.state = 'pending' + + def act_cancel(self): + self.state = 'cancel' + + def act_draft(self): + self.state = 'draft' + + def custody_confirm(self): + self.asset_id.employee_id = self.new_employee_id.id + self.asset_id.department_id = self.new_department_id.id + self.asset_id.location_id = self.new_location_id.id + self.asset_id.custody_type = self.custody_type + self.asset_id.custody_period = self.custody_period + self.asset_id.return_date = self.return_date + self.asset_id.purpose = self.note + if self.type == 'assignment': + self.asset_id.status = 'assigned' + elif self.type == 'release': + self.asset_id.status = 'available' + + +""" + def sell_dispose_confirm(self): + super(AccountAssetOperation, self).sell_dispose_confirm() + self.asset_id.custody_type = False + self.asset_id.custody_period = False + self.asset_id.purpose = False + self.asset_id.return_date = False + self.asset_id.department_id = False + self.asset_id.employee_id = False + self.asset_id.location_id = False + self.asset_id.status = False + """ +class AccountAssestatus(models.Model): + _name = 'asset.states' + name = fields.Char(string='Name') diff --git a/odex25_accounting/exp_asset_custody/reports/asset_adjustment_report.xml b/odex25_accounting/exp_asset_custody/reports/asset_adjustment_report.xml new file mode 100644 index 000000000..a73e10d91 --- /dev/null +++ b/odex25_accounting/exp_asset_custody/reports/asset_adjustment_report.xml @@ -0,0 +1,232 @@ + + + + + \ No newline at end of file diff --git a/odex25_accounting/exp_asset_custody/security/ir.model.access.csv b/odex25_accounting/exp_asset_custody/security/ir.model.access.csv new file mode 100644 index 000000000..9e08178dc --- /dev/null +++ b/odex25_accounting/exp_asset_custody/security/ir.model.access.csv @@ -0,0 +1,6 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_asset_operation,account.asset.operation,model_account_asset_operation,account.group_account_readonly,1,0,0,0 +access_asset_operation_manager,account.asset.operation,model_account_asset_operation,account.group_account_manager,1,1,1,1 +access_asset_multi_operation,account.asset.multi.operation,model_account_asset_multi_operation,account.group_account_readonly,1,0,0,0 +access_asset_multi_operation_manager,account.asset.multi.operation,model_account_asset_multi_operation,account.group_account_manager,1,1,1,1 +access_asset_state_operation_manager,account.state.multi.operation,model_asset_states,,1,1,1,1 \ No newline at end of file diff --git a/odex25_accounting/exp_asset_custody/static/description/icon.png b/odex25_accounting/exp_asset_custody/static/description/icon.png new file mode 100644 index 000000000..4141f52da Binary files /dev/null and b/odex25_accounting/exp_asset_custody/static/description/icon.png differ diff --git a/odex25_accounting/exp_asset_custody/views/account_asset_adjustment_view.xml b/odex25_accounting/exp_asset_custody/views/account_asset_adjustment_view.xml new file mode 100644 index 000000000..4434ce1ef --- /dev/null +++ b/odex25_accounting/exp_asset_custody/views/account_asset_adjustment_view.xml @@ -0,0 +1,21 @@ + + + + account.asset.adjustment.form + account.asset.adjustment + + + + + + + + + + \ No newline at end of file diff --git a/odex25_accounting/exp_asset_custody/views/account_asset_custody_multi_operation.xml b/odex25_accounting/exp_asset_custody/views/account_asset_custody_multi_operation.xml new file mode 100644 index 000000000..a177258fc --- /dev/null +++ b/odex25_accounting/exp_asset_custody/views/account_asset_custody_multi_operation.xml @@ -0,0 +1,285 @@ + + + + + account.asset.multi.operation.tree + account.asset.multi.operation + + + + + + + + + + + + + + account.asset.multi.assignment.form + account.asset.multi.operation + +
    +
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    +
    +
    +
    + + + account.asset.multi.release.form + account.asset.multi.operation + +
    +
    +
    + +
    +

    + + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    +
    +
    +
    + + + account.asset.multi.transfer.form + account.asset.multi.operation + +
    +
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    +
    +
    +
    + + + Multiple Assignment + account.asset.multi.operation + tree,form + {'default_manual':1, 'default_type':'assignment'} + [('type','=','assignment')] + + + + Multiple Release + account.asset.multi.operation + tree,form + {'default_manual':1, 'default_type':'release'} + [('type','=','release')] + + + + Multiple Transfer + account.asset.multi.operation + tree,form + {'default_manual':1, 'default_type':'transfer'} + [('type','=','transfer')] + + +
    \ No newline at end of file diff --git a/odex25_accounting/exp_asset_custody/views/account_asset_custody_operation_view.xml b/odex25_accounting/exp_asset_custody/views/account_asset_custody_operation_view.xml new file mode 100644 index 000000000..a1d2d700c --- /dev/null +++ b/odex25_accounting/exp_asset_custody/views/account_asset_custody_operation_view.xml @@ -0,0 +1,326 @@ + + + + + + account.asset.operation.search + account.asset.operation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + account.asset.operation.tree + account.asset.operation + + + + + + + + + + + + + + account.asset.operation.form + account.asset.operation + +
    +
    +
    + +
    +

    + + - + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    +
    +
    +
    + + + + account.asset.assignment.tree + account.asset.operation + + + + + + + + + + + + + + + + + + + + + + + + Assets Assignment + account.asset.operation + tree,form + + + {'default_type': 'assignment', 'default_custody_type': 'personal', 'default_custody_period': 'permanent'} + + [('type', '=', 'assignment')] + + + + account.asset.release.tree + account.asset.operation + + + + + + + + + + + + + + + + + + + + + + Assets Release + account.asset.operation + tree,form + + {'default_type': 'release'} + [('type', '=', 'release')] + + + + account.asset.transfer.tree + account.asset.operation + + + + + + + + + + + + + + + + + + + + + + + + + Assets Transfer + account.asset.operation + tree,form + + {'default_type': 'transfer'} + [('type', '=', 'transfer')] + + + + + + Operation Analysis + graph,pivot,tree + + + account.asset.operation + {'search_default_group_by_type': True} + + + asset_operation_form3.extend + account.asset.multi.operation + + + + hr_expense_petty_cash.group_assets_manager + + + hr_expense_petty_cash.group_assets_manager + + + hr_expense_petty_cash.group_assets_manager + + + + + asset_operation_form5.extend + account.asset.operation + + + + hr_expense_petty_cash.group_assets_manager + + + hr_expense_petty_cash.group_assets_manager + + + hr_expense_petty_cash.group_assets_manager + + + + +
    diff --git a/odex25_accounting/exp_asset_custody/views/account_asset_view.xml b/odex25_accounting/exp_asset_custody/views/account_asset_view.xml new file mode 100644 index 000000000..4382e0657 --- /dev/null +++ b/odex25_accounting/exp_asset_custody/views/account_asset_view.xml @@ -0,0 +1,51 @@ + + + + + account.asset.search + account.asset + + + + + + + + + + + + + + + + + account.asset.form + account.asset + + +
    + +
    + + + + + + + + + + + + + + + + +
    +
    + +
    diff --git a/odex25_accounting/exp_asset_custody/views/menus.xml b/odex25_accounting/exp_asset_custody/views/menus.xml new file mode 100644 index 000000000..d1c4ed7f8 --- /dev/null +++ b/odex25_accounting/exp_asset_custody/views/menus.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + diff --git a/odex25_accounting/exp_asset_custody_link/__init__.py b/odex25_accounting/exp_asset_custody_link/__init__.py new file mode 100644 index 000000000..5305644df --- /dev/null +++ b/odex25_accounting/exp_asset_custody_link/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import models \ No newline at end of file diff --git a/odex25_accounting/exp_asset_custody_link/__manifest__.py b/odex25_accounting/exp_asset_custody_link/__manifest__.py new file mode 100644 index 000000000..c1ee0a913 --- /dev/null +++ b/odex25_accounting/exp_asset_custody_link/__manifest__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +{ + 'name': "HR Custody Integration With Asset Custody", + + 'summary': """ + - Assign Asset as a custody to an employee + - Release Asset as a custody from an employee + """, + 'version': '14.0', + 'sequence': 4, + 'category': 'Odex25-Accounting/Odex25-Accounting', + 'website': 'http://exp-sa.com', + 'license': 'AGPL-3', + 'author': 'Expert Co. Ltd.', + 'depends': ['exp_employee_custody','exp_asset_custody','purchase'], + + # always loaded + 'data': [ + 'security/ir.model.access.csv', + 'views/employee_custody_action.xml', + ], + +} diff --git a/odex25_accounting/exp_asset_custody_link/i18n/ar_001.po b/odex25_accounting/exp_asset_custody_link/i18n/ar_001.po new file mode 100644 index 000000000..9468ab608 --- /dev/null +++ b/odex25_accounting/exp_asset_custody_link/i18n/ar_001.po @@ -0,0 +1,266 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * exp_asset_custody_link +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-01-31 13:21+0000\n" +"PO-Revision-Date: 2023-01-31 13:21+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: exp_asset_custody_link +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_asset_custody_line__asset_id +msgid "Asset" +msgstr "الأصل" + +#. module: exp_asset_custody_link +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_custom_employee_custody__asset_assign_count +msgid "Asset Assignment" +msgstr "إسناد أصل" + +#. module: exp_asset_custody_link +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_asset_custody_line__asset_custody_line +msgid "Asset Custody Line" +msgstr "بند أصل" + +#. module: exp_asset_custody_link +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_custom_employee_custody__asset_line_ids +msgid "Asset Line" +msgstr "بند الأصول" + +#. module: exp_asset_custody_link +#: model_terms:ir.ui.view,arch_db:exp_asset_custody_link.employee_custody_form_view_inherit +msgid "Asset Lines" +msgstr "بند الأصول" + +#. module: exp_asset_custody_link +#: model:ir.model,name:exp_asset_custody_link.model_account_asset_operation +msgid "Asset Operation" +msgstr "عمليات الأصول" + +#. module: exp_asset_custody_link +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_custom_employee_custody__asset_release_count +msgid "Asset Release" +msgstr "إرجاع عهدة" + +#. module: exp_asset_custody_link +#: code:addons/exp_asset_custody_link/models/account_asset_operation.py:0 +#, python-format +msgid "Asset is required to confirm this operation." +msgstr "الأصل مطلوب لتأكيد هذه العملية" + +#. module: exp_asset_custody_link +#: model:ir.actions.act_window,name:exp_asset_custody_link.action_account_asset_assignment1 +msgid "Assets Assignment" +msgstr "إسناد عهدة" + +#. module: exp_asset_custody_link +#: model:ir.actions.act_window,name:exp_asset_custody_link.action_account_asset_release1 +msgid "Assets Release" +msgstr "إرجاع عهدة" + +#. module: exp_asset_custody_link +#: code:addons/exp_asset_custody_link/models/employee_custody.py:0 +#: model:ir.model.fields.selection,name:exp_asset_custody_link.selection__asset_custody_line__type__assignment +#: model:ir.model.fields.selection,name:exp_asset_custody_link.selection__custom_employee_custody__state__assign +#, python-format +msgid "Assignment" +msgstr "إسناد" + +#. module: exp_asset_custody_link +#: model_terms:ir.ui.view,arch_db:exp_asset_custody_link.employee_custody_form_view_inherit +msgid "Assignments" +msgstr "الإسناد" + +#. module: exp_asset_custody_link +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_asset_custody_line__create_uid +msgid "Created by" +msgstr "" + +#. module: exp_asset_custody_link +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_asset_custody_line__create_date +msgid "Created on" +msgstr "" + +#. module: exp_asset_custody_link +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_asset_custody_line__custody_period +msgid "Custody Period" +msgstr "فترة العهدة" + +#. module: exp_asset_custody_link +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_asset_custody_line__custody_type +msgid "Custody Type" +msgstr "نوع العهدة" + +#. module: exp_asset_custody_link +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_asset_custody_line__date +msgid "Date" +msgstr "التاريخ" + +#. module: exp_asset_custody_link +#: code:addons/exp_asset_custody_link/models/employee_custody.py:0 +#: model:ir.model.fields.selection,name:exp_asset_custody_link.selection__custom_employee_custody__state__direct +#, python-format +msgid "Direct Manager" +msgstr "المدير المباشر" + +#. module: exp_asset_custody_link +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_account_asset_operation__display_name +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_asset_custody_line__display_name +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_custom_employee_custody__display_name +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_mail_followers__display_name +msgid "Display Name" +msgstr "الاسم المعروض" + +#. module: exp_asset_custody_link +#: model:ir.model,name:exp_asset_custody_link.model_mail_followers +msgid "Document Followers" +msgstr "متابعو المستند" + +#. module: exp_asset_custody_link +#: code:addons/exp_asset_custody_link/models/employee_custody.py:0 +#: model:ir.model.fields.selection,name:exp_asset_custody_link.selection__custom_employee_custody__state__draft +#, python-format +msgid "Draft" +msgstr "مسودة" + +#. module: exp_asset_custody_link +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_account_asset_operation__emp_asset_custody_id +msgid "Emp Asset Custody" +msgstr "" + +#. module: exp_asset_custody_link +#: model:ir.model,name:exp_asset_custody_link.model_custom_employee_custody +msgid "Employee custody" +msgstr "العهد الغير مالية" + +#. module: exp_asset_custody_link +#: model:ir.model.fields.selection,name:exp_asset_custody_link.selection__asset_custody_line__custody_type__general +msgid "General" +msgstr "عام" + +#. module: exp_asset_custody_link +#: code:addons/exp_asset_custody_link/models/employee_custody.py:0 +#: model:ir.model.fields.selection,name:exp_asset_custody_link.selection__custom_employee_custody__state__admin +#, python-format +msgid "Human Resources Manager" +msgstr "تصديق الموارد البشرية" + +#. module: exp_asset_custody_link +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_account_asset_operation__id +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_asset_custody_line__id +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_custom_employee_custody__id +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_mail_followers__id +msgid "ID" +msgstr "المُعرف" + +#. module: exp_asset_custody_link +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_account_asset_operation____last_update +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_asset_custody_line____last_update +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_custom_employee_custody____last_update +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_mail_followers____last_update +msgid "Last Modified on" +msgstr "آخر تعديل في" + +#. module: exp_asset_custody_link +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_asset_custody_line__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: exp_asset_custody_link +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_asset_custody_line__write_date +msgid "Last Updated on" +msgstr "" + +#. module: exp_asset_custody_link +#: model:ir.model.fields.selection,name:exp_asset_custody_link.selection__asset_custody_line__custody_period__permanent +msgid "Permanent" +msgstr "مستديمة" + +#. module: exp_asset_custody_link +#: model:ir.model.fields.selection,name:exp_asset_custody_link.selection__asset_custody_line__custody_type__personal +msgid "Personal" +msgstr "شخصية" + +#. module: exp_asset_custody_link +#: code:addons/exp_asset_custody_link/models/employee_custody.py:0 +#, python-format +msgid "Please Select an asset" +msgstr "الرجاء إختيار أصل" + +#. module: exp_asset_custody_link +#: model_terms:ir.ui.view,arch_db:exp_asset_custody_link.employee_custody_form_view_inherit +msgid "Purchase Request" +msgstr "طلب شراء" + +#. module: exp_asset_custody_link +#: code:addons/exp_asset_custody_link/models/employee_custody.py:0 +#: model:ir.model.fields.selection,name:exp_asset_custody_link.selection__custom_employee_custody__state__refuse +#, python-format +msgid "Refuse" +msgstr "رفض" + +#. module: exp_asset_custody_link +#: model_terms:ir.ui.view,arch_db:exp_asset_custody_link.employee_custody_form_view_inherit +msgid "Releases" +msgstr "رفض" + +#. module: exp_asset_custody_link +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_asset_custody_line__return_date +msgid "Return Date" +msgstr "تاريخ الإرجاع" + +#. module: exp_asset_custody_link +#: code:addons/exp_asset_custody_link/models/employee_custody.py:0 +#: model:ir.model.fields.selection,name:exp_asset_custody_link.selection__custom_employee_custody__state__done +#, python-format +msgid "Return Done" +msgstr "تم ارجاع العهده" + +#. module: exp_asset_custody_link +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_custom_employee_custody__state +msgid "State" +msgstr "الحالة" + +#. module: exp_asset_custody_link +#: model:ir.model.fields.selection,name:exp_asset_custody_link.selection__asset_custody_line__custody_period__temporary +msgid "Temporary" +msgstr "موقتة" + +#. module: exp_asset_custody_link +#: model:ir.model.fields,field_description:exp_asset_custody_link.field_asset_custody_line__type +msgid "Type" +msgstr "النوع" + +#. module: exp_asset_custody_link +#: code:addons/exp_asset_custody_link/models/employee_custody.py:0 +#: model:ir.model.fields.selection,name:exp_asset_custody_link.selection__custom_employee_custody__state__wait +#, python-format +msgid "Wait Assignment" +msgstr "إنتظار الإرجاع" + +#. module: exp_asset_custody_link +#: code:addons/exp_asset_custody_link/models/employee_custody.py:0 +#: model:ir.model.fields.selection,name:exp_asset_custody_link.selection__custom_employee_custody__state__wait_release +#, python-format +msgid "Wait Release" +msgstr "إنتظار الإسناد" + +#. module: exp_asset_custody_link +#: model:ir.model,name:exp_asset_custody_link.model_asset_custody_line +msgid "asset.custody.line" +msgstr "" + +#. module: exp_asset_custody_link +#: code:addons/exp_asset_custody_link/models/employee_custody.py:0 +#: model:ir.model.fields.selection,name:exp_asset_custody_link.selection__custom_employee_custody__state__submit +#, python-format +msgid "send" +msgstr "إرسال" diff --git a/odex25_accounting/exp_asset_custody_link/models/__init__.py b/odex25_accounting/exp_asset_custody_link/models/__init__.py new file mode 100644 index 000000000..83a7fdfc3 --- /dev/null +++ b/odex25_accounting/exp_asset_custody_link/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + +from . import account_asset_operation +from . import employee_custody \ No newline at end of file diff --git a/odex25_accounting/exp_asset_custody_link/models/account_asset_operation.py b/odex25_accounting/exp_asset_custody_link/models/account_asset_operation.py new file mode 100644 index 000000000..a5ddec395 --- /dev/null +++ b/odex25_accounting/exp_asset_custody_link/models/account_asset_operation.py @@ -0,0 +1,70 @@ +from odoo import models, fields, api, _, exceptions +class AccountAssetOperation(models.Model): + _inherit = 'account.asset.operation' + + emp_asset_custody_id = fields.Many2one(comodel_name='custom.employee.custody') + + def act_confirm(self): + module = self.env['ir.module.module'].sudo() + exp_petty_cash_module = module.search( + [('state', '=', 'installed'), ('name', '=', 'exp_employee_custody')]) + if not self.asset_id: + raise exceptions.Warning(_('Asset is required to confirm this operation.')) + if self.type in ('assignment', 'release', 'transfer'): + self.custody_confirm() + self.state = 'done' + if self.type == 'assignment': + self.asset_id.status = 'assigned' + if exp_petty_cash_module: + custody = self.env['custom.employee.custody'].search([('id', '=', self.emp_asset_custody_id.id)]) + print("===============================================================", custody) + for cus in custody: + operation = self.env['account.asset.operation'].search( + [('emp_asset_custody_id', '=', cus.id), ('type', '=', 'assignment')]) + print("----------", operation) + print("----------", operation.state) + if all(ope.state in 'done' for ope in operation): + print("----------", operation.state) + cus.write({'state': 'assign'}) + elif self.type == 'release': + self.asset_id.status = 'available' + # self.asset_id.status = self.asset_status == 'good' and 'available' or 'scrap' + if exp_petty_cash_module: + custody = self.env['custom.employee.custody'].search([('id', '=', self.emp_asset_custody_id.id)]) + for cus in custody: + operation = self.env['account.asset.operation'].search( + [('emp_asset_custody_id', '=', cus.id), ('type', '=', 'release')]) + if all(ope.state in 'done' for ope in operation): + cus.write({'state': 'done'}) + + + # def custody_confirm(self): + # + # self.asset_id.employee_id = self.new_employee_id.id + # self.asset_id.department_id = self.new_department_id.id + # self.asset_id.location_id = self.new_location_id.id + # self.asset_id.custody_type = self.custody_type + # self.asset_id.custody_period = self.custody_period + # self.asset_id.return_date = self.return_date + # self.asset_id.purpose = self.note +class HrEmployee(models.Model): + _inherit = 'hr.employee' + petty_cash_count1 = fields.Integer(compute='assignment_no') + assignment_no = fields.Integer(compute='_compute_assignment_no') + def assignment_no(self): + for emp in self: + items = self.env['account.asset.operation'].search([ + ('asset_statuso','=','assigned'),('new_employee_id', '=',self.id ) + ]) + emp.petty_cash_count1 = len(items) + # emp.user_id.partner_id.id + def get_assignment(self): + self.ensure_one() + return { + 'type': 'ir.actions.act_window', + 'name': 'Assignments', + 'view_mode': 'tree', + 'res_model': 'account.asset.operation', + 'domain': [('asset_statuso','=','assigned'),('new_employee_id', '=', self.id)], + 'context': "{'create': False}" + } diff --git a/odex25_accounting/exp_asset_custody_link/models/employee_custody.py b/odex25_accounting/exp_asset_custody_link/models/employee_custody.py new file mode 100644 index 000000000..7620c31d9 --- /dev/null +++ b/odex25_accounting/exp_asset_custody_link/models/employee_custody.py @@ -0,0 +1,117 @@ +from odoo import models, fields, api, _, exceptions +from odoo import SUPERUSER_ID + + +# from datetime import datetime , date + + +class EmployeeCustody(models.Model): + _inherit = 'custom.employee.custody' + + state = fields.Selection(selection=[ + ("draft", _("Draft")), + ("submit", _("send")), + ("direct", _("Direct Manager")), + ("admin", _("Human Resources Manager")), + ("wait", _("Wait Assignment")), + ("assign", _("Assignment")), + ("wait_release", _("Wait Release")), + ("done", _("Return Done")), + ("refuse", _("Refuse")) + ], default='draft') + + asset_line_ids = fields.One2many('asset.custody.line', 'asset_custody_line',required=True) + asset_assign_count = fields.Integer(compute='_asset_assign_count', string='Asset Assignment') + asset_release_count = fields.Integer(compute='_asset_release_count', string='Asset Release') + + + def create_asset_custody(self): + for i in self.asset_line_ids: + data = { + 'date': self.current_date, + 'asset_id': i.asset_id.id, + 'type': 'assignment', + 'custody_type': i.custody_type, + 'custody_period': i.custody_period, + 'state': 'draft', + 'user_id': self.env.uid, + 'new_employee_id': self.employee_id.id, + 'new_department_id': self.department_id.id, + 'emp_asset_custody_id': self.id, + + } + self.env['account.asset.operation'].create(data) + + + def asset_custody_release(self): + for i in self.asset_line_ids: + data = { + 'name': i.asset_id.name, + 'date': self.current_date, + 'asset_id': i.asset_id.id, + 'type': 'release', + 'custody_type': i.custody_type, + 'custody_period': i.custody_period, + 'state': 'draft', + 'user_id': self.env.uid, + 'current_employee_id': self.employee_id.id, + 'new_employee_id': self.employee_id.id, + 'current_department_id': self.department_id.id, + 'emp_asset_custody_id': self.id, + + } + self.env['account.asset.operation'].create(data) + + + def _asset_assign_count(self): + self.asset_assign_count = len( + self.env['asset.custody.line'].search([('asset_custody_line', '=', self.id)])) + + + def _asset_release_count(self): + self.asset_release_count = len( + self.env['asset.custody.line'].search([('asset_custody_line', '=', self.id)])) + + + def approve(self): + if not self.asset_line_ids: + raise exceptions.Warning(_('Please Select an asset')) + self.create_asset_custody() + self.write({'state': 'wait'}) + + + def done(self): + self.asset_custody_release() + self.state = "wait_release" + +class EmployeeCustodyLine(models.Model): + _name = 'asset.custody.line' + + # Asset custody fields + type = fields.Selection([('assignment', 'Assignment')]) + custody_type = fields.Selection(selection=[('personal', 'Personal'), ('general', 'General')]) + custody_period = fields.Selection(selection=[('temporary', 'Temporary'), ('permanent', 'Permanent')]) + return_date = fields.Date() + date = fields.Date() + asset_id = fields.Many2one('account.asset') + asset_custody_line = fields.Many2one(comodel_name='custom.employee.custody') # Inverse field + +class Followers(models.Model): + _inherit = 'mail.followers' + + @api.model + def create(self, vals): + if 'res_model' in vals and 'res_id' in vals and 'partner_id' in vals: + dups = self.env['mail.followers'].search( + [('res_model', '=', vals.get('res_model')), ('res_id', '=', vals.get('res_id')), + ('partner_id', '=', vals.get('partner_id'))]) + + if len(dups): + for p in dups: + p.unlink() + + res = super(Followers, self).create(vals) + + return res + + diff --git a/odex25_accounting/exp_asset_custody_link/security/ir.model.access.csv b/odex25_accounting/exp_asset_custody_link/security/ir.model.access.csv new file mode 100644 index 000000000..356298ce9 --- /dev/null +++ b/odex25_accounting/exp_asset_custody_link/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id/id,perm_read,perm_write,perm_create,perm_unlink +access_employee_asset_custody_line,access_employee_custody_asset_line,model_asset_custody_line,base.group_user,1,1,1,1 diff --git a/odex25_accounting/exp_asset_custody_link/views/employee_custody_action.xml b/odex25_accounting/exp_asset_custody_link/views/employee_custody_action.xml new file mode 100644 index 000000000..ba67204cb --- /dev/null +++ b/odex25_accounting/exp_asset_custody_link/views/employee_custody_action.xml @@ -0,0 +1,90 @@ + + + + Assets Assignment + account.asset.operation + tree,form + { 'create': False } + [('emp_asset_custody_id', '=', active_id),('type', '=', 'assignment')] + + + + + Assets Release + account.asset.operation + tree,form + { 'create': False } + [('emp_asset_custody_id', '=', active_id),('type', '=', 'release')] + + + + + Employee Custody With Asset + custom.employee.custody + + + + + +
    + + +
    +
    + + + + + + + + + + + + + + + +
    +
    + + hr_employee.extend1.form2 + hr.employee + + + + + + + + + +
    +
    diff --git a/odex25_accounting/exp_budget_check/__init__.py b/odex25_accounting/exp_budget_check/__init__.py new file mode 100644 index 000000000..511a0ca3a --- /dev/null +++ b/odex25_accounting/exp_budget_check/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + +from . import controllers +from . import models \ No newline at end of file diff --git a/odex25_accounting/exp_budget_check/__manifest__.py b/odex25_accounting/exp_budget_check/__manifest__.py new file mode 100644 index 000000000..66ee98e25 --- /dev/null +++ b/odex25_accounting/exp_budget_check/__manifest__.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +{ + 'name': "Check Budget", + + 'summary': """ + """, + + 'description': """ + Check budget in vendor bill + """, + 'website': 'http://exp-sa.com', + 'license': 'GPL-3', + 'author': 'Expert Co. Ltd.', + + 'category': 'Odex25-Accounting/Odex25-Accounting', + 'version': '0.1', + + # any module necessary for this one to work correctly + 'depends': [ + 'account', + 'account_configuration', + 'account_budget_custom', + 'hr_expense_petty_cash', + + ], + + # always loaded + 'data': [ + # 'security/ir.model.access.csv', + 'views/account_invoice_view.xml', + 'views/hr_expense_view.xml', + ], + # only loaded in demonstration mode + 'demo': [ + 'demo/demo.xml', + ], +} diff --git a/odex25_accounting/exp_budget_check/controllers/__init__.py b/odex25_accounting/exp_budget_check/controllers/__init__.py new file mode 100644 index 000000000..457bae27e --- /dev/null +++ b/odex25_accounting/exp_budget_check/controllers/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import controllers \ No newline at end of file diff --git a/odex25_accounting/exp_budget_check/controllers/controllers.py b/odex25_accounting/exp_budget_check/controllers/controllers.py new file mode 100644 index 000000000..3059a1074 --- /dev/null +++ b/odex25_accounting/exp_budget_check/controllers/controllers.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from odoo import http + +# class ExpBudgetCheck(http.Controller): +# @http.route('/exp_budget_check/exp_budget_check/', auth='public') +# def index(self, **kw): +# return "Hello, world" + +# @http.route('/exp_budget_check/exp_budget_check/objects/', auth='public') +# def list(self, **kw): +# return http.request.render('exp_budget_check.listing', { +# 'root': '/exp_budget_check/exp_budget_check', +# 'objects': http.request.env['exp_budget_check.exp_budget_check'].search([]), +# }) + +# @http.route('/exp_budget_check/exp_budget_check/objects//', auth='public') +# def object(self, obj, **kw): +# return http.request.render('exp_budget_check.object', { +# 'object': obj +# }) \ No newline at end of file diff --git a/odex25_accounting/exp_budget_check/demo/demo.xml b/odex25_accounting/exp_budget_check/demo/demo.xml new file mode 100644 index 000000000..b8f148ce2 --- /dev/null +++ b/odex25_accounting/exp_budget_check/demo/demo.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/odex25_accounting/exp_budget_check/i18n/ar.po b/odex25_accounting/exp_budget_check/i18n/ar.po new file mode 100644 index 000000000..736b045d4 --- /dev/null +++ b/odex25_accounting/exp_budget_check/i18n/ar.po @@ -0,0 +1,266 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * exp_budget_check +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-28 11:05+0000\n" +"PO-Revision-Date: 2022-07-28 11:05+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: exp_budget_check +#: model:ir.model,name:exp_budget_check.model_account_analytic_account +msgid "Analytic Account" +msgstr "الحساب التحليلي" + +#. module: exp_budget_check +#: code:addons/exp_budget_check/models/account_invoice.py:0 +#: model:ir.model.fields.selection,name:exp_budget_check.selection__account_move__state__budget_approve +#, python-format +msgid "Approved" +msgstr "موافقة" + +#. module: exp_budget_check +#: code:addons/exp_budget_check/models/account_invoice.py:0 +#: model:ir.model.fields.selection,name:exp_budget_check.selection__account_move__state__budget_check +#, python-format +msgid "Budget Check" +msgstr "فحص الموازنة" + +#. module: exp_budget_check +#: model:ir.model,name:exp_budget_check.model_budget_confirmation +msgid "Budget Confirmation" +msgstr "تصديق الموازنة" + +#. module: exp_budget_check +#: model:ir.model,name:exp_budget_check.model_crossovered_budget_lines +msgid "Budget Line" +msgstr "خط الموازنة" + +#. module: exp_budget_check +#: model:ir.model.fields.selection,name:exp_budget_check.selection__account_move__state__cancel +msgid "Cancelled" +msgstr "ملغي" + +#. module: exp_budget_check +#: model:ir.model.fields,field_description:exp_budget_check.field_account_bank_statement_line__budget_check +#: model:ir.model.fields,field_description:exp_budget_check.field_account_move__budget_check +#: model:ir.model.fields,field_description:exp_budget_check.field_account_payment__budget_check +#: model_terms:ir.ui.view,arch_db:exp_budget_check.budget_check_view_move_form +msgid "Check Budget" +msgstr "فحص الموازنة" + +#. module: exp_budget_check +#: model_terms:ir.ui.view,arch_db:exp_budget_check.budget_check_view_move_form +msgid "Confirm" +msgstr "تأكيد" + +#. module: exp_budget_check +#: model:ir.model.fields,field_description:exp_budget_check.field_crossovered_budget_lines__confirm +#: model_terms:ir.ui.view,arch_db:exp_budget_check.crossovered_budget_view_form_inherit +msgid "Confirm Amount" +msgstr "المبلغ المصدق" + +#. module: exp_budget_check +#: model_terms:ir.ui.view,arch_db:exp_budget_check.budget_check_view_move_form +msgid "Confirm Bill" +msgstr "تأكيد الفاتورة" + +#. module: exp_budget_check +#: model:ir.model.fields,field_description:exp_budget_check.field_account_analytic_account__display_name +#: model:ir.model.fields,field_description:exp_budget_check.field_account_move__display_name +#: model:ir.model.fields,field_description:exp_budget_check.field_account_move_line__display_name +#: model:ir.model.fields,field_description:exp_budget_check.field_budget_confirmation__display_name +#: model:ir.model.fields,field_description:exp_budget_check.field_crossovered_budget_lines__display_name +msgid "Display Name" +msgstr "الاسم المعروض" + +#. module: exp_budget_check +#: model:ir.model.fields.selection,name:exp_budget_check.selection__account_move__state__draft +msgid "Draft" +msgstr "مسودة" + +#. module: exp_budget_check +#: model:ir.model.fields,field_description:exp_budget_check.field_account_bank_statement_line__exceed_budget +#: model:ir.model.fields,field_description:exp_budget_check.field_account_move__exceed_budget +#: model:ir.model.fields,field_description:exp_budget_check.field_account_payment__exceed_budget +msgid "Exceed Budget" +msgstr "تخطي الموازنة" + +#. module: exp_budget_check +#: model:ir.model.fields,field_description:exp_budget_check.field_account_analytic_account__id +#: model:ir.model.fields,field_description:exp_budget_check.field_account_move__id +#: model:ir.model.fields,field_description:exp_budget_check.field_account_move_line__id +#: model:ir.model.fields,field_description:exp_budget_check.field_budget_confirmation__id +#: model:ir.model.fields,field_description:exp_budget_check.field_crossovered_budget_lines__id +msgid "ID" +msgstr "المُعرف" + +#. module: exp_budget_check +#: model:ir.model.fields,field_description:exp_budget_check.field_budget_confirmation__invoice_id +msgid "Invoice" +msgstr "" + +#. module: exp_budget_check +#: model:ir.model.fields,field_description:exp_budget_check.field_account_bank_statement_line__is_approve +#: model:ir.model.fields,field_description:exp_budget_check.field_account_move__is_approve +#: model:ir.model.fields,field_description:exp_budget_check.field_account_payment__is_approve +msgid "Is Approve" +msgstr "" + +#. module: exp_budget_check +#: model:ir.model.fields,field_description:exp_budget_check.field_account_bank_statement_line__is_budget +#: model:ir.model.fields,field_description:exp_budget_check.field_account_move__is_budget +#: model:ir.model.fields,field_description:exp_budget_check.field_account_payment__is_budget +msgid "Is Budget" +msgstr "" + +#. module: exp_budget_check +#: model:ir.model.fields,field_description:exp_budget_check.field_account_bank_statement_line__is_check +#: model:ir.model.fields,field_description:exp_budget_check.field_account_move__is_check +#: model:ir.model.fields,field_description:exp_budget_check.field_account_payment__is_check +msgid "Is Check" +msgstr "" + +#. module: exp_budget_check +#: model:ir.model.fields,field_description:exp_budget_check.field_account_bank_statement_line__is_reject +#: model:ir.model.fields,field_description:exp_budget_check.field_account_move__is_reject +#: model:ir.model.fields,field_description:exp_budget_check.field_account_payment__is_reject +msgid "Is Reject" +msgstr "" + +#. module: exp_budget_check +#: model:ir.model.fields,field_description:exp_budget_check.field_account_analytic_account__is_analytic_budget +msgid "Is Use In Budget" +msgstr "يستخدم في الموازنة" + +#. module: exp_budget_check +#: model:ir.model,name:exp_budget_check.model_account_move +msgid "Journal Entry" +msgstr "قيد اليومية" + +#. module: exp_budget_check +#: model:ir.model,name:exp_budget_check.model_account_move_line +msgid "Journal Item" +msgstr "عنصر اليومية" + +#. module: exp_budget_check +#: model:ir.model.fields,field_description:exp_budget_check.field_account_analytic_account____last_update +#: model:ir.model.fields,field_description:exp_budget_check.field_account_move____last_update +#: model:ir.model.fields,field_description:exp_budget_check.field_account_move_line____last_update +#: model:ir.model.fields,field_description:exp_budget_check.field_budget_confirmation____last_update +#: model:ir.model.fields,field_description:exp_budget_check.field_crossovered_budget_lines____last_update +msgid "Last Modified on" +msgstr "آخر تعديل في" + +#. module: exp_budget_check +#: code:addons/exp_budget_check/models/account_invoice.py:0 +#, python-format +msgid "Please Choose Analytic account for This Bill" +msgstr "الرجاء إختيار حسابات تحليلية لهذه الفاتورة" + +#. module: exp_budget_check +#: code:addons/exp_budget_check/models/account_invoice.py:0 +#, python-format +msgid "Please Set An Expense Account For Product %s" +msgstr "الرجاء إختيار حساب للمنتج%s" + +#. module: exp_budget_check +#: model:ir.model.fields.selection,name:exp_budget_check.selection__account_move__state__posted +msgid "Posted" +msgstr "مُرحل" + +#. module: exp_budget_check +#: model:ir.model.fields,field_description:exp_budget_check.field_account_bank_statement_line__reject +#: model:ir.model.fields,field_description:exp_budget_check.field_account_move__reject +#: model:ir.model.fields,field_description:exp_budget_check.field_account_payment__reject +msgid "Reject" +msgstr "رفض" + +#. module: exp_budget_check +#: model:ir.model.fields,field_description:exp_budget_check.field_crossovered_budget_lines__reserve +#: model_terms:ir.ui.view,arch_db:exp_budget_check.crossovered_budget_view_form_inherit +msgid "Reserve Amount" +msgstr "المبلغ المحجوز" + +#. module: exp_budget_check +#: model:ir.model.fields,field_description:exp_budget_check.field_account_bank_statement_line__state_a +#: model:ir.model.fields,field_description:exp_budget_check.field_account_bank_statement_line__state_b +#: model:ir.model.fields,field_description:exp_budget_check.field_account_bank_statement_line__state_bill +#: model:ir.model.fields,field_description:exp_budget_check.field_account_move__state +#: model:ir.model.fields,field_description:exp_budget_check.field_account_move__state_a +#: model:ir.model.fields,field_description:exp_budget_check.field_account_move__state_b +#: model:ir.model.fields,field_description:exp_budget_check.field_account_move__state_bill +#: model:ir.model.fields,field_description:exp_budget_check.field_account_payment__state +#: model:ir.model.fields,field_description:exp_budget_check.field_account_payment__state_a +#: model:ir.model.fields,field_description:exp_budget_check.field_account_payment__state_b +#: model:ir.model.fields,field_description:exp_budget_check.field_account_payment__state_bill +msgid "Status" +msgstr "الحالة" + +#. module: exp_budget_check +#: model:ir.model.fields,field_description:exp_budget_check.field_account_move_line__price_tax +msgid "Tax" +msgstr "ضريبة" + +#. module: exp_budget_check +#: code:addons/exp_budget_check/models/account_invoice.py:0 +#, python-format +msgid "The Budget Has Been Rejected" +msgstr "تم رفض الموازنة لهذه الفاتورة" + +#. module: exp_budget_check +#: model:ir.model.fields.selection,name:exp_budget_check.selection__budget_confirmation__type__vendor_bill +msgid "Vendor Bill" +msgstr "فاتورة مورد" + +#. module: exp_budget_check +#: code:addons/exp_budget_check/models/account_invoice.py:0 +#, python-format +msgid "Vendor Bill :%s" +msgstr "فاتورة المورد :%s" + +#. module: exp_budget_check +#: code:addons/exp_budget_check/models/account_invoice.py:0 +#: model:ir.model.fields.selection,name:exp_budget_check.selection__account_move__state__wait_budget +#, python-format +msgid "Wait Budget" +msgstr "إنتظار تحقق الموازنة" + + +#. module: exp_budget_check +#: model:ir.model.fields,field_description:exp_budget_check.field_budget_confirmation__type +msgid "type" +msgstr "النوع" + +#. module: exp_budget_check +#: code:addons/exp_budget_check/models/account_invoice.py:0 +#, python-format +msgid "analytic account is %s not link with budget" +msgstr "الحساب التحليلي %s ليس له موازنة" + +#. module: exp_budget_check +#: code:addons/exp_budget_check/models/account_invoice.py:0 +#, python-format +msgid "Rejected By : %s With Reject Reason : %s" +msgstr "تم الرقض بواسطة %s . مع سبب الرقض : %s" + + +#. module: exp_budget_check +#: code:addons/exp_budget_check/models/account_invoice.py:0 +#, python-format +msgid "Please insert Bill Date" +msgstr "الرجاء إدخال تاريخ الفاتورة" + +#. module: account_budget_custom +#: code:addons/account_budget_custom/models/budget_confirmation.py:0 +#, python-format +msgid "Specify Reject Reason" +msgstr "تحديد سبب الرفض" diff --git a/odex25_accounting/exp_budget_check/models/__init__.py b/odex25_accounting/exp_budget_check/models/__init__.py new file mode 100644 index 000000000..c34917386 --- /dev/null +++ b/odex25_accounting/exp_budget_check/models/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + +from . import account_invoice +from . import analytic_account +from . import account_budget +from . import hr_expense diff --git a/odex25_accounting/exp_budget_check/models/account_budget.py b/odex25_accounting/exp_budget_check/models/account_budget.py new file mode 100644 index 000000000..65a3201bd --- /dev/null +++ b/odex25_accounting/exp_budget_check/models/account_budget.py @@ -0,0 +1,64 @@ +from odoo import api, fields, models, _ + + +class CrossoveredBudgetLines(models.Model): + _inherit = "crossovered.budget.lines" + + reserve = fields.Float(string='Reserve Amount') + confirm = fields.Float(string='Confirm Amount') + + def _compute_operations_amount(self): + if not self.ids: return + for line in self: + pull_out = provide = budget_confirm_amount = 0.0 + date_to = self.env.context.get('wizard_date_to') or line.date_to + date_from = self.env.context.get( + 'wizard_date_from') or line.date_from + + if line.analytic_account_id.id: + if 'reserved' not in self.env.context: + self.env.cr.execute(""" + SELECT SUM(amount) + FROM budget_operations + WHERE from_budget_line_id=%s + AND (date between %s AND %s) + AND state='confirmed'""", + (line.id, date_from, date_to,)) + pull_out = self.env.cr.fetchone()[0] or 0.0 + + if 'reserved' in self.env.context: + self.env.cr.execute(""" + SELECT SUM(amount) + FROM budget_operations + WHERE from_budget_line_id=%s + AND (date between %s AND %s) + AND state='confirmed' + AND from_reserved=%s""", + (line.id, date_from, date_to, self.env.context['reserved'])) + pull_out = self.env.cr.fetchone()[0] or 0.0 + + self.env.cr.execute(""" + SELECT SUM(amount) + FROM budget_operations + WHERE to_budget_line_id=%s + AND (date between %s AND %s) + AND state='confirmed'""", + (line.id, date_from, date_to,)) + provide = self.env.cr.fetchone()[0] or 0.0 + + self.env.cr.execute(""" + SELECT SUM(amount) + FROM budget_confirmation_line + WHERE budget_line_id=%s + AND (date between %s AND %s) + AND state='done'""", + (line.id, date_from, date_to,)) + budget_confirm_amount = self.env.cr.fetchone()[0] or 0.0 + + line.pull_out = abs(pull_out) + line.provide = abs(provide) + line.budget_confirm_amount = budget_confirm_amount + line.remain = abs(line.planned_amount) + provide - abs(pull_out) - abs(line.practical_amount) - abs( + line.reserved_amount) + line.reserve + if line.planned_amount < 0: + line.remain = -line.remain diff --git a/odex25_accounting/exp_budget_check/models/account_invoice.py b/odex25_accounting/exp_budget_check/models/account_invoice.py new file mode 100644 index 000000000..0cce1e65e --- /dev/null +++ b/odex25_accounting/exp_budget_check/models/account_invoice.py @@ -0,0 +1,209 @@ +from odoo import models, fields, api, _ +from odoo.exceptions import AccessError, UserError, RedirectWarning, ValidationError, Warning +from odoo.tools import float_is_zero, float_compare, pycompat + + +class BudgetConfirmationCustom(models.Model): + _inherit = 'budget.confirmation' + + type = fields.Selection(selection_add=[('vendor.bill', 'Vendor Bill')]) + invoice_id = fields.Many2one('account.move') + + def cancel(self): + super(BudgetConfirmationCustom, self).cancel() + if self.invoice_id and self.type == 'vendor.bill': + self.invoice_id.write({'state': 'draft'}) + self.invoice_id.message_post(body=_( + "Rejected By : %s With Reject Reason : %s" % (str(self.env.user.name), str(self.reject_reason)))) + + def done(self): + super(BudgetConfirmationCustom, self).done() + if self.invoice_id and self.type == 'vendor.bill': + self.invoice_id.write({'is_approve': True}) + self.invoice_id.write({'state': 'budget_approve'}) + for rec in self: + for line in rec.lines_ids: + budget_post = self.env['account.budget.post'].search([]).filtered( + lambda x: line.account_id in x.account_ids) + analytic_account_id = line.analytic_account_id + budget_lines = analytic_account_id.crossovered_budget_line.filtered( + lambda x: x.general_budget_id in budget_post and + x.crossovered_budget_id.state == 'done' and + x.date_from <= self.date <= x.date_to) + print("budget_lines.reserve budget_lines.reserve budget_lines.reserve", budget_lines.reserve) + amount = budget_lines.reserve + amount += line.amount + budget_lines.write({'reserve': amount}) + + +class AccountMove(models.Model): + _inherit = 'account.move' + + state = fields.Selection(selection=[ + ('draft', 'Draft'), + ('confirm', 'Confirm'), + ('wait_budget', 'Wait Budget'), + ('budget_approve', 'Approved'), + ('posted', 'Posted'), + ('cancel', 'Cancelled'), + ]) + + state_a = fields.Selection(related='state') + state_b = fields.Selection(related='state') + + is_budget = fields.Boolean(default=True) + state_bill = fields.Selection(related='state') + budget_check = fields.Boolean(string="Check Budget", default=False, readonly=True) + exceed_budget = fields.Boolean(default=False) + is_check = fields.Boolean(default=False) + is_approve = fields.Boolean(default=False) + + def copy(self): + self.write({'budget_check': False}) + # self.write({'is_check':False}) + return super(AccountMove, self).copy() + + def action_confirm(self): + if not self.invoice_date: + raise ValidationError(_('Please insert Bill Date')) + for rec in self.invoice_line_ids: + if rec.analytic_account_id.is_analytic_budget and not rec.analytic_account_id.is_auto_check: + self.write({ + 'state': 'confirm' + }) + break + else: + self.write({ + 'state': 'budget_approve' + }) + + def button_cancel(self): + res = super(AccountMove, self).button_cancel() + if self.is_check: + date = fields.Date.from_string(self.date) + for line in self.invoice_line_ids: + analytic_account_id = line.analytic_account_id + budget_post = self.env['account.budget.post'].search([]).filtered( + lambda x: line.account_id in x.account_ids) + budget_lines = analytic_account_id.crossovered_budget_line.filtered( + lambda x: x.general_budget_id in budget_post and + x.crossovered_budget_id.state == 'done' and + fields.Date.from_string(x.date_from) <= date <= fields.Date.from_string(x.date_to)) + amount = budget_lines.reserve + amount -= (line.price_subtotal + line.price_tax) + budget_lines.write({'reserve': amount}) + + return res + + def action_post(self): + res = super(AccountMove, self).action_post() + if self.is_check: + confirm_budget = self.env['budget.confirmation'].search([('invoice_id', '=', self.id)]) + confirm_budget.write({'ref': self.name}) + for line in self.invoice_line_ids: + analytic_account_id = line.analytic_account_id + budget_post = self.env['account.budget.post'].search([]).filtered( + lambda x: line.account_id in x.account_ids) + budget_lines = analytic_account_id.crossovered_budget_line.filtered( + lambda x: x.general_budget_id in budget_post and + x.crossovered_budget_id.state == 'done' and + x.date_from <= self.invoice_date <= x.date_to) + amount = budget_lines.confirm + amount += (line.price_subtotal + line.price_tax) + budget_lines.write({'confirm': amount}) + budget_lines.write({'reserve': abs((line.price_subtotal + line.price_tax) - budget_lines.reserve)}) + return res + + def button_draft(self): + res = super(AccountMove, self).button_draft() + if self.is_check: + date = fields.Date.from_string(self.date) + for line in self.invoice_line_ids: + analytic_account_id = line.analytic_account_id + budget_post = self.env['account.budget.post'].search([]).filtered( + lambda x: line.account_id in x.account_ids) + budget_lines = analytic_account_id.crossovered_budget_line.filtered( + lambda x: x.general_budget_id in budget_post and + x.crossovered_budget_id.state == 'done' and + fields.Date.from_string(x.date_from) <= date <= fields.Date.from_string(x.date_to)) + amount = budget_lines.confirm + amount -= (line.price_subtotal + line.price_tax) + budget_lines.write({'confirm': amount}) + return res + + def action_budget(self): + confirmation_lines = [] + if not self.budget_check: + amount = 0 + for line in self.invoice_line_ids.filtered(lambda r: r.analytic_account_id.is_analytic_budget == True): + if line.analytic_account_id: + if not line.analytic_account_id: + raise ValidationError(_('Please Choose Analytic account for This Bill')) + budget_lines = line.analytic_account_id.crossovered_budget_line.filtered( + lambda x: + x.crossovered_budget_id.state == 'done' and + fields.Date.from_string(x.date_from) <= fields.Date.from_string( + self.invoice_date) <= fields.Date.from_string(x.date_to)) + if not budget_lines: + raise UserError( + _('analytic account is %s not link with budget') % line.analytic_account_id.name) + else: + remain = abs(budget_lines[0].remain) + amount = amount + (line.price_subtotal + line.price_tax) + new_remain = remain - amount + confirmation_lines.append((0, 0, { + 'amount': line.price_subtotal + line.price_tax, + 'analytic_account_id': line.analytic_account_id.id, + 'description': line.product_id.name, + 'budget_line_id': budget_lines[0].id, + 'remain': new_remain + (line.price_subtotal + line.price_tax), + 'new_balance': new_remain, + 'account_id': line.account_id.id + })) + + data = { + 'name': _('Vendor Bill :%s') % self.partner_id.name, + 'date': self.invoice_date, + 'beneficiary_id': self.partner_id.id, + # 'department_id': self.department_id.id, + 'type': 'vendor.bill', + 'ref': self.name, + 'description': self.ref, + 'total_amount': amount, + 'lines_ids': confirmation_lines, + 'invoice_id': self.id + } + self.env['budget.confirmation'].create(data) + + self.write({ + 'is_check': True + }) + self.write({ + 'state': 'wait_budget' + }) + + def action_open_budget_confirmation(self): + self.ensure_one() + return { + "name": _('Budget Confirmation'), + "type": "ir.actions.act_window", + "res_model": "budget.confirmation", + "view_mode": "form", + "target": "new", + "domain": [('invoice_id', '=', self.id)] + } + + +class PurchaseOrderLine(models.Model): + _inherit = 'account.move.line' + + price_tax = fields.Float(compute='_compute_amount', string='Tax', store=True) + + @api.depends('quantity', 'price_unit', 'tax_ids') + def _compute_amount(self): + for line in self: + taxes = line.tax_ids.compute_all(line.price_unit, line.move_id.currency_id, line.quantity, + product=line.product_id, partner=line.move_id.partner_id) + line.update({ + 'price_tax': sum(t.get('amount', 0.0) for t in taxes.get('taxes', [])), + }) diff --git a/odex25_accounting/exp_budget_check/models/analytic_account.py b/odex25_accounting/exp_budget_check/models/analytic_account.py new file mode 100644 index 000000000..4c4a56466 --- /dev/null +++ b/odex25_accounting/exp_budget_check/models/analytic_account.py @@ -0,0 +1,14 @@ +from odoo import models, fields, api, _ + + +class AccountAnalyticAccount(models.Model): + _inherit = 'account.analytic.account' + + is_analytic_budget = fields.Boolean(string="Is Use In Budget", default=False) + is_auto_check = fields.Boolean(string="Auto Check", default=False) + +# +# class CrossoveredBudgetLines(models.Model): +# _inherit = "crossovered.budget.lines" +# +# analytic_account_id = fields.Many2one('account.analytic.account', 'Analytic Account', domain=[('is_analytic_budget','=',True)]) diff --git a/odex25_accounting/exp_budget_check/models/hr_expense.py b/odex25_accounting/exp_budget_check/models/hr_expense.py new file mode 100644 index 000000000..5d62a9761 --- /dev/null +++ b/odex25_accounting/exp_budget_check/models/hr_expense.py @@ -0,0 +1,167 @@ +from odoo import models, fields, api, _ +from odoo.exceptions import AccessError, UserError, RedirectWarning, ValidationError, Warning +from odoo.tools import float_is_zero, float_compare, pycompat + + +class BudgetConfirmationCustom(models.Model): + _inherit = 'budget.confirmation' + + type = fields.Selection(selection_add=[('expense', 'Expense')]) + expense_id = fields.Many2one('hr.expense') + + def cancel(self): + super(BudgetConfirmationCustom, self).cancel() + if self.expense_id and self.type == 'expense': + self.expense_id.write({'state': 'draft'}) + self.expense_id.message_post(body=_( + "Rejected By : %s With Reject Reason : %s" % (str(self.env.user.name), str(self.reject_reason)))) + + def done(self): + super(BudgetConfirmationCustom, self).done() + if self.expense_id and self.type == 'expense': + self.expense_id.write({'is_approve': True}) + self.expense_id.write({'state': 'budget_approve'}) + for rec in self: + for line in rec.lines_ids: + budget_post = self.env['account.budget.post'].search([]).filtered( + lambda x: line.account_id in x.account_ids) + analytic_account_id = line.analytic_account_id + budget_lines = analytic_account_id.crossovered_budget_line.filtered( + lambda x: x.general_budget_id in budget_post and + x.crossovered_budget_id.state == 'done' and + x.date_from <= self.date <= x.date_to) + print("budget_lines.reserve budget_lines.reserve budget_lines.reserve", budget_lines.reserve) + amount = budget_lines.reserve + amount += line.amount + budget_lines.write({'reserve': amount}) + + +class AccountMove(models.Model): + _inherit = 'hr.expense' + + state = fields.Selection(selection_add=[ + ('confirm', 'Confirm'), + ('wait_budget', 'Wait Budget'), + ('budget_approve', 'Approved'), + ]) + + is_budget = fields.Boolean(related='analytic_account_id.is_analytic_budget') + is_check = fields.Boolean(default=False, copy=False) + is_approve = fields.Boolean(default=False, copy=False) + + def action_submit_expenses(self): + if self.analytic_account_id.is_analytic_budget: + if self.state == 'draft': + self.write({ + 'state': 'confirm' + }) + elif self.state == 'confirm': + raise UserError(_('Please Check Budget First')) + elif self.state == 'wait_budget': + raise UserError(_("The Budget Confirmation Doesn't Approve yet")) + elif self.state == 'budget_approve': + if self.is_approve: + confirm_budget = self.env['budget.confirmation'].search([('expense_id', '=', self.id)]) + confirm_budget.write({'ref': self.name}) + analytic_account_id = self.analytic_account_id + budget_post = self.env['account.budget.post'].search([]).filtered( + lambda x: self.account_id in x.account_ids) + budget_lines = analytic_account_id.crossovered_budget_line.filtered( + lambda x: x.general_budget_id in budget_post and + x.crossovered_budget_id.state == 'done' and + x.date_from <= self.date <= x.date_to) + amount = budget_lines.confirm + amount += self.total_amount + budget_lines.write({'confirm': amount}) + budget_lines.write({'reserve': abs(self.total_amount - budget_lines.reserve)}) + todo = self.filtered(lambda x: x.payment_mode == 'own_account') or self.filtered( + lambda x: x.payment_mode == 'company_account') + sheet = self.env['hr.expense.sheet'].create({ + 'company_id': self.company_id.id, + 'employee_id': self[0].employee_id.id, + 'name': todo[0].name if len(todo) == 1 else '', + 'expense_line_ids': [(6, 0, todo.ids)] + }) + return { + 'name': _('New Expense Report'), + 'type': 'ir.actions.act_window', + 'view_mode': 'form', + 'res_model': 'hr.expense.sheet', + 'target': 'current', + 'res_id': sheet.id, + } + else: + return super(AccountMove, self).action_submit_expenses() + + def button_cancel(self): + res = super(AccountMove, self).button_cancel() + if self.is_check: + date = fields.Date.from_string(self.date) + for line in self.invoice_line_ids: + analytic_account_id = line.analytic_account_id + budget_post = self.env['account.budget.post'].search([]).filtered( + lambda x: line.account_id in x.account_ids) + budget_lines = analytic_account_id.crossovered_budget_line.filtered( + lambda x: x.general_budget_id in budget_post and + x.crossovered_budget_id.state == 'done' and + fields.Date.from_string(x.date_from) <= date <= fields.Date.from_string(x.date_to)) + amount = budget_lines.reserve + amount -= (line.price_subtotal + line.price_tax) + budget_lines.write({'reserve': amount}) + + return res + + def button_draft(self): + res = super(AccountMove, self).button_draft() + if self.is_check: + date = fields.Date.from_string(self.date) + for line in self.invoice_line_ids: + analytic_account_id = line.analytic_account_id + budget_post = self.env['account.budget.post'].search([]).filtered( + lambda x: line.account_id in x.account_ids) + budget_lines = analytic_account_id.crossovered_budget_line.filtered( + lambda x: x.general_budget_id in budget_post and + x.crossovered_budget_id.state == 'done' and + fields.Date.from_string(x.date_from) <= date <= fields.Date.from_string(x.date_to)) + amount = budget_lines.confirm + amount -= (line.price_subtotal + line.price_tax) + budget_lines.write({'confirm': amount}) + return res + + def action_budget(self): + budget_lines = self.analytic_account_id.crossovered_budget_line.filtered( + lambda x: x.crossovered_budget_id.state == 'done' and fields.Date.from_string( + x.date_from) <= fields.Date.from_string(self.date) <= fields.Date.from_string(x.date_to)) + if not budget_lines: + raise UserError( + _('analytic account is %s not link with budget') % self.analytic_account_id.name) + else: + remain = abs(budget_lines[0].remain) + amount = self.total_amount + new_remain = remain - amount + + data = { + 'name': _('Expense :%s') % self.employee_id.name, + 'date': self.date, + 'beneficiary_id': self.address_id.id, + 'type': 'expense', + 'ref': self.name, + 'description': self.name, + 'total_amount': amount, + 'lines_ids': [(0, 0, { + 'amount': amount, + 'analytic_account_id': self.analytic_account_id.id, + 'description': self.product_id.name, + 'budget_line_id': budget_lines[0].id, + 'remain': new_remain + amount, + 'new_balance': new_remain, + 'account_id': self.account_id.id + })], + 'expense_id': self.id + } + self.env['budget.confirmation'].create(data) + + self.write({ + 'is_check': True, + 'state': 'wait_budget' + }) diff --git a/odex25_accounting/exp_budget_check/security/ir.model.access.csv b/odex25_accounting/exp_budget_check/security/ir.model.access.csv new file mode 100644 index 000000000..8c41231e2 --- /dev/null +++ b/odex25_accounting/exp_budget_check/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_exp_budget_check_exp_budget_check,exp_budget_check.exp_budget_check,model_exp_budget_check_exp_budget_check,,1,0,0,0 \ No newline at end of file diff --git a/odex25_accounting/exp_budget_check/views/account_invoice_view.xml b/odex25_accounting/exp_budget_check/views/account_invoice_view.xml new file mode 100644 index 000000000..4522542b9 --- /dev/null +++ b/odex25_accounting/exp_budget_check/views/account_invoice_view.xml @@ -0,0 +1,107 @@ + + + + + + analytic.analytic.account.form.custom + account.analytic.account + + + + + + + + + + + + crossovered.budget.inherit.view.form + crossovered.budget + + + + ['|', ('company_id', '=', False), ('company_id', '=', + parent.company_id),('is_analytic_budget','=',True)] + + + + + + + + + + + + + + + + + + + + + + + + budget.account.view.move.inherit.form + account.move + + + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/odex25_accounting/hr_expense_petty_cash/views/hr_expense_sheet_views.xml b/odex25_accounting/hr_expense_petty_cash/views/hr_expense_sheet_views.xml new file mode 100644 index 000000000..293fdfe15 --- /dev/null +++ b/odex25_accounting/hr_expense_petty_cash/views/hr_expense_sheet_views.xml @@ -0,0 +1,153 @@ + + + + view.hr.expense.sheet.form.inherit + hr.expense.sheet + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + hr_expense_petty_cash.group_petty_cash_manager + + + + {'invisible': ['|',('state', 'not in', ('post', 'done')),('payment_mode', '=', + 'petty_cash')]} + + + + + + {'invisible': [('payment_mode', 'not in', ['own_account', 'petty_cash'])]} + + + + + + + +
    +

    + + +

    +
    + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + petty.cash.list + petty.cash + + + + + + + + + + + + + + + + + petty.cash.kanban + petty.cash + + + + + + +
    +
    +
    + + + +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + + petty.cash.search + petty.cash + + + + + + + + + + + + + + + Petty Cash + petty.cash + tree,kanban,form + + + +

    + Create a new petty cash holder +

    +
    +
    + + + + + + hr_employee.extend.form + hr.employee + + + + + + + + + +
    diff --git a/odex25_accounting/hr_expense_petty_cash/wizards/__init__.py b/odex25_accounting/hr_expense_petty_cash/wizards/__init__.py new file mode 100644 index 000000000..c1f71f550 --- /dev/null +++ b/odex25_accounting/hr_expense_petty_cash/wizards/__init__.py @@ -0,0 +1 @@ +from . import cancel_petty_cash diff --git a/odex25_accounting/hr_expense_petty_cash/wizards/cancel_petty_cash.py b/odex25_accounting/hr_expense_petty_cash/wizards/cancel_petty_cash.py new file mode 100644 index 000000000..cf546c51d --- /dev/null +++ b/odex25_accounting/hr_expense_petty_cash/wizards/cancel_petty_cash.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models + + +class PettyCash(models.TransientModel): + + + _name = "petty.cash.cancel.wizard" + _description = "petty refuse Reason wizard" + + reason = fields.Text(string='Cancel Request Reason', required=True) + petty_id = fields.Many2one('petty.cash') + user_id = fields.Many2one('res.users', string='Scheduler User', default=lambda self: self.env.user, required=True) + + @api.model + def default_get(self, fields): + res = super(PettyCash, self).default_get(fields) + active_ids = self.env.context.get('active_ids', []) + + res.update({'petty_id': active_ids[0] if active_ids else False}) + return res + + + def request_cancel_reason(self): + self.ensure_one() + print('zainab') + self.petty_id.write({'state':'running'}) + return {'type': 'ir.actions.act_window_close'} + diff --git a/odex25_accounting/hr_expense_petty_cash/wizards/cancel_purchase_request.xml b/odex25_accounting/hr_expense_petty_cash/wizards/cancel_purchase_request.xml new file mode 100644 index 000000000..6aac1d010 --- /dev/null +++ b/odex25_accounting/hr_expense_petty_cash/wizards/cancel_purchase_request.xml @@ -0,0 +1,19 @@ + + + + petty.cash.cancel.wizard.form + petty.cash.cancel.wizard + +
    + + This Employee Already has Petty Cash called" + + +
    +
    + +
    +
    +
    diff --git a/odex25_accounting/hr_expense_petty_cash/wizards/convert_to_contract.xml b/odex25_accounting/hr_expense_petty_cash/wizards/convert_to_contract.xml new file mode 100644 index 000000000..cb4a2649d --- /dev/null +++ b/odex25_accounting/hr_expense_petty_cash/wizards/convert_to_contract.xml @@ -0,0 +1,41 @@ + + + + convert.po.contract.wizard.form + convert.po.contract.wizard + +
    + + + + + + + + + + + + + + + +
    +
    + +
    +
    + + +
    diff --git a/odex25_accounting/journal_entry_report/__init__.py b/odex25_accounting/journal_entry_report/__init__.py new file mode 100644 index 000000000..5305644df --- /dev/null +++ b/odex25_accounting/journal_entry_report/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import models \ No newline at end of file diff --git a/odex25_accounting/journal_entry_report/__manifest__.py b/odex25_accounting/journal_entry_report/__manifest__.py new file mode 100644 index 000000000..fe9933d5c --- /dev/null +++ b/odex25_accounting/journal_entry_report/__manifest__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +{ + 'name': 'Journal Entry Report', + 'version': '1', + 'summary': 'Journal Entry Report', + 'description': """ """, + 'category': 'Odex25-Accounting/Odex25-Accounting', + 'author': "Expert Co. Ltd.", + 'website': "http://www.exp-sa.com", + 'depends': ['account'], + 'data': [ + 'views/account_move_view.xml', + 'reports/report_journal_entry.xml' + ], + + 'qweb': [], + 'installable': True, + 'application': True, + 'auto_install': False, +} diff --git a/odex25_accounting/journal_entry_report/i18n/ar.po b/odex25_accounting/journal_entry_report/i18n/ar.po new file mode 100644 index 000000000..3c40e40b5 --- /dev/null +++ b/odex25_accounting/journal_entry_report/i18n/ar.po @@ -0,0 +1,106 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * journal_entry_report +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0+e-20210105\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-05-19 05:45+0000\n" +"PO-Revision-Date: 2021-05-19 05:45+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: journal_entry_report +#: model_terms:ir.ui.view,arch_db:journal_entry_report.report_journal_entry_document +msgid "Account" +msgstr "حساب" + +#. module: journal_entry_report +#: model_terms:ir.ui.view,arch_db:journal_entry_report.report_journal_entry_document +msgid "Cost Center" +msgstr "مركز التكلفة" + +#. module: journal_entry_report +#: model_terms:ir.ui.view,arch_db:journal_entry_report.report_journal_entry_document +msgid "Credit" +msgstr "الدائن" + +#. module: journal_entry_report +#: model_terms:ir.ui.view,arch_db:journal_entry_report.report_journal_entry_document +msgid "Date" +msgstr "التاريخ" + +#. module: journal_entry_report +#: model_terms:ir.ui.view,arch_db:journal_entry_report.report_journal_entry_document +msgid "Debit" +msgstr "المدين" + +#. module: journal_entry_report +#: model_terms:ir.ui.view,arch_db:journal_entry_report.report_journal_entry_document +msgid "Details" +msgstr "التفاصيل" + +#. module: journal_entry_report +#: model:ir.model.fields,field_description:journal_entry_report.field_account_move__display_name +msgid "Display Name" +msgstr "الاسم المعروض" + +#. module: journal_entry_report +#: model:ir.model.fields,field_description:journal_entry_report.field_account_move__id +msgid "ID" +msgstr "المُعرف" + +#. module: journal_entry_report +#: model_terms:ir.ui.view,arch_db:journal_entry_report.report_journal_entry_document +msgid "Journal" +msgstr "دفتر اليومية" + +#. module: journal_entry_report +#: model:ir.actions.report,name:journal_entry_report.action_report_journal_entry +msgid "Journal Entries" +msgstr "القيود اليومية" + +#. module: journal_entry_report +#: model:ir.model,name:journal_entry_report.model_account_move +msgid "Journal Entry" +msgstr "قيد اليومية" + +#. module: journal_entry_report +#: model_terms:ir.ui.view,arch_db:journal_entry_report.report_journal_entry_document +msgid "Journal Entry Number‬(" +msgstr "رقم القيد‬(" + +#. module: journal_entry_report +#: model:ir.model.fields,field_description:journal_entry_report.field_account_move____last_update +msgid "Last Modified on" +msgstr "آخر تعديل في" + +#. module: journal_entry_report +#: model_terms:ir.ui.view,arch_db:journal_entry_report.report_journal_entry_document +msgid "Partner" +msgstr "الشريك" + +#. module: journal_entry_report +#: model_terms:ir.ui.view,arch_db:journal_entry_report.report_journal_entry_document +msgid "Ref." +msgstr "المرجع" + +#. module: journal_entry_report +#: model_terms:ir.ui.view,arch_db:journal_entry_report.report_journal_entry_document +msgid "Number" +msgstr "رقم القيد" + +#. module: journal_entry_report +#: model:ir.model.fields,field_description:journal_entry_report.field_account_move_line__einvoice +msgid "E-invoice" +msgstr "رقم الفاتورة الالكترونية" + +#. module: journal_entry_report +#: model_terms:ir.ui.view,arch_db:journal_entry_report.report_journal_entry_document +msgid "Total" +msgstr "الإجمالي" diff --git a/odex25_accounting/journal_entry_report/models/__init__.py b/odex25_accounting/journal_entry_report/models/__init__.py new file mode 100644 index 000000000..de26888c6 --- /dev/null +++ b/odex25_accounting/journal_entry_report/models/__init__.py @@ -0,0 +1,2 @@ + +from . import account_move_line \ No newline at end of file diff --git a/odex25_accounting/journal_entry_report/models/account_move_line.py b/odex25_accounting/journal_entry_report/models/account_move_line.py new file mode 100644 index 000000000..6942d3c16 --- /dev/null +++ b/odex25_accounting/journal_entry_report/models/account_move_line.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- + +from odoo import api, fields, models, _ + + +class AccountMove(models.Model): + _inherit = "account.move.line" + + einvoice = fields.Char(string="E-invoice", copy=False) diff --git a/odex25_accounting/journal_entry_report/reports/report_journal_entry.xml b/odex25_accounting/journal_entry_report/reports/report_journal_entry.xml new file mode 100644 index 000000000..e332f3e34 --- /dev/null +++ b/odex25_accounting/journal_entry_report/reports/report_journal_entry.xml @@ -0,0 +1,152 @@ + + + + + + + \ No newline at end of file diff --git a/odex25_accounting/journal_entry_report/static/description/iWesabe-Apps-Journal-Entry-Report.png b/odex25_accounting/journal_entry_report/static/description/iWesabe-Apps-Journal-Entry-Report.png new file mode 100644 index 000000000..fcf8ea3b1 Binary files /dev/null and b/odex25_accounting/journal_entry_report/static/description/iWesabe-Apps-Journal-Entry-Report.png differ diff --git a/odex25_accounting/journal_entry_report/static/description/icon.png b/odex25_accounting/journal_entry_report/static/description/icon.png new file mode 100644 index 000000000..4141f52da Binary files /dev/null and b/odex25_accounting/journal_entry_report/static/description/icon.png differ diff --git a/odex25_accounting/journal_entry_report/static/fonts/ae_AlMohanad.ttf b/odex25_accounting/journal_entry_report/static/fonts/ae_AlMohanad.ttf new file mode 100644 index 000000000..bdd7360e1 Binary files /dev/null and b/odex25_accounting/journal_entry_report/static/fonts/ae_AlMohanad.ttf differ diff --git a/odex25_accounting/journal_entry_report/static/src/css/website_rtl.css b/odex25_accounting/journal_entry_report/static/src/css/website_rtl.css new file mode 100644 index 000000000..85347c670 --- /dev/null +++ b/odex25_accounting/journal_entry_report/static/src/css/website_rtl.css @@ -0,0 +1,22 @@ +@media (min-width: 768px){ + .rtl .navbar-right{ + float: left !important; + } + .rtl .navbar-right .dropdown .dropdown-menu{ + right: auto !important; + left: 0 !important; + } + .rtl .navbar-left{ + float: right !important; + } + .rtl .navbar-left .dropdown .dropdown-menu{ + left: auto !important; + right: 0 !important; + } + .navbar-nav.navbar-right:last-child{ + margin-left: auto; + } + .rtl .pull-left{ + float: right !important; + } +} diff --git a/odex25_accounting/journal_entry_report/views/account_move_view.xml b/odex25_accounting/journal_entry_report/views/account_move_view.xml new file mode 100644 index 000000000..33188e3d0 --- /dev/null +++ b/odex25_accounting/journal_entry_report/views/account_move_view.xml @@ -0,0 +1,15 @@ + + + + + account.move.form + account.move + + + + + + + + + \ No newline at end of file diff --git a/odex25_accounting/l10n_exp/__init__.py b/odex25_accounting/l10n_exp/__init__.py new file mode 100644 index 000000000..0779d2f41 --- /dev/null +++ b/odex25_accounting/l10n_exp/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- + +from odoo.api import Environment, SUPERUSER_ID +from odoo.exceptions import ValidationError +from odoo import _ + + +def _check_modules(cr): + env = Environment(cr, SUPERUSER_ID, {}) + if env['ir.module.module'].search([('name', '=', 'l10n_exp'),('state', '!=', 'installed')]): + module = env['ir.module.module'].search([ + ('name', '=', 'account_chart_of_accounts'), + ('state', '=', 'installed') + ]) + if not module: + raise ValidationError(_('Hierarchy Chart Of Accounts (account_chart_of_accounts) must be install before installing this module.')) + + module = env['ir.module.module'].search([ + ('name', '=', 'l10n_multilang'), + ('state', '=', 'installed') + ]) + if not module: + raise ValidationError(_('Multi Language Chart of Accounts (l10n_multilang) must be install before installing this module.')) \ No newline at end of file diff --git a/odex25_accounting/l10n_exp/__manifest__.py b/odex25_accounting/l10n_exp/__manifest__.py new file mode 100644 index 000000000..1ea3c9040 --- /dev/null +++ b/odex25_accounting/l10n_exp/__manifest__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + + +{ + 'name': 'Saudi Arabia - Accounting', + 'version': '1.0', + 'category': 'Odex25-Accounting/Odex25-Accounting', + 'description': """ +This is the latest Saudi Arabia Odoo localisation necessary to run Odoo accounting for Saudi Arabia with: +================================================================================================= + - Chart of Accounts""", + + 'author': "Expert Co. Ltd.", + 'website': "http://www.exp-sa.com", + 'category': 'Accounting/Localizations/Account Charts', + 'depends': ['l10n_multilang', 'account_chart_of_accounts'], + #'pre_init_hook': '_check_modules', + 'data': [ + 'data/l10n_exp_chart_data.xml', + 'data/account.account.template.csv', + #'data/account.chart.template.csv', + 'data/account_chart_template_data.xml', + ], + 'auto_install': ['account_chart_of_accounts'], +} diff --git a/odex25_accounting/l10n_exp/data/account.account.template.csv b/odex25_accounting/l10n_exp/data/account.account.template.csv new file mode 100644 index 000000000..0b15c6ceb --- /dev/null +++ b/odex25_accounting/l10n_exp/data/account.account.template.csv @@ -0,0 +1,220 @@ +id,code,name,user_type_id/id,parent_id/id,reconcile,chart_template_id/id +account_account_46_6c73eb66,0,Company,account_chart_of_accounts.data_account_type_view,,,l10n_exp +account_account_47_d78e0779,1,Assets,account_chart_of_accounts.data_account_type_view,account_account_46_6c73eb66,,l10n_exp +account_account_65_c1509b94,11,Current Assets,account_chart_of_accounts.data_account_type_view,account_account_47_d78e0779,,l10n_exp +account_account_66_fd62e5ad,111,Cash in Banks and Funds,account_chart_of_accounts.data_account_type_view,account_account_65_c1509b94,,l10n_exp +account_account_53_7cb227ec,1111,Cash in Current Accounts,account_chart_of_accounts.data_account_type_view,account_account_66_fd62e5ad,,l10n_exp +account_account_57_cf9662ed,111101,Al Rajhi Bank,account.data_account_type_liquidity,account_account_53_7cb227ec,,l10n_exp +account_account_40_5f61e45d,111102,Al-Inma Bank,account.data_account_type_liquidity,account_account_53_7cb227ec,,l10n_exp +account_account_54_5a374538,111103,AL-Bilad Bank,account.data_account_type_liquidity,account_account_53_7cb227ec,,l10n_exp +account_account_38_0ebb4933,111104,Account pending payments receipt -Cashs,account.data_account_type_current_assets,account_account_53_7cb227ec,True,l10n_exp +account_account_39_10b7ab87,111105, Account outstanding payments receivable- cash,account.data_account_type_current_assets,account_account_53_7cb227ec,True,l10n_exp +account_account_41_6e9068fc,111106,Account pending payments receipt Banks,account.data_account_type_current_assets,account_account_53_7cb227ec,True,l10n_exp +account_account_42_b1f5d19c,111107,Account outstanding payments receivable - banks,account.data_account_type_current_assets,account_account_53_7cb227ec,True,l10n_exp +1_configurable_chart_template_liquidity_transfer,111108,Transfers Account,account.data_account_type_current_assets,account_account_53_7cb227ec,True,l10n_exp +account_account_36_e0178b31,111109,Bank Reconciliation Account,account.data_account_type_current_liabilities,account_account_53_7cb227ec,,l10n_exp +account_account_67_33fdff22,1112,Cash in Boxes,account_chart_of_accounts.data_account_type_view,account_account_66_fd62e5ad,,l10n_exp +account_account_68_19de836b,1113,Petty Cash Account,account_chart_of_accounts.data_account_type_view,account_account_66_fd62e5ad,,l10n_exp +account_account_37_0a66304e,111401,Cash Boxes,account.data_account_type_liquidity,account_account_67_33fdff22,,l10n_exp +account_account_48_45d5d5e3,111501,Employee cash covenant account,account.data_account_type_liquidity,account_account_68_19de836b,,l10n_exp +account_account_138_f7b94056,111502,Other Petty Cash,account.data_account_type_liquidity,account_account_68_19de836b,,l10n_exp +account_account_69_d82bbacb,112,Accounts Receivable,account_chart_of_accounts.data_account_type_view,account_account_65_c1509b94,,l10n_exp +account_account_70_677ecbdd,1121,Receivable,account_chart_of_accounts.data_account_type_view,account_account_69_d82bbacb,,l10n_exp +1_current_assets,112103,Employee loans and advances,account.data_account_type_current_assets,account_account_70_677ecbdd,,l10n_exp +1_pos_receivable,112104,Receipts / Receivable,account.data_account_type_receivable,account_account_70_677ecbdd,True,l10n_exp +account_account_71_60f68e70,113,Taxes,account_chart_of_accounts.data_account_type_view,account_account_65_c1509b94,,l10n_exp +account_account_72_e218ef68,1131,VAT purchases,account_chart_of_accounts.data_account_type_view,account_account_71_60f68e70,,l10n_exp +1_tax_paid,113101,VAT purchases,account.data_account_type_current_assets,account_account_72_e218ef68,,l10n_exp +account_account_74_b59bda8f,114,Advance Payments,account_chart_of_accounts.data_account_type_view,account_account_65_c1509b94,,l10n_exp +account_account_75_f2e13aa2,1141,Expenses Paid in Advance,account_chart_of_accounts.data_account_type_view,account_account_74_b59bda8f,,l10n_exp +1_prepayments,114101,Prepaid Expenses,account.data_account_type_prepayments,account_account_75_f2e13aa2,,l10n_exp +account_account_76_700e1cbe,115,Stores,account_chart_of_accounts.data_account_type_view,account_account_65_c1509b94,,l10n_exp +account_account_77_edae9703,1151,Goods and Tools Store,account_chart_of_accounts.data_account_type_view,account_account_76_700e1cbe,,l10n_exp +1_stock_valuation,115101,The main store,account.data_account_type_current_assets,account_account_77_edae9703,,l10n_exp +1_stock_in,115102,Goods on the way,account.data_account_type_current_assets,account_account_77_edae9703,True,l10n_exp +1_stock_out,115103,store under inspection,account.data_account_type_current_assets,account_account_77_edae9703,True,l10n_exp +account_account_78_321e9deb,12,Non-Current Assets,account_chart_of_accounts.data_account_type_view,account_account_47_d78e0779,,l10n_exp +account_account_79_07629e73,121,Fixed Assets,account_chart_of_accounts.data_account_type_view,account_account_78_321e9deb,,l10n_exp +account_account_80_4600c70f,1211,The Cars,account_chart_of_accounts.data_account_type_view,account_account_79_07629e73,,l10n_exp +account_account_62_286d2c1a,121101,The Cars,account.data_account_type_fixed_assets,account_account_80_4600c70f,,l10n_exp +account_account_81_bfa28ebc,1212,The Furniture,account_chart_of_accounts.data_account_type_view,account_account_79_07629e73,,l10n_exp +1_fixed_assets,121201,The Furniture,account.data_account_type_fixed_assets,account_account_81_bfa28ebc,,l10n_exp +account_account_82_a15be3d4,1213,Computers and electronic devices,account_chart_of_accounts.data_account_type_view,account_account_79_07629e73,,l10n_exp +account_account_253_4ec9623d,121301,Computers,account.data_account_type_fixed_assets,account_account_82_a15be3d4,,l10n_exp +account_account_83_33cae736,122,Other Assets,account_chart_of_accounts.data_account_type_view,account_account_78_321e9deb,,l10n_exp +account_account_84_6702a9d9,1221,Electronic Systems,account_chart_of_accounts.data_account_type_view,account_account_83_33cae736,,l10n_exp +1_non_current_assets,122101,Website,account.data_account_type_non_current_assets,account_account_84_6702a9d9,,l10n_exp +account_account_85_2e9b74d6,2,Liabilities and Equity,account_chart_of_accounts.data_account_type_view,account_account_46_6c73eb66,,l10n_exp +account_account_86_8a06bf9e,21,Current Liabilities,account_chart_of_accounts.data_account_type_view,account_account_85_2e9b74d6,,l10n_exp +account_account_87_2c3cce44,211,Short Term Commitments,account_chart_of_accounts.data_account_type_view,account_account_86_8a06bf9e,,l10n_exp +account_account_88_817af232,2111,short term loans,account_chart_of_accounts.data_account_type_view,account_account_87_2c3cce44,,l10n_exp +account_account_228_bd7c63be,211101,Short Term Loans,account.data_account_type_current_liabilities,account_account_88_817af232,,l10n_exp +account_account_90_300bdcda,2112,Short Term Payment Papers,account_chart_of_accounts.data_account_type_view,account_account_87_2c3cce44,,l10n_exp +1_current_liabilities,211201,Bills of exchange and checks,account.data_account_type_current_liabilities,account_account_90_300bdcda,,l10n_exp +account_account_89_47fb493d,212,long-term commitments,account_chart_of_accounts.data_account_type_view,account_account_86_8a06bf9e,,l10n_exp +account_account_91_9e465d19,2121,long term loans,account_chart_of_accounts.data_account_type_view,account_account_89_47fb493d,,l10n_exp +account_account_230_35218190,212102,long term loans,account.data_account_type_non_current_liabilities,account_account_91_9e465d19,,l10n_exp +account_account_92_e4127fde,2122,long-term bills of exchange,account_chart_of_accounts.data_account_type_view,account_account_89_47fb493d,,l10n_exp +account_account_229_84ec3052,212201,long-term bills of exchange,account.data_account_type_non_current_liabilities,account_account_92_e4127fde,,l10n_exp +account_account_93_01f44a26,213,creditors,account_chart_of_accounts.data_account_type_view,account_account_86_8a06bf9e,,l10n_exp +account_account_94_65ac12f8,2131,trade creditors,account_chart_of_accounts.data_account_type_view,account_account_93_01f44a26,,l10n_exp +1_receivable,213101,external suppliers,account.data_account_type_receivable,account_account_94_65ac12f8,True,l10n_exp +1_payable,213102,Creditors/ Payments,account.data_account_type_payable,account_account_94_65ac12f8,True,l10n_exp +account_account_95_8382072a,214,accrued expenses,account_chart_of_accounts.data_account_type_view,account_account_86_8a06bf9e,,l10n_exp +account_account_96_d28f20a5,2141,accrued expenses,account_chart_of_accounts.data_account_type_view,account_account_95_8382072a,,l10n_exp +1_to_receive_pay,214101,Salary and wages due,account.data_account_type_current_liabilities,account_account_96_d28f20a5,True,l10n_exp +account_account_232_f7b879b7,214103,Eligible social security,account.data_account_type_current_liabilities,account_account_96_d28f20a5,,l10n_exp +account_account_231_809292f4,214104,Payments made by clients,account.data_account_type_current_liabilities,account_account_96_d28f20a5,,l10n_exp +account_account_97_4f194535,215,Zakat provision,account_chart_of_accounts.data_account_type_view,account_account_86_8a06bf9e,,l10n_exp +account_account_98_8c546453,2151,Zakat provision,account_chart_of_accounts.data_account_type_view,account_account_97_4f194535,,l10n_exp +account_account_233_ecae933a,215101,Zakat provision,account.data_account_type_current_liabilities,account_account_98_8c546453,,l10n_exp +account_account_99_5d369744,22,Non-current obligations,account_chart_of_accounts.data_account_type_view,account_account_85_2e9b74d6,,l10n_exp +account_account_100_f1248c0d,221,credit related parties,account_chart_of_accounts.data_account_type_view,account_account_99_5d369744,,l10n_exp +account_account_101_58c25bee,2211,Accounts payable to related parties,account_chart_of_accounts.data_account_type_view,account_account_100_f1248c0d,,l10n_exp +account_account_234_497027d0,221101,Partners Drawing Accounts,account.data_account_type_equity,account_account_101_58c25bee,,l10n_exp +account_account_235_ae73fe3e,221102,Short term loan to related parties,account.data_account_type_equity,account_account_101_58c25bee,,l10n_exp +account_account_236_df111e8d,221103,Other creditor related parties,account.data_account_type_equity,account_account_101_58c25bee,,l10n_exp +account_account_102_b02675b1,222,Other credit balances,account_chart_of_accounts.data_account_type_view,account_account_99_5d369744,,l10n_exp +account_account_103_b0e622d6,2221,Other creditors,account_chart_of_accounts.data_account_type_view,account_account_102_b02675b1,,l10n_exp +account_account_238_d62e16f2,222101,temporary investments,account.data_account_type_equity,account_account_103_b0e622d6,,l10n_exp +account_account_237_9013bc14,222102,Other creditors,account.data_account_type_equity,account_account_103_b0e622d6,,l10n_exp +account_account_104_c6b44665,223,Taxes,account_chart_of_accounts.data_account_type_view,account_account_99_5d369744,,l10n_exp +account_account_105_8dc905d4,2231,Sales Tax VAT,account_chart_of_accounts.data_account_type_view,account_account_104_c6b44665,,l10n_exp +1_tax_receivable,223101,Sales Tax,account.data_account_type_current_assets,account_account_105_8dc905d4,,l10n_exp +account_account_240_91f4b7d8,223102,VAT due,account.data_account_type_current_liabilities,account_account_105_8dc905d4,,l10n_exp +account_account_106_5ef42f61,224,Allotments,account_chart_of_accounts.data_account_type_view,account_account_99_5d369744,,l10n_exp +account_account_107_2f46d77a,2241,Provision for employee obligations,account_chart_of_accounts.data_account_type_view,account_account_106_5ef42f61,,l10n_exp +account_account_241_49ec34fc,224101,Holidays allotted,account.data_account_type_non_current_liabilities,account_account_107_2f46d77a,,l10n_exp +account_account_242_7ea4fe8a,224102,custom travel tickets,account.data_account_type_non_current_liabilities,account_account_107_2f46d77a,,l10n_exp +account_account_243_6a7f90de,224103,Provision for end of severance pay,account.data_account_type_non_current_liabilities,account_account_107_2f46d77a,,l10n_exp +account_account_108_d4c7ec75,2242,other allowances,account_chart_of_accounts.data_account_type_view,account_account_106_5ef42f61,,l10n_exp +account_account_244_bbf0c0e8,224201,"Provision for doubtful debts, receivables from individuals",account.data_account_type_current_liabilities,account_account_108_d4c7ec75,,l10n_exp +account_account_245_695a09b6,224202,"Provision for doubtful debts, receivables from companies",account.data_account_type_current_liabilities,account_account_108_d4c7ec75,,l10n_exp +account_account_109_df598a12,23,Property rights,account_chart_of_accounts.data_account_type_view,account_account_85_2e9b74d6,,l10n_exp +account_account_110_f75b7972,231,Equity,account_chart_of_accounts.data_account_type_view,account_account_109_df598a12,,l10n_exp +account_account_111_98161560,2311,capital,account_chart_of_accounts.data_account_type_view,account_account_110_f75b7972,,l10n_exp +account_account_246_ebe9ecda,231101,capital,account.data_account_type_equity,account_account_111_98161560,,l10n_exp +account_account_247_5989bf9a,231102,financing for investment,account.data_account_type_equity,account_account_111_98161560,,l10n_exp +account_account_112_d0561224,232,Reserve ,account_chart_of_accounts.data_account_type_view,account_account_109_df598a12,,l10n_exp +account_account_113_706a1cf7,2321,Regular Reserve,account_chart_of_accounts.data_account_type_view,account_account_112_d0561224,,l10n_exp +account_account_248_45083bfd,232101,Regular Reserve,account.data_account_type_equity,account_account_113_706a1cf7,,l10n_exp +account_account_249_027afc8a,232102,Capital Losses,account.data_account_type_equity,account_account_113_706a1cf7,,l10n_exp +account_account_114_7b2e99ad,233,Profits and Losses,account_chart_of_accounts.data_account_type_view,account_account_109_df598a12,,l10n_exp +account_account_115_a082702d,2331,profits and losses,account_chart_of_accounts.data_account_type_view,account_account_114_7b2e99ad,,l10n_exp +account_account_43_73a28584,233101,"Profits, losses, and residuals",account.data_unaffected_earnings,account_account_115_a082702d,,l10n_exp +1_tax_received,291001,Tax Received,account.data_account_type_current_liabilities,account_account_105_8dc905d4,,l10n_exp +1_tax_payable,291002,Tax Payable,account.data_account_type_current_liabilities,account_account_105_8dc905d4,,l10n_exp +account_account_116_1c1c95fe,3,expenses,account_chart_of_accounts.data_account_type_view,account_account_46_6c73eb66,,l10n_exp +account_account_117_d7566a08,31,General and administrative expenses,account_chart_of_accounts.data_account_type_view,account_account_116_1c1c95fe,,l10n_exp +account_account_118_d6b23c93,311,Administrative expenses,account_chart_of_accounts.data_account_type_view,account_account_117_d7566a08,,l10n_exp +account_account_119_2b115ffc,3111,Salaries and Wages,account_chart_of_accounts.data_account_type_view,account_account_118_d6b23c93,,l10n_exp +account_account_147_dedc9baf,311101,basic salary,account.data_account_type_expenses,account_account_119_2b115ffc,,l10n_exp +account_account_148_990325eb,311102,housing allowance,account.data_account_type_expenses,account_account_119_2b115ffc,,l10n_exp +account_account_149_eb24deb1,311103,transportation allowance,account.data_account_type_expenses,account_account_119_2b115ffc,,l10n_exp +account_account_150_c160aa0a,311104,call exchange,account.data_account_type_expenses,account_account_119_2b115ffc,,l10n_exp +account_account_151_873e0227,311105,work nature allowance,account.data_account_type_expenses,account_account_119_2b115ffc,,l10n_exp +account_account_152_a8c2a986,311106,cost of living allowance,account.data_account_type_expenses,account_account_119_2b115ffc,,l10n_exp +account_account_153_3915aabb,311107,expatriate allowance,account.data_account_type_expenses,account_account_119_2b115ffc,,l10n_exp +account_account_154_4001295f,311108,assignment allowance,account.data_account_type_expenses,account_account_119_2b115ffc,,l10n_exp +account_account_120_1ab280d4,3112,Other staff costs,account_chart_of_accounts.data_account_type_view,account_account_118_d6b23c93,,l10n_exp +account_account_155_b3c93c17,311201,medical expenses,account.data_account_type_expenses,account_account_120_1ab280d4,,l10n_exp +account_account_156_31ee8d22,311202,medical insurance,account.data_account_type_expenses,account_account_120_1ab280d4,,l10n_exp +account_account_157_fef6b222,311203,Staff residence,account.data_account_type_expenses,account_account_120_1ab280d4,,l10n_exp +account_account_158_99631784,311204,Exit and return visa,account.data_account_type_expenses,account_account_120_1ab280d4,,l10n_exp +account_account_159_774ebe76,311205,Iqama renewal fee,account.data_account_type_expenses,account_account_120_1ab280d4,,l10n_exp +account_account_160_3d3e87b0,311206,Work permit fees,account.data_account_type_expenses,account_account_120_1ab280d4,,l10n_exp +account_account_161_f7f5b49d,311207,Service office expenses,account.data_account_type_expenses,account_account_120_1ab280d4,,l10n_exp +account_account_162_e6634720,311208,Sponsorship Transfer Fee,account.data_account_type_expenses,account_account_120_1ab280d4,,l10n_exp +account_account_163_76059d0a,311209,Training and seminars,account.data_account_type_expenses,account_account_120_1ab280d4,,l10n_exp +account_account_164_e1271be0,311210,Recruitment expenses,account.data_account_type_expenses,account_account_120_1ab280d4,,l10n_exp +account_account_166_d3ad0634,311211,Recruitment office fees,account.data_account_type_expenses,account_account_120_1ab280d4,,l10n_exp +account_account_165_f11a2e81,311212,Social Security,account.data_account_type_expenses,account_account_120_1ab280d4,,l10n_exp +account_account_167_2fe30391,311213,Work visit visa,account.data_account_type_expenses,account_account_120_1ab280d4,,l10n_exp +account_account_168_65e0166b,311214,"Licenses of the Council of Engineers, Professionals and Technicians",account.data_account_type_expenses,account_account_120_1ab280d4,,l10n_exp +account_account_169_789f90f9,311215,End of service gratuity,account.data_account_type_expenses,account_account_120_1ab280d4,,l10n_exp +account_account_170_e6a057ef,311216,Transportation and travel expenses,account.data_account_type_expenses,account_account_120_1ab280d4,,l10n_exp +account_account_171_8d5cdbab,311217,Staff salary transfer fee,account.data_account_type_expenses,account_account_120_1ab280d4,,l10n_exp +account_account_121_1994bb54,3113,"Rewards, incentives and points",account_chart_of_accounts.data_account_type_view,account_account_118_d6b23c93,,l10n_exp +account_account_172_fb45ff01,311301,Sales bonuses and commissions,account.data_account_type_expenses,account_account_121_1994bb54,,l10n_exp +account_account_173_f6e7779f,311302,temporary wages,account.data_account_type_expenses,account_account_121_1994bb54,,l10n_exp +account_account_122_905dc364,3114,Other allowances,account_chart_of_accounts.data_account_type_view,account_account_118_d6b23c93,,l10n_exp +account_account_174_5e896e98,311401,Travel ticket exchange,account.data_account_type_expenses,account_account_122_905dc364,,l10n_exp +account_account_175_f67e7e81,311402,Alternate warning period,account.data_account_type_expenses,account_account_122_905dc364,,l10n_exp +account_account_176_12f13a3c,311403,education allowance,account.data_account_type_expenses,account_account_122_905dc364,,l10n_exp +account_account_177_bbddfa7d,311404,Vacation allowance,account.data_account_type_expenses,account_account_122_905dc364,,l10n_exp +account_account_123_b5c2a7c4,3115,Licensing fees and government subscriptions,account_chart_of_accounts.data_account_type_view,account_account_118_d6b23c93,,l10n_exp +account_account_178_c0d3ac34,311501,business account fees,account.data_account_type_expenses,account_account_123_b5c2a7c4,,l10n_exp +account_account_179_b917cbdb,311502,Municipal license fees,account.data_account_type_expenses,account_account_123_b5c2a7c4,,l10n_exp +account_account_181_d936559d,311503,Chamber of Commerce subscription,account.data_account_type_expenses,account_account_123_b5c2a7c4,,l10n_exp +account_account_124_6a434946,312,General expenses,account_chart_of_accounts.data_account_type_view,account_account_117_d7566a08,,l10n_exp +account_account_125_582bd695,3121,Service charges,account_chart_of_accounts.data_account_type_view,account_account_124_6a434946,,l10n_exp +account_account_60_ad170c1f,312101,Rents,account.data_account_type_expenses,account_account_125_582bd695,,l10n_exp +account_account_183_1f5b24c7,312102,Water,account.data_account_type_expenses,account_account_125_582bd695,,l10n_exp +account_account_184_9b55bddb,312103,Electricity,account.data_account_type_expenses,account_account_125_582bd695,,l10n_exp +account_account_185_70877cd7,312104,Gasoline and motor oil,account.data_account_type_expenses,account_account_125_582bd695,,l10n_exp +account_account_186_ffa5322f,312105,Advertising,account.data_account_type_expenses,account_account_125_582bd695,,l10n_exp +account_account_187_a091e945,312106,Technical and information expenses,account.data_account_type_expenses,account_account_125_582bd695,,l10n_exp +account_account_188_2a5ed1ce,312108,Building Maintenance,account.data_account_type_expenses,account_account_125_582bd695,,l10n_exp +account_account_189_4c385ed9,312109,Computer and electronic equipment maintenance,account.data_account_type_expenses,account_account_125_582bd695,,l10n_exp +account_account_190_57672b84,312110,government services,account.data_account_type_expenses,account_account_125_582bd695,,l10n_exp +account_account_191_7ee8b51f,312111,Recruitment visas,account.data_account_type_expenses,account_account_125_582bd695,,l10n_exp +account_account_192_0a5aca1d,312112,office equipment maintenance,account.data_account_type_expenses,account_account_125_582bd695,,l10n_exp +account_account_193_e00db8e6,312113,Real estate services for the office,account.data_account_type_expenses,account_account_125_582bd695,,l10n_exp +account_account_194_4ee836b4,312114,Marketing services expenses,account.data_account_type_expenses,account_account_125_582bd695,,l10n_exp +1_cost_of_goods_sold,312115,Cost of Goods Sold,account.data_account_type_direct_costs,account_account_125_582bd695,,l10n_exp +account_account_126_f124c559,3122,Communications and mail,account_chart_of_accounts.data_account_type_view,account_account_124_6a434946,,l10n_exp +account_account_196_b1eb2c3f,312201,Phone charges and mobile bills,account.data_account_type_expenses,account_account_126_f124c559,,l10n_exp +account_account_197_7f0a6829,312202,Postage and subscription,account.data_account_type_expenses,account_account_126_f124c559,,l10n_exp +account_account_127_d924497a,3123,Service office supplies,account_chart_of_accounts.data_account_type_view,account_account_124_6a434946,,l10n_exp +account_account_195_edc46352,312301,Publications,account.data_account_type_expenses,account_account_127_d924497a,,l10n_exp +account_account_198_5ff20305,312302,Stationery and office supplies,account.data_account_type_expenses,account_account_127_d924497a,,l10n_exp +account_account_199_3b1547e0,312303,Buffet supplies,account.data_account_type_expenses,account_account_127_d924497a,,l10n_exp +account_account_128_385d1617,3124,Miscellaneous other expenses,account_chart_of_accounts.data_account_type_view,account_account_124_6a434946,,l10n_exp +account_account_61_6ff47f77,312401,municipal licenses,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_200_a6c1aca0,312402,Gifts,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_201_0dcfd64a,312403,Travel ticket expenses,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_202_3dca95a3,312404,Hotel accommodation expenses,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_203_e45c14d8,312405,Shipping and unloading expenses,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_204_288f3450,312406,Newspaper and magazine ads,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_205_7694c361,312407,Radio and TV advertisements,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_206_5240d494,312408,Internet subscription,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_207_6adc039e,312409,Consulting and technical support fees,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_208_1172372f,312410,Legalization fees,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_209_70eb8c65,312411,Subscription and exhibitions,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_210_9b3cf9f5,312412,Miscellaneous administrative expenses,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_211_506f7a3f,312413,Paying fines and violations,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_212_7f1f952d,312414,Transfer fees,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_213_1e8ca1f9,312415,Bank fees and commissions,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_214_57a204fb,312416,Sales discounts,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_215_da6e9471,312417,Shipping and delivery costs,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_216_5c90146a,312418,Service costs,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_217_053ee245,312419,Rental commissions,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_218_ae6ead8f,312420,Leisure activities and outings,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_219_b9c9750a,312421,Hospitality and petty cash,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_220_fa538654,312422,Investment profit expense,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_221_c6efd4e2,312423,Advocacy and legal advice fees,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_222_cb49e83e,312424,Legal reference fees,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_223_a475086d,312425,Declaration of zakat and income,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_224_73e56a71,312426,Fine for late payment of value added tax,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_225_f8e78964,312427,Doubtful debts,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_226_8aaded69,312428,Other subscription fees,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_227_3243e5b0,312429,Banking service fees,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +1_expense,312430,Expenses,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +1_expense_rent,312431,office rentals,account.data_account_type_expenses,account_account_128_385d1617,,l10n_exp +account_account_129_c20e9be3,313,depreciation,account_chart_of_accounts.data_account_type_view,account_account_117_d7566a08,,l10n_exp +account_account_130_23ffe55c,3131,Depreciation expense,account_chart_of_accounts.data_account_type_view,account_account_129_c20e9be3,,l10n_exp +account_account_64_da01c863,313101,Depreciation expense,account.data_account_type_depreciation,account_account_130_23ffe55c,,l10n_exp +account_account_131_dee3e8df,4,Revenues,account_chart_of_accounts.data_account_type_view,account_account_46_6c73eb66,,l10n_exp +account_account_132_ddaf24b2,41,Sales revenue,account_chart_of_accounts.data_account_type_view,account_account_131_dee3e8df,,l10n_exp +account_account_133_eab09a57,411,The sales,account_chart_of_accounts.data_account_type_view,account_account_132_ddaf24b2,,l10n_exp +account_account_134_aa3d1407,4111,cash sales,account_chart_of_accounts.data_account_type_view,account_account_133_eab09a57,,l10n_exp +account_account_140_b53efa48,411101,Returns purchases,account.data_account_type_revenue,account_account_134_aa3d1407,,l10n_exp +1_income,411102,Cash proceeds from sales of services,account.data_account_type_revenue,account_account_134_aa3d1407,,l10n_exp +account_account_135_70e50462,42,Other revenue,account_chart_of_accounts.data_account_type_view,account_account_131_dee3e8df,,l10n_exp +account_account_136_2b41da3a,421,Other sales,account_chart_of_accounts.data_account_type_view,account_account_135_70e50462,,l10n_exp +account_account_137_0b886e4d,4211,Revenue other than activity,account_chart_of_accounts.data_account_type_view,account_account_136_2b41da3a,,l10n_exp +account_account_141_24dc93b6,421101,Purchase Discounts,account.data_account_type_other_income,account_account_137_0b886e4d,,l10n_exp +account_account_142_f225ed68,421102,commission income,account.data_account_type_other_income,account_account_137_0b886e4d,,l10n_exp +account_account_143_61ad26e9,421103,rental income,account.data_account_type_other_income,account_account_137_0b886e4d,,l10n_exp +account_account_145_6bd6176a,421104,Employee discounts,account.data_account_type_other_income,account_account_137_0b886e4d,,l10n_exp +account_account_146_9eeddf1a,421105,governmental support,account.data_account_type_other_income,account_account_137_0b886e4d,,l10n_exp diff --git a/odex25_accounting/l10n_exp/data/account.chart.template.csv b/odex25_accounting/l10n_exp/data/account.chart.template.csv new file mode 100644 index 000000000..e504a4333 --- /dev/null +++ b/odex25_accounting/l10n_exp/data/account.chart.template.csv @@ -0,0 +1,2 @@ +"id","name","property_account_receivable_id:id","property_account_payable_id:id","property_account_expense_categ_id:id","property_account_income_categ_id:id","income_currency_exchange_account_id:id","expense_currency_exchange_account_id:id","default_pos_receivable_account_id:id","use_anglo_saxon" +"l10n_exp","SA Account Chart Template (by Expert)","1100","2100","5000","4000","7700","7700","1104","True" diff --git a/odex25_accounting/l10n_exp/data/account_chart_template_data.xml b/odex25_accounting/l10n_exp/data/account_chart_template_data.xml new file mode 100644 index 000000000..5774c8af5 --- /dev/null +++ b/odex25_accounting/l10n_exp/data/account_chart_template_data.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/odex25_accounting/l10n_exp/data/l10n_exp_chart_data.xml b/odex25_accounting/l10n_exp/data/l10n_exp_chart_data.xml new file mode 100644 index 000000000..e2fb986e8 --- /dev/null +++ b/odex25_accounting/l10n_exp/data/l10n_exp_chart_data.xml @@ -0,0 +1,15 @@ + + + + + + SA Account Chart Template (by Expert) + 1111 + 1112 + 1116 + 1 + + + + + diff --git a/odex25_accounting/l10n_exp/i18n/ar.po b/odex25_accounting/l10n_exp/i18n/ar.po new file mode 100644 index 000000000..f5637e935 --- /dev/null +++ b/odex25_accounting/l10n_exp/i18n/ar.po @@ -0,0 +1,1117 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_exp +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0+e-20210105\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-02021-05-26 05:04+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: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_46_6c73eb66 +msgid "Company" +msgstr "الشركة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_47_d78e0779 +msgid "Assets" +msgstr "الأصول" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_65_c1509b94 +msgid "Current Assets" +msgstr "الأصول المتداولة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_66_fd62e5ad +msgid "Cash in Banks and Funds" +msgstr "النقدية في البنوك والصناديق" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_53_7cb227ec +msgid "Cash in Current Accounts" +msgstr "النقدية في الحسابات الجارية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_57_cf9662ed +msgid "Al Rajhi Bank" +msgstr "بنك الراجحي" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_40_5f61e45d +msgid "Al-Inma Bank" +msgstr "بنك الانماء" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_54_5a374538 +msgid "AL-Bilad Bank" +msgstr "بنك البلاد" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_38_0ebb4933 +msgid "Account pending payments receipt -Cashs" +msgstr "حساب الدفعات المعلقة للصناديق" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_39_10b7ab87 +msgid " Account outstanding payments receivable- cash" +msgstr "حساب المقبوضات المعلقة للصناديق" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_41_6e9068fc +msgid "Account pending payments receipt Banks" +msgstr "حساب الدفعات المعلقة للبنوك" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_42_b1f5d19c +msgid "Account outstanding payments receivable - banks" +msgstr "حساب المقبوضات المعلقة للبنوك" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.1_configurable_chart_template_liquidity_transfer +msgid "Transfers Account" +msgstr "حساب التحويلات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_36_e0178b31 +msgid "Bank Reconciliation Account" +msgstr "حساب التسويات البنكية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_67_33fdff22 +msgid "Cash in Boxes" +msgstr "النقدية في الصناديق" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_68_19de836b +msgid "Petty Cash Account" +msgstr "حساب العهد النقدية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_37_0a66304e +msgid "Cash Boxes" +msgstr "النقدية في الصندوق" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_48_45d5d5e3 +msgid "Employee cash covenant account" +msgstr "حساب العهد النقدية لدى الموظفين" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_138_f7b94056 +msgid "Other Petty Cash" +msgstr "العهد النقدية الأخرى" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_69_d82bbacb +msgid "Accounts Receivable" +msgstr "الذمم المدينة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_70_677ecbdd +msgid "Receivable" +msgstr "المدينون" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.1_current_assets +msgid "Employee loans and advances" +msgstr "السلف والقروض لدى الموظفين" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.1_pos_receivable +msgid "Receipts / Receivable" +msgstr "ح/ المدينون / المقبوضات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_71_60f68e70 +msgid "Taxes" +msgstr "الضرائب" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_72_e218ef68 +msgid "VAT purchases" +msgstr "ضريبة القيمة المضافة - مشتريات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.1_tax_paid +msgid "VAT purchases" +msgstr "ضريبة القيمة المضافة - مشتريات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_74_b59bda8f +msgid "Advance Payments" +msgstr "المدفوعات المقدمة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_75_f2e13aa2 +msgid "Expenses Paid in Advance" +msgstr "المصروفات المدفوعة مقدماً" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.1_prepayments +msgid "Prepaid Expenses" +msgstr "المصروفات المقدمة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_76_700e1cbe +msgid "Stores" +msgstr "المخازن" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_77_edae9703 +msgid "Goods and Tools Store" +msgstr "مخزن البضائع والأدوات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.1_stock_valuation +msgid "The main store" +msgstr "المخزن الرئيسي" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.1_stock_in +msgid "Goods on the way" +msgstr "بضاعة في الطريق" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.1_stock_out +msgid "store under inspection" +msgstr "مخزن تحت الفحص" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_78_321e9deb +msgid "Non-Current Assets" +msgstr "الأصول طويلة الأجل" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_79_07629e73 +msgid "Fixed Assets" +msgstr "الأصول الثابتة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_80_4600c70f +msgid "The Cars" +msgstr "السيارات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_62_286d2c1a +msgid "The Cars" +msgstr "السيارات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_81_bfa28ebc +msgid "The Furniture" +msgstr "الأثاث والمفروشات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.1_fixed_assets +msgid "The Furniture" +msgstr "الأثاث" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_82_a15be3d4 +msgid "Computers and electronic devices" +msgstr "الأجهزة الإلكترونية والحاسبات الآلية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_253_4ec9623d +msgid "Computers" +msgstr "أجهزة الحاسب الآلي" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_83_33cae736 +msgid "Other Assets" +msgstr "الأصول الأخرى" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_84_6702a9d9 +msgid "Electronic Systems" +msgstr "الأنظمة الإلكترونية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.1_non_current_assets +msgid "Website" +msgstr "الموقع الإلكتروني" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_85_2e9b74d6 +msgid "Liabilities and Equity" +msgstr "الإلتزمات وحقوق الملكية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_86_8a06bf9e +msgid "Current Liabilities" +msgstr "الإلتزامات المتداولة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_87_2c3cce44 +msgid "Short Term Commitments" +msgstr "الإلتزامات قصيرة الأجل" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_88_817af232 +msgid "short term loans" +msgstr "القروض قصيرة الأجل" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_228_bd7c63be +msgid "Short Term Loans" +msgstr "القروض قصيرة الأجل" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_90_300bdcda +msgid "Short Term Payment Papers" +msgstr "أواق الدفع قصيرة الأجل" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.1_current_liabilities +msgid "Bills of exchange and checks" +msgstr "الكمبيالات والشيكات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_89_47fb493d +msgid "long-term commitments" +msgstr "الإلتزامات طويلة الأجل" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_91_9e465d19 +msgid "long term loans" +msgstr "القروض طويلة الأجل" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_230_35218190 +msgid "long term loans" +msgstr "القروض طويلة الأجل" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_92_e4127fde +msgid "long-term bills of exchange" +msgstr "أوراق الدفع طويلة الأجل" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_229_84ec3052 +msgid "long-term bills of exchange" +msgstr "أوراق الدفع طويلة الأجل" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_93_01f44a26 +msgid "creditors" +msgstr "الدائنون" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_94_65ac12f8 +msgid "trade creditors" +msgstr "الدائنون التجاريون" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.1_receivable +msgid "external suppliers" +msgstr "الموردين الخارجين" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.1_payable +msgid "Creditors/ Payments" +msgstr "المدفوعات / الدائنون" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_95_8382072a +msgid "accrued expenses" +msgstr "المصاريف المستحقة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_96_d28f20a5 +msgid "accrued expenses" +msgstr "المصروفات المستحقة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.1_to_receive_pay +msgid "Salary and wages due" +msgstr "رواتب وأجور مستحقة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_232_f7b879b7 +msgid "Eligible social security" +msgstr "التأمينات الاجتماعية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_231_809292f4 +msgid "Payments made by clients" +msgstr "المدفوعات المقدمة من العملاء" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_97_4f194535 +msgid "Zakat provision" +msgstr "مخصص الزكاة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_98_8c546453 +msgid "Zakat provision" +msgstr "الزكاة الشرعية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_233_ecae933a +msgid "Zakat provision" +msgstr "الزكاة الشرعية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_99_5d369744 +msgid "Non-current obligations" +msgstr "الإلتزامات غير المتداولة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_100_f1248c0d +msgid "credit related parties" +msgstr "أطراف ذات علاقة دائنة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_101_58c25bee +msgid "Accounts payable to related parties" +msgstr "ذمم دائنة لأطراف ذات علاقة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_234_497027d0 +msgid "Partners Drawing Accounts" +msgstr "جاري الشركاء" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_235_ae73fe3e +msgid "Short term loan to related parties" +msgstr "قرض قصير لأطراف ذات علاقة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_236_df111e8d +msgid "Other creditor related parties" +msgstr "أطراف دائنة ذات علاقة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_102_b02675b1 +msgid "Other credit balances" +msgstr "أرصدة دائنة أخرى" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_103_b0e622d6 +msgid "Other creditors" +msgstr "دائنون آخرون" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_238_d62e16f2 +msgid "temporary investments" +msgstr "أستثمارات مؤقتة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_237_9013bc14 +msgid "Other creditors" +msgstr "دائنون آخرون" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_104_c6b44665 +msgid "Taxes" +msgstr "الضرائب" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_105_8dc905d4 +msgid "Sales Tax VAT" +msgstr "ضريبة القيمة المضافة - مبيعات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.1_tax_receivable +msgid "Sales Tax" +msgstr "ضريبة القيمة المضافة - مبيعات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_240_91f4b7d8 +msgid "VAT due" +msgstr "ضريبة القيمة المضافة المستحقة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_106_5ef42f61 +msgid "Allotments" +msgstr "المخصصات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_107_2f46d77a +msgid "Provision for employee obligations" +msgstr "مخصص التزامات الموظفين" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_241_49ec34fc +msgid "Holidays allotted" +msgstr "مخصص الإجازات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_242_7ea4fe8a +msgid "custom travel tickets" +msgstr "مخصص تذاكر سفر" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_243_6a7f90de +msgid "Provision for end of severance pay" +msgstr "مخصص مكافأة نهاية الخدمة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_108_d4c7ec75 +msgid "other allowances" +msgstr "مخصصات أخرى" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_244_bbf0c0e8 +msgid "Provision for doubtful debts, receivables from individuals" +msgstr "مخصص ديون مشكوك في تحصيلها ذمم أفراد" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_245_695a09b6 +msgid "Provision for doubtful debts, receivables from companies" +msgstr "مخصص ديون مشكوك في تحصيلها ذمم شركات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_109_df598a12 +msgid "Property rights" +msgstr "حقوق الملكية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_110_f75b7972 +msgid "Equity" +msgstr "الأسهم" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_111_98161560 +msgid "capital" +msgstr "رأس المال" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_246_ebe9ecda +msgid "capital" +msgstr "رأس المال" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_247_5989bf9a +msgid "financing for investment" +msgstr "تمويل للإستثمار" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_112_d0561224 +msgid "Reserve " +msgstr "الاحتياطيات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_113_706a1cf7 +msgid "Regular Reserve" +msgstr "الإحتياطي النظامي" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_248_45083bfd +msgid "Regular Reserve" +msgstr "الاحتياطيات النظامية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_249_027afc8a +msgid "Capital Losses" +msgstr "خسائر رأس مالية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_114_7b2e99ad +msgid "Profits and Losses" +msgstr "الأرباح والخسائر" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_115_a082702d +msgid "profits and losses" +msgstr "أرباح وخسائر" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_43_73a28584 +msgid "Profits, losses, and residuals" +msgstr "الأرباح والخسائر والمبقاة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_252_a8e1f749 +msgid "Profits and Losses" +msgstr "الارباح و الخسائر" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.1_tax_received +msgid "Tax Received" +msgstr "الضريبة المستلمة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.1_tax_payable +msgid "Tax Payable" +msgstr "الضريبة الدائنة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_116_1c1c95fe +msgid "expenses" +msgstr "المصروفات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_117_d7566a08 +msgid "General and administrative expenses" +msgstr "المصروفات الإدارية والعمومية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_118_d6b23c93 +msgid "Administrative expenses" +msgstr "المصاريف الإدارية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_119_2b115ffc +msgid "Salaries and Wages" +msgstr "الرواتب والأجور" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_147_dedc9baf +msgid "basic salary" +msgstr "الراتب الأساسي" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_148_990325eb +msgid "housing allowance" +msgstr "بدل سكن" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_149_eb24deb1 +msgid "transportation allowance" +msgstr "بدل تنقل" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_150_c160aa0a +msgid "call exchange" +msgstr "بدل اتصال" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_151_873e0227 +msgid "work nature allowance" +msgstr "بدل طبيعة عمل" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_152_a8c2a986 +msgid "cost of living allowance" +msgstr "بدل غلاء معيشة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_153_3915aabb +msgid "expatriate allowance" +msgstr "بدل اغتراب" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_154_4001295f +msgid "assignment allowance" +msgstr "بدل انتداب" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_120_1ab280d4 +msgid "Other staff costs" +msgstr "تكاليف الموظفين الأخرى" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_155_b3c93c17 +msgid "medical expenses" +msgstr "مصاريف طبية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_156_31ee8d22 +msgid "medical insurance" +msgstr "تأمين طبي" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_157_fef6b222 +msgid "Staff residence" +msgstr "سكن الموظفين" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_158_99631784 +msgid "Exit and return visa" +msgstr "تأشيرة خروج وعودة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_159_774ebe76 +msgid "Iqama renewal fee" +msgstr "رسوم تجديد الإقامات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_160_3d3e87b0 +msgid "Work permit fees" +msgstr "رسوم رخص العمل" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_161_f7f5b49d +msgid "Service office expenses" +msgstr "مصاريف تعقيب" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_162_e6634720 +msgid "Sponsorship Transfer Fee" +msgstr "رسوم نقل الكفالة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_163_76059d0a +msgid "Training and seminars" +msgstr "التدريب والندوات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_164_e1271be0 +msgid "Recruitment expenses" +msgstr "مصاريف توظيف" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_166_d3ad0634 +msgid "Recruitment office fees" +msgstr "رسوم مكتب الاستقدام" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_165_f11a2e81 +msgid "Social Security" +msgstr "التأمينات الاجتماعية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_167_2fe30391 +msgid "Work visit visa" +msgstr "تأشيرة زيارة عمل" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_168_65e0166b +msgid "Licenses of the Council of Engineers, Professionals and Technicians" +msgstr "رخص هيئة المهندسين والمهنيين والفنيين" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_169_789f90f9 +msgid "End of service gratuity" +msgstr "مكافأة نهاية الخدمة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_170_e6a057ef +msgid "Transportation and travel expenses" +msgstr "مصروفات انتقال وسفر" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_171_8d5cdbab +msgid "Staff salary transfer fee" +msgstr "رسوم تحويل رواتب الموظفين" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_121_1994bb54 +msgid "Rewards, incentives and points" +msgstr "المكافآت والحوافز والنقاط" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_172_fb45ff01 +msgid "Sales bonuses and commissions" +msgstr "مكافآت وعمولات مبيعات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_173_f6e7779f +msgid "temporary wages" +msgstr "أجور مؤقتة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_122_905dc364 +msgid "Other allowances" +msgstr "بدلات أخرى" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_174_5e896e98 +msgid "Travel ticket exchange" +msgstr "بدل تذاكر سفر" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_175_f67e7e81 +msgid "Alternate warning period" +msgstr "بدل فترة إنذار" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_176_12f13a3c +msgid "education allowance" +msgstr "بدل تعليم" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_177_bbddfa7d +msgid "Vacation allowance" +msgstr "بدل اجازة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_123_b5c2a7c4 +msgid "Licensing fees and government subscriptions" +msgstr "رسوم تراخيص واشتراكات حكومية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_178_c0d3ac34 +msgid "business account fees" +msgstr "رسوم حساب تجاري" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_179_b917cbdb +msgid "Municipal license fees" +msgstr "مصاريف رخص البلدية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_181_d936559d +msgid "Chamber of Commerce subscription" +msgstr "اشتراك الغرفة التجارية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_124_6a434946 +msgid "General expenses" +msgstr "المصروفات العمومية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_125_582bd695 +msgid "Service charges" +msgstr "مصاريف الخدمات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_60_ad170c1f +msgid "Rents" +msgstr "ايجارات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_183_1f5b24c7 +msgid "Water" +msgstr "المياه" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_184_9b55bddb +msgid "Electricity" +msgstr "الكهرباء" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_185_70877cd7 +msgid "Gasoline and motor oil" +msgstr "بنزين وزيت للسيارات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_186_ffa5322f +msgid "Advertising" +msgstr "دعاية وإعلان" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_187_a091e945 +msgid "Technical and information expenses" +msgstr "مصاريف تقنية ومعلومات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_188_2a5ed1ce +msgid "Building Maintenance" +msgstr "صيانة مباني" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_189_4c385ed9 +msgid "Computer and electronic equipment maintenance" +msgstr "صيانة كمبيوتر وأجهزة الكترونية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_190_57672b84 +msgid "government services" +msgstr "خدمات حكومية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_191_7ee8b51f +msgid "Recruitment visas" +msgstr "تأشيرات استقدام" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_192_0a5aca1d +msgid "office equipment maintenance" +msgstr "صيانة معدات مكتبية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_193_e00db8e6 +msgid "Real estate services for the office" +msgstr "الخدمات العقارية للمكتب" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_194_4ee836b4 +msgid "Marketing services expenses" +msgstr "مصروفات خدمات التسويق" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.1_cost_of_goods_sold +msgid "Cost of Goods Sold" +msgstr "تكلفة البضاعة المباعة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_126_f124c559 +msgid "Communications and mail" +msgstr "الاتصالات والبريد" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_196_b1eb2c3f +msgid "Phone charges and mobile bills" +msgstr "رسوم الهاتف وفواتير الجوال" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_197_7f0a6829 +msgid "Postage and subscription" +msgstr "اشتراك ومصاريف البريد" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_127_d924497a +msgid "Service office supplies" +msgstr "لوازم مكتبية خدمية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_195_edc46352 +msgid "Publications" +msgstr "مطبوعات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_198_5ff20305 +msgid "Stationery and office supplies" +msgstr "قرطاسية ومستلزمات مكتبية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_199_3b1547e0 +msgid "Buffet supplies" +msgstr "مستلزمات البوفية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_128_385d1617 +msgid "Miscellaneous other expenses" +msgstr "مصاريف أخرى متنوعة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_61_6ff47f77 +msgid "municipal licenses" +msgstr "رخص البلدية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_200_a6c1aca0 +msgid "Gifts" +msgstr "هدايا" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_201_0dcfd64a +msgid "Travel ticket expenses" +msgstr "مصاريف تذاكر السفر" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_202_3dca95a3 +msgid "Hotel accommodation expenses" +msgstr "مصاريف إقامة فندقية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_203_e45c14d8 +msgid "Shipping and unloading expenses" +msgstr "مصاريف الشحن والتفريغ" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_204_288f3450 +msgid "Newspaper and magazine ads" +msgstr "اعلانات الصحف والمجلات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_205_7694c361 +msgid "Radio and TV advertisements" +msgstr "اعلانات الإذاعة والتلفزيون" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_206_5240d494 +msgid "Internet subscription" +msgstr "اشتراك الانترنت" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_207_6adc039e +msgid "Consulting and technical support fees" +msgstr "مصاريف الاستشارات والدعم الفني" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_208_1172372f +msgid "Legalization fees" +msgstr "رسوم التصديقات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_209_70eb8c65 +msgid "Subscription and exhibitions" +msgstr "اشتراك ومعارض" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_210_9b3cf9f5 +msgid "Miscellaneous administrative expenses" +msgstr "مصروفات إدارية متنوعة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_211_506f7a3f +msgid "Paying fines and violations" +msgstr "سداد المخالفات والغرامات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_212_7f1f952d +msgid "Transfer fees" +msgstr "مصاريف نقل ملكية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_213_1e8ca1f9 +msgid "Bank fees and commissions" +msgstr "عمولات ومصاريف بنكية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_214_57a204fb +msgid "Sales discounts" +msgstr "خصومات المبيعات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_215_da6e9471 +msgid "Shipping and delivery costs" +msgstr "تكاليف الشحن والتوصيل" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_216_5c90146a +msgid "Service costs" +msgstr "تكاليف خدمات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_217_053ee245 +msgid "Rental commissions" +msgstr "عمولات إيجار" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_218_ae6ead8f +msgid "Leisure activities and outings" +msgstr "نشاطات ونزهات ترفيهية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_219_b9c9750a +msgid "Hospitality and petty cash" +msgstr "مصاريف ضيافة ونثرية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_220_fa538654 +msgid "Investment profit expense" +msgstr "مصروف أرباح الاستثمار" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_221_c6efd4e2 +msgid "Advocacy and legal advice fees" +msgstr "مصاريف المحاماة والاستشارات القانونية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_222_cb49e83e +msgid "Legal reference fees" +msgstr "مصاريف المراجع القانوني" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_223_a475086d +msgid "Declaration of zakat and income" +msgstr "إقرار الزكاة والدخل" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_224_73e56a71 +msgid "Fine for late payment of value added tax" +msgstr "غرامة تأخير سداد ضريبة القيمة المضافة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_225_f8e78964 +msgid "Doubtful debts" +msgstr "مصروف ديون مشكوك في تحصيلها" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_226_8aaded69 +msgid "Other subscription fees" +msgstr "رسوم اشتراكات أخرى" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_227_3243e5b0 +msgid "Banking service fees" +msgstr "رسوم خدمات بنكية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.1_expense +msgid "Expenses" +msgstr "مصاريف متنوعة" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.1_expense_rent +msgid "office rentals" +msgstr "أيجارات المكاتب" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_129_c20e9be3 +msgid "depreciation" +msgstr "الإهلاك" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_130_23ffe55c +msgid "Depreciation expense" +msgstr "مصاريف الإهلاك" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_64_da01c863 +msgid "Depreciation expense" +msgstr "مصروفات الإهلاك" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_131_dee3e8df +msgid "Revenues" +msgstr "الإيرادات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_132_ddaf24b2 +msgid "Sales revenue" +msgstr "إيرادات المبيعات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_133_eab09a57 +msgid "The sales" +msgstr "المبيعات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_134_aa3d1407 +msgid "cash sales" +msgstr "المبيعات النقدية" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_140_b53efa48 +msgid "Returns purchases" +msgstr "مردودات المشتريات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.1_income +msgid "Cash proceeds from sales of services" +msgstr "ايرادات نقدية لمبيعات الخدمات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_135_70e50462 +msgid "Other revenue" +msgstr "الإيرادات الأخرى" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_136_2b41da3a +msgid "Other sales" +msgstr "مبيعات أخرى" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_137_0b886e4d +msgid "Revenue other than activity" +msgstr "إيرادات بخلاف النشاط" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_141_24dc93b6 +msgid "Purchase Discounts" +msgstr "خصومات المشتريات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_142_f225ed68 +msgid "commission income" +msgstr "إيراد عمولات" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_143_61ad26e9 +msgid "rental income" +msgstr "إيراد تأجير" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_145_6bd6176a +msgid "Employee discounts" +msgstr "خصومات الموظفين" + +#. module: l10n_exp +#: model:account.account.template,name:l10n_exp.account_account_146_9eeddf1a +msgid "governmental support" +msgstr "دعم حكومي" + + diff --git a/odex25_accounting/l10n_exp/static/description/icon.png b/odex25_accounting/l10n_exp/static/description/icon.png new file mode 100644 index 000000000..4141f52da Binary files /dev/null and b/odex25_accounting/l10n_exp/static/description/icon.png differ diff --git a/odex25_accounting/mis_builder/README.rst b/odex25_accounting/mis_builder/README.rst new file mode 100644 index 000000000..be45228b4 --- /dev/null +++ b/odex25_accounting/mis_builder/README.rst @@ -0,0 +1,597 @@ +=========== +MIS Builder +=========== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png + :target: https://odoo-community.org/page/development-status + :alt: Production/Stable +.. |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%2Fmis--builder-lightgray.png?logo=github + :target: https://github.com/OCA/mis-builder/tree/14.0/mis_builder + :alt: OCA/mis-builder +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/mis-builder-14-0/mis-builder-14-0-mis_builder + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/248/14.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows you to build Management Information Systems dashboards. +Such style of reports presents KPI in rows and time periods in columns. +Reports mainly fetch data from account moves, but can also combine data coming +from arbitrary Odoo models. Reports can be exported to PDF, Excel and they +can be added to Odoo dashboards. + +**Table of contents** + +.. contents:: + :local: + +Installation +============ + +Your preferred way to install addons will work with MIS Builder. + +An easy way to install it with all its dependencies is using pip: + +* ``pip install --pre odoo12-addon-mis_builder`` +* then restart Odoo, update the addons list in your database, and install + the MIS Builder application. + +Usage +===== + +To configure this module, you need to: + +* Go to Accounting > Configuration > MIS Reporting > MIS Report Templates where + you can create report templates by defining KPI's. KPI's constitute the rows of your + reports. Such report templates are time independent. + +.. figure:: https://raw.githubusercontent.com/OCA/mis-builder/10.0/mis_builder/static/description/ex_report_template.png + :alt: Sample report template + :width: 80 % + :align: center + +* Then in Accounting > Reports > MIS Reporting > MIS Reports you can create report instance by + binding the templates to time periods, hence defining the columns of your reports. + +.. figure:: https://raw.githubusercontent.com/OCA/mis-builder/10.0/mis_builder/static/description/ex_report_settings.png + :alt: Sample report configuration + :width: 80 % + :align: center + +* From the MIS Reports view, you can preview the report, add it to and Odoo dashboard, + and export it to PDF or Excel. + +.. figure:: https://raw.githubusercontent.com/OCA/mis-builder/10.0/mis_builder/static/description/ex_report_preview.png + :alt: Sample preview + :width: 80 % + :align: center + +Development +=========== + +A typical extension is to provide a mechanism to filter reports on analytic dimensions +or operational units. To implement this, you can override _get_additional_move_line_filter +and _get_additional_filter to further filter move lines or queries based on a user +selection. A typical use case could be to add an analytic account field on mis.report.instance, +or even on mis.report.instance.period if you want different columns to show different +analytic accounts. + +Known issues / Roadmap +====================== + +The mis_builder `roadmap `_ +and `known issues `_ can +be found on GitHub. + +Changelog +========= + +14.0.3.6.7 (2021-06-02) +**Bugfixes** + +- When on a MIS Report Instance, if you wanted to generate a new line of type comparison, you couldn't currently select any existing period to compare. + This happened because the field domain was searching in a NewId context, thus not finding a correct period. + Changing the domain and making it use a computed field with a search for the _origin record solves the problem. (`#361 `_) + + +14.0.3.6.6 (2021-04-23) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Bugfixes** + +- Fix drilldown action name when the account model has been customized. (`#350 `_) + + +14.0.3.6.5 (2021-04-23) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Bugfixes** + +- While duplicating a MIS report instance, comparison columns are ignored because + they would raise an error otherwise, as they keep the old source_cmpcol_from_id + and source_cmpcol_to_id from the original record. (`#343 `_) + + +14.0.3.6.4 (2021-04-06) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Features** + +- The drilldown action name displayed on the breadcrumb has been revised. + The kpi description and the account ``display_name`` are shown instead + of the kpi's technical definition. (`#304 `_) +- Add analytic group filters on report instance, periods and in the interactive + view. (`#320 `_) + + +13.0.3.6.3 (2020-08-28) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Bugfixes** + +- Having a "Compare columns" added on a KPI with an associated style using a + Factor/Divider did lead to the said factor being applied on the percentages + when exporting to XLSX. (`#300 `_) + + +**Misc** + +- `#280 `_, `#296 `_ + + +13.0.3.6.2 (2020-04-22) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Bugfixes** + +- The "Settings" button is now displayed for users with the "Show full accounting features" right when previewing a report. (`#281 `_) + + +13.0.3.6.1 (2020-04-22) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Bugfixes** + +- Fix ``TypeError: 'module' object is not iterable`` when using + budgets by account. (`#276 `_) + + +13.0.3.6.0 (2020-03-28) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Features** + +- Add column-level filters on analytic account and analytic tags. + These filters are combined with a AND with the report-level filters + and cannot be modified in the preview. (`#138 `_) +- Access to KPI from other reports in KPI expressions, aka subreports. In a + report template, one can list named "subreports" (other report templates). When + evaluating expressions, you can access KPI's of subreports with a dot-prefix + notation. Example: you can define a MIS Report for a "Balance Sheet", and then + have another MIS Report "Balance Sheet Ratios" that fetches KPI's from "Balance + Sheet" to create new KPI's for the ratios (e.g. balance_sheet.current_assets / + balance_sheet.total_assets). (`#155 `_) + + +13.0.3.5.0 (2020-01-??) +~~~~~~~~~~~~~~~~~~~~~~~ + +Migration to odoo 13.0. + +12.0.3.5.0 (2019-10-26) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Features** + +- The ``account_id`` field of the model selected in 'Move lines source' + in the Period form can now be a Many2one + relationship with any model that has a ``code`` field (not only with + ``account.account`` model). To this end, the model to be used for Actuals + move lines can be configured on the report template. It can be something else + than move lines and the only constraint is that its ``account_id`` field + has a ``code`` field. (`#149 `_) +- Add ``source_aml_model_name`` field so extension modules providing + alternative data sources can more easily customize their data source. (`#214 `_) +- Support analytic tag filters in the backend view and preview widget. + Selecting several tags in the filter means filtering on move lines which + have *all* these tags set. This is to support the most common use case of + using tags for different dimensions. The filter also makes a AND with the + analytic account filter. (`#228 `_) +- Display company in account details rows in multi-company mode. (`#242 `_) + + +**Bugfixes** + +- Propagate context to xlsx report, so the analytic account filter + works when exporting to xslx too. This also requires a fix to + ``report_xlsx`` (see https://github.com/OCA/reporting-engine/pull/259). (`#178 `_) +- In columns of type Sum, preserve styles for KPIs that are not summable + (eg percentage values). Before this fix, such cells were displayed without + style. (`#219 `_) +- In Excel export, keep the percentage point suffix (pp) instead of replacing it with %. (`#220 `_) + + +12.0.3.4.0 (2019-07-09) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Features** + +- New year-to-date mode for defining periods. (`#165 `_) +- Add support for move lines with negative debit or credit. + Used by some for storno accounting. Not officially supported. (`#175 `_) +- In Excel export, use a number format with thousands separator. The + specific separator used depends on the Excel configuration (eg regional + settings). (`#190 `_) +- Add generation date/time at the end of the XLS export. (`#191 `_) +- In presence of Sub KPIs, report more informative user errors when + non-multi expressions yield tuples of incorrect lenght. (`#196 `_) + + +**Bugfixes** + +- Fix rendering of percentage types in Excel export. (`#192 `_) + + +12.0.3.3.0 (2019-01-26) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Features** + +*Dynamic analytic filters in report preview are not yet available in 11, +this requires an update to the JS widget that proved difficult to implement +so far. Help welcome.* + +- Analytic account filters. On a report, an analytic + account can be selected for filtering. The filter will + be applied to move lines queries. A filter box is also + available in the widget to let the user select the analytic + account during report preview. (`#15 `_) +- Control visibility of analytic filter combo box in widget. + This is useful to hide the analytic filters on reports where + they do not make sense, such as balance sheet reports. (`#42 `_) +- Display analytic filters in the header of exported pdf and xls. (`#44 `_) +- Replace the last old gtk icons with fontawesome icons. (`#104 `_) +- Use active_test=False in AEP queries. + This is important for reports involving inactive taxes. + This should not negatively effect existing reports, because + an accounting report must take into account all existing move lines + even if they reference objects such as taxes, journals, accounts types + that have been deactivated since their creation. (`#107 `_) +- int(), float() and round() support for AccountingNone. (`#108 `_) +- Allow referencing subkpis by name by writing `kpi_x.subkpi_y` in expressions. (`#114 `_) +- Add an option to control the display of the start/end dates in the + column headers. It is disabled by default (this is a change compared + to previous behaviour). (`#118 `_) +- Add evaluate method to mis.report. This is a simplified + method to evaluate kpis of a report over a time period, + without creating a mis.report.instance. (`#123 `_) + +**Bugs** + +- In the style form, hide the "Hide always" checkbox when "Hide always inherit" + is checked, as for all other syle elements. (`#121 _`) + +**Upgrading from 3.2 (breaking changes)** + +If you use ``Actuals (alternative)`` data source in combination with analytic +filters, the underlying model must now have an ``analytic_account_id`` field. + + +11.0.3.2.2 (2018-06-30) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [FIX] Fix bug in company_default_get call returning + id instead of recordset + (`#103 `_) +* [IMP] add "hide always" style property to make hidden KPI's + (for KPI that serve as basis for other formulas, but do not + need to be displayed). + (`#46 `_) + +11.0.3.2.1 (2018-05-29) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [FIX] Missing comparison operator for AccountingNone + leading to errors in pbal computations + (`#93 `_) + +10.0.3.2.0 (2018-05-02) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [FIX] make subkpi ordering deterministic + (`#71 `_) +* [ADD] report instance level option to disable account expansion, + enabling the creation of detailed templates while deferring the decision + of rendering the details or not to the report instance + (`#74 `_) +* [ADD] pbal and nbal accounting expressions, to sum positive + and negative balances respectively (ie ignoring accounts with negative, + resp positive balances) + (`#86 `_) + +11.0.3.1.2 (2018-02-04) +~~~~~~~~~~~~~~~~~~~~~~~ + +Migration to Odoo 11. No new feature. +(`#67 `_) + +10.0.3.1.1 (2017-11-14) +~~~~~~~~~~~~~~~~~~~~~~~ + +New features: + +* [ADD] month and year relative periods, easier to use than + date ranges for the most common case. + (`#2 `_) +* [ADD] multi-company consolidation support, with currency conversion + (the conversion rate date is the end of the reporting period) + (`#7 `_, + `#3 `_) +* [ADD] provide ref, datetime, dateutil, time, user in the evaluation + context of move line domains; among other things, this allows using + references to xml ids (such as account types or tax tags) when + querying move lines + (`#26 `_). +* [ADD] extended account selectors: you can now select accounts using + any domain on account.account, not only account codes + ``balp[('user_type_id', '=', ref('account.data_account_type_receivable').id)]`` + (`#4 `_). +* [IMP] in the report instance configuration form, the filters are + now grouped in a notebook page, this improves readability and + extensibility + (`#39 `_). + +Bug fixes: + +* [FIX] fix error when saving periods in comparison mode on newly + created (not yet saved) report instances. + `#50 `_ +* [FIX] improve display of Base Date report instance view. + `#51 `_ + +Upgrading from 3.0 (breaking changes): + +* Alternative move line data sources must have a company_id field. + +10.0.3.0.4 (2017-10-14) +~~~~~~~~~~~~~~~~~~~~~~~ + +Bug fix: + +* [FIX] issue with initial balance rounding. + `#30 `_ + +10.0.3.0.3 (2017-10-03) +~~~~~~~~~~~~~~~~~~~~~~~ + +Bug fix: + +* [FIX] fix error saving KPI on newly created reports. + `#18 `_ + +10.0.3.0.2 (2017-10-01) +~~~~~~~~~~~~~~~~~~~~~~~ + +New features: + +* [ADD] Alternative move line source per report column. + This makes mis buidler accounting expressions work on any model + that has debit, credit, account_id and date fields. Provided you can + expose, say, committed purchases, or your budget as a view with + debit, credit and account_id, this opens up a lot of possibilities +* [ADD] Comparison column source (more flexible than the previous, + now deprecated, comparison mechanism). + CAVEAT: there is no automated migration to the new mechanism. +* [ADD] Sum column source, to create columns that add/subtract + other columns. +* [ADD] mis.kpi.data abstract model as a basis for manual KPI values + supporting automatic ajustment to the reporting time period (the basis + for budget item, but could also server other purposes, such as manually + entering some KPI values, such as number of employee) +* [ADD] mis_builder_budget module providing a new budget data source +* [ADD] new "hide empty" style property +* [IMP] new AEP method to get accounts involved in an expression + (this is useful to find which KPI relate to a given P&L + acount, to implement budget control) +* [IMP] many UI improvements +* [IMP] many code style improvements and some refactoring +* [IMP] add the column date_from, date_to in expression evaluation context, + as well as time, datetime and dateutil modules + +Main bug fixes: + +* [FIX] deletion of templates and reports (cascade and retricts) + (https://github.com/OCA/account-financial-reporting/issues/281) +* [FIX] copy of reports + (https://github.com/OCA/account-financial-reporting/issues/282) +* [FIX] better error message when periods have wrong/missing dates + (https://github.com/OCA/account-financial-reporting/issues/283) +* [FIX] xlsx export of string types KPI + (https://github.com/OCA/account-financial-reporting/issues/285) +* [FIX] sorting of detail by account +* [FIX] computation bug in detail by account when multiple accounting + expressions were used in a KPI +* [FIX] permission issue when adding report to dashboard with non admin user + +10.0.2.0.3 (unreleased) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [IMP] more robust behaviour in presence of missing expressions +* [FIX] indent style +* [FIX] local variable 'ctx' referenced before assignment when generating + reports with no objects +* [IMP] use fontawesome icons +* [MIG] migrate to 10.0 +* [FIX] unicode error when exporting to Excel +* [IMP] provide full access to mis builder style for group Adviser. + +9.0.2.0.2 (2016-09-27) +~~~~~~~~~~~~~~~~~~~~~~ + +* [IMP] Add refresh button in mis report preview. +* [IMP] Widget code changes to allow to add fields in the widget more easily. + +9.0.2.0.1 (2016-05-26) +~~~~~~~~~~~~~~~~~~~~~~ + +* [IMP] remove unused argument in declare_and_compute_period() + for a cleaner API. This is a breaking API changing merged in + urgency before it is used by other modules. + +9.0.2.0.0 (2016-05-24) +~~~~~~~~~~~~~~~~~~~~~~ + +Part of the work for this release has been done at the Sorrento sprint +April 26-29, 2016. The rest (ie a major refactoring) has been done in +the weeks after. + +* [IMP] hide button box in edit mode on the report instance settings form +* [FIX] Fix sum aggregation of non-stored fields + (https://github.com/OCA/account-financial-reporting/issues/178) +* [IMP] There is now a default style at the report level +* [CHG] Number display properties (rounding, prefix, suffix, factor) are + now defined in styles +* [CHG] Percentage difference are rounded to 1 digit instead of the kpi's + rounding, as the KPI rounding does not make sense in this case +* [CHG] The divider suffix (k, M, etc) is not inserted automatically anymore + because it is inconsistent when working with prefixes; you need to add it + manually in the suffix +* [IMP] AccountingExpressionProcessor now supports 'balu' expressions + to obtain the unallocated profit/loss of previous fiscal years; + get_unallocated_pl is the corresponding convenience method +* [IMP] AccountingExpressionProcessor now has easy methods to obtain + balances by account: get_balances_initial, get_balances_end, + get_balances_variation +* [IMP] there is now an auto-expand feature to automatically display + a detail by account for selected kpis +* [IMP] the kpi and period lists are now manipulated through forms instead + of directly in the tree views +* [IMP] it is now possible to create a report through a wizard, such + reports are deemed temporary and available through a "Last Reports Generated" + menu, they are garbaged collected automatically, unless saved permanently, + which can be done using a Save button +* [IMP] there is now a beginner mode to configure simple reports with + only one period +* [IMP] it is now easier to configure periods with fixed start/end dates +* [IMP] the new sub-kpi mechanism allows the creation of columns + with multiple values, or columns with different values +* [IMP] thanks to the new style model, the Excel export is now styled +* [IMP] a new style model is now used to centralize style configuration +* [FIX] use =like instead of like to search for accounts, because + the % are added by the user in the expressions +* [FIX] Correctly compute the initial balance of income and expense account + based on the start of the fiscal year +* [IMP] Support date ranges (from OCA/server-tools/date_range) as a more + flexible alternative to fiscal periods +* v9 migration: fiscal periods are removed, account charts are removed, + consolidation accounts have been removed + +8.0.1.0.0 (2016-04-27) +~~~~~~~~~~~~~~~~~~~~~~ + +* The copy of a MIS Report Instance now copies period. + https://github.com/OCA/account-financial-reporting/pull/181 +* The copy of a MIS Report Template now copies KPIs and queries. + https://github.com/OCA/account-financial-reporting/pull/177 +* Usability: the default view for MIS Report instances is now the rendered preview, + and the settings are accessible through a gear icon in the list view and + a button in the preview. + https://github.com/OCA/account-financial-reporting/pull/170 +* Display blank cells instead of 0.0 when there is no data. + https://github.com/OCA/account-financial-reporting/pull/169 +* Usability: better layout of the MIS Report periods settings on small screens. + https://github.com/OCA/account-financial-reporting/pull/167 +* Include the download buttons inside the MIS Builder widget, and refactor + the widget to open the door to analytic filtering in the previews. + https://github.com/OCA/account-financial-reporting/pull/151 +* Add KPI rendering prefixes (so you can print $ in front of the value). + https://github.com/OCA/account-financial-reporting/pull/158 +* Add hooks for analytic filtering. + https://github.com/OCA/account-financial-reporting/pull/128 + https://github.com/OCA/account-financial-reporting/pull/131 + +8.0.0.2.0 +~~~~~~~~~ + +Pre-history. Or rather, you need to look at the git log. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* ACSONE SA/NV + +Contributors +~~~~~~~~~~~~ + +* Stéphane Bidoul +* Laetitia Gangloff +* Adrien Peiffer +* Alexis de Lattre +* Alexandre Fayolle +* Jordi Ballester +* Thomas Binsfeld +* Giovanni Capalbo +* Marco Calcagni +* Sébastien Beau +* Laurent Mignon +* Luc De Meyer +* Benjamin Willig +* Martronic SA +* nicomacr +* Juan Jose Scarafia +* Richard deMeester +* Eric Caudal +* Andrea Stirpe +* Maxence Groine +* Arnaud Pineux +* Ernesto Tejeda +* Pedro M. Baeza + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-sbidoul| image:: https://github.com/sbidoul.png?size=40px + :target: https://github.com/sbidoul + :alt: sbidoul + +Current `maintainer `__: + +|maintainer-sbidoul| + +This module is part of the `OCA/mis-builder `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/odex25_accounting/mis_builder/__init__.py b/odex25_accounting/mis_builder/__init__.py new file mode 100644 index 000000000..d827ec98a --- /dev/null +++ b/odex25_accounting/mis_builder/__init__.py @@ -0,0 +1,6 @@ +# Copyright 2014 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from . import models +from . import wizard +from . import report diff --git a/odex25_accounting/mis_builder/__manifest__.py b/odex25_accounting/mis_builder/__manifest__.py new file mode 100644 index 000000000..2b6bf4d68 --- /dev/null +++ b/odex25_accounting/mis_builder/__manifest__.py @@ -0,0 +1,36 @@ +# Copyright 2014-2018 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +{ + "name": "MIS Builder", + "version": "14.0.3.6.7", + 'category': 'Odex25-Accounting/Odex25-Accounting', + "summary": """ + Build 'Management Information System' Reports and Dashboards + """, + "author": "ACSONE SA/NV, " "Odoo Community Association (OCA)", + "website": "https://github.com/OCA/mis-builder", + "depends": [ + "account", + "board", + "report_xlsx", # OCA/reporting-engine + "date_range", # OCA/server-ux + ], + "data": [ + "wizard/mis_builder_dashboard.xml", + "views/mis_report.xml", + "views/mis_report_instance.xml", + "views/mis_report_style.xml", + "datas/ir_cron.xml", + "security/ir.model.access.csv", + "security/mis_builder_security.xml", + "report/mis_report_instance_qweb.xml", + "report/mis_report_instance_xlsx.xml", + ], + "qweb": ["static/src/xml/mis_report_widget.xml"], + "installable": True, + "application": True, + "license": "AGPL-3", + "development_status": "Production/Stable", + "maintainers": ["sbidoul"], +} diff --git a/odex25_accounting/mis_builder/datas/ir_cron.xml b/odex25_accounting/mis_builder/datas/ir_cron.xml new file mode 100644 index 000000000..b019e1b6a --- /dev/null +++ b/odex25_accounting/mis_builder/datas/ir_cron.xml @@ -0,0 +1,13 @@ + + + + Vacuum temporary reports + 4 + hours + -1 + + + model._vacuum_report() + + + diff --git a/odex25_accounting/mis_builder/i18n/ca.po b/odex25_accounting/mis_builder/i18n/ca.po new file mode 100644 index 000000000..d113c45cb --- /dev/null +++ b/odex25_accounting/mis_builder/i18n/ca.po @@ -0,0 +1,2023 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mis_builder +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2020-08-31 13:00+0000\n" +"Last-Translator: brendapaniagua \n" +"Language-Team: none\n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.10\n" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "%s (copy)" +msgstr "%s (còpia)" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[('user_type_id', '=',\n" +" ref('account.\n" +" data_account_type_receivable')." +"id)][]\n" +" \n" +" : variation of the balance of " +"all receivable\n" +" accounts over the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[][('tax_line_id." +"tag_ids', '=',\n" +" ref('l10n_be.tax_tag_56')." +"id)]\n" +" \n" +" : balance of move lines related " +"to tax grid\n" +" 56." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" debp[55%][('journal_id." +"code', '=',\n" +" 'BNK1')]\n" +" \n" +" : sum of all debits on accounts " +"55 and\n" +" journal BNK1 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"AccountingNone\n" +" : a null value that behaves as 0 " +"in\n" +" arithmetic operations." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal, crd, deb, pbal, nbal\n" +" : balance, debit, credit, " +"positive balance,\n" +" negative balance." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal[70]\n" +" : variation of the balance of " +"account 70\n" +" over the period (it is the same " +"as balp[70]." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bale[1%]\n" +" : balance of accounts starting " +"with 1 at end\n" +" of period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bali[70,60]\n" +" : initial balance of accounts 70 " +"and 60." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"balu[]\n" +" : (u for unallocated) is a " +"special\n" +" expression that shows the " +"unallocated\n" +" profit/loss of previous\n" +" fiscal years." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"crdp[40%]\n" +" : sum of all credits on accounts " +"starting\n" +" with 40 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"date_from, date_to\n" +" : beginning and end date of the " +"period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"datetime, datetime, dateutil\n" +" : the python modules." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"p, i, e\n" +" : respectively variation over " +"the period,\n" +" initial balance, ending balance" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"pbale[55%]\n" +" : sum of all ending balances of " +"accounts\n" +" starting with 55 whose\n" +" ending balance is positive." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"sum, min, max, len, avg\n" +" : behave as expected, very " +"similar to the\n" +" python builtins." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields." +msgstr "" +"Model que sigui 'de tipus apunt' , és a dir, que tingui almenys els camps " +"debit, credit, date, account_id y company_id." + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__move_lines_source +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields. This model is the data source for column Actuals." +msgstr "" +"Un model \"com a línia de moviment\", és a dir, que tingui almenys camps de " +"dèbit, crèdit, data, account_id i company_id. Aquest model és l’origen de " +"dades de la columna Actuals." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "A date filter is mandatory for this source in column %s." +msgstr "Un filtre de data és obligatori per aquest origen a la columna %s." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__account_model +msgid "Account model" +msgstr "Model de compte" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__accumulation_method +msgid "Accumulation Method" +msgstr "Mètode d'agregació" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "" +"Actual (alternative) models used in columns must have the same account model " +"in the Account field and must be the same defined in the report template: %s" +msgstr "" +"Els models actuals (alternatius) utilitzats a les columnes han de tenir el " +"mateix model de compte al camp Compte i han de ser els mateixos definits a " +"la plantilla de l’informe: %s" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals +msgid "Actuals" +msgstr "Dades reals" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals_alt +msgid "Actuals (alternative)" +msgstr "Dades reals (alternativa)" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source +msgid "" +"Actuals: current data, from accounting and other queries.\n" +"Actuals (alternative): current data from an alternative source (eg a " +"database view providing look-alike account move lines).\n" +"Sum columns: summation (+/-) of other columns.\n" +"Compare to column: compare to other column.\n" +msgstr "" +"Dades reals: dades actuals provinents de la comptabilitat i altres " +"consultes.\n" +"Dades reals (alternativa): dades actuals provinents d'un origen alternatiu " +"(per exemple, vista de la base de dades proveint registres de \"tipus apunt" +"\").\n" +"Suma de columnes: sumarització (+/-) d'altres columnes.\n" +"Comparar columnes: comparació amb una altra columna.\n" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_prorata_read_group_mixin +msgid "Adapt model with date_from/date_to for pro-rata temporis read_group" +msgstr "" +"Adapta el model amb data_from / date_to per al grup de lectura de temporis " +"pro-rata" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_add_to_dashboard_action +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Add to dashboard" +msgstr "Afegir al taulell" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Additionally following variables are available\n" +" in the evaluation context:" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__aggregate +msgid "Aggregate" +msgstr "Agregació" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__all +msgid "All Entries" +msgstr "Tots els assentaments" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__all_kpi_ids +msgid "All Kpi" +msgstr "Tot Kpi" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__posted +msgid "All Posted Entries" +msgstr "Tots els assentaments assentats" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__allowed_cmpcol_ids +msgid "Allowed Cmpcol" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__amount +msgid "Amount" +msgstr "Import" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__style_expression +msgid "" +"An expression that returns a style depending on the KPI value. Such style is " +"applied on top of the row style." +msgstr "" +"Una expressió que retorna un estil depenent del valor del KPI. Aquest estil " +"s'aplica a la part superior de l'estil de la fila." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_account_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "Analytic Account" +msgstr "Compte Analític" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Account Filter" +msgstr "Filtre Analític de Comptes" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_group_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_group_id +#, python-format +msgid "Analytic Account Group" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account Group: %s" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account: %s" +msgstr "Compte Analític: %s" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_tag_ids +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "Analytic Tags" +msgstr "Etiquetes Analítiques" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Tags Filter" +msgstr "Filtre d'Etiquetes Analítiques" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Tags: %s" +msgstr "Etiquetes Analítiques: %s" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Auto expand" +msgstr "Auto expandir" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__avg +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__avg +#, python-format +msgid "Average" +msgstr "Mitjana" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color +msgid "Background Color" +msgstr "Color del fons" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color_inherit +msgid "Background Color Inherit" +msgstr "Color del fons heretat" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__background_color +msgid "Background color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "Color del fons utilitzant un codi RGB vàlid (de #000000 a #FFFFFF)" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date +msgid "Base date" +msgstr "Data base" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__bold +msgid "Bold" +msgstr "Negreta" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Can not update a multi kpi from the kpi line" +msgstr "No es pot actualitzar un kpi múltiple des d'una línia de kpi" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Cancel" +msgstr "Cancel·lar" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__multi_company +msgid "" +"Check if you wish to specify children companies to be searched for data." +msgstr "" +"Comprovi si desitja especificar companyies filles per a buscar-hi dades." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Color" +msgstr "Color" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color_inherit +msgid "Color Inherit" +msgstr "Color heretat" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_to_sum_id +msgid "Column" +msgstr "Columna" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Column %s cannot be compared to itrec." +msgstr "La columna %s no es pot comparar amb itrec." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, fuzzy, python-format +msgid "Column %s with move lines source must have from/to dates." +msgstr "La columna %s amb font de dades reals ha de tenir data des de/fins a." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Columns" +msgstr "Columnes" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Columns to compare must belong to the same report in %s" +msgstr "Les columnes a comparar han de pertànyer al mateix informe en %s" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_ids +msgid "Columns to sum" +msgstr "Columnes a sumar" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "Columns {} and {} are not comparable" +msgstr "Les columnes {} i {} no són comparables" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_ids +msgid "Companies" +msgstr "Companyies" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__query_company_ids +msgid "Companies for which data will be searched." +msgstr "Companyies per a les que es buscaran dades." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_id +msgid "Company" +msgstr "Companyia" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_to_id +msgid "Compare" +msgstr "Comparar" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__cmpcol +msgid "Compare columns" +msgstr "Comparar columnes" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__compare_method +msgid "Comparison Method" +msgstr "Mètode de comparació" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__comparison_mode +msgid "Comparison Mode" +msgstr "Mode de comparació" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_uid +msgid "Created by" +msgstr "Creat per" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_date +msgid "Created on" +msgstr "Creat el" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__currency_id +msgid "Currency" +msgstr "Moneda" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__dashboard_id +msgid "Dashboard" +msgstr "Taulell" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date +msgid "Date" +msgstr "Data" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__date_field +msgid "Date Field" +msgstr "Camp data" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_from +msgid "Date From" +msgstr "Data Des de" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_range_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_id +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__date_range +#, python-format +msgid "Date Range" +msgstr "Rang de dates" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_type_id +msgid "Date Range Type" +msgstr "Tipus de rang de dates" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_to +msgid "Date To" +msgstr "Data a" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Dates" +msgstr "Dates" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__d +#, python-format +msgid "Day" +msgstr "Dia" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__description +msgid "Description" +msgstr "Descripció" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__accumulation_method +msgid "" +"Determines how values of this kpi spanning over a time period are " +"transformed to match the reporting period. Sum: values of shorter period are " +"added, values of longest or partially overlapping periods are adjusted pro-" +"rata temporis.\n" +"Average: values of included period are averaged with a pro-rata temporis " +"weight." +msgstr "" +"Determina com els valors d'aquest kpi transcorrent sobre el període de temps " +"són transformats per casar amb el període de l'informe. Sum: s'afegeixen els " +"valors del període més curt, i els valors del més llarg o de períodes que " +"solapen parcialment s'ajusten prorratejant-se en el temps.\n" +"Mitjana: els valors del període inclòs fan mitjana amb el pes del prorrateig " +"temporal." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__diff +#, python-format +msgid "Difference" +msgstr "Diferència" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__no_auto_expand_accounts +msgid "Disable account details expansion" +msgstr "Desactiva l'expansió dels detalls del compte" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display Columns Description" +msgstr "Mostrar Columnes Descripció" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__display_name +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__display_name +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__display_name +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__display_name +msgid "Display Name" +msgstr "Nom a mostrar" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts +msgid "Display details by account" +msgstr "Mostrar detalls per compte" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display the date range details in the column headers." +msgstr "Mostra els detalls de l'interval de dates a les capçaleres de columna." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider_inherit +msgid "Divider Inherit" +msgstr "Divisor heretat" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__domain +msgid "Domain" +msgstr "Domini" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp_inherit +msgid "Dp Inherit" +msgstr "Dp heretat" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_prorata_read_group_mixin__date +msgid "" +"Dummy field that adapts searches on date to searches on date_from/date_to." +msgstr "" +"Camp dummy que adapta les cerques en data a les cerques en data_from / " +"date_to." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__duration +msgid "Duration" +msgstr "Durada" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Enter expression here, for example balp[70%]. See also help tab." +msgstr "" +"Introdueixi l'expressió aquí, per exemple [balp70%]. Vegi també la pestanya " +"d'ajuda." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Examples:" +msgstr "Exemples:" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Export" +msgstr "Exportar" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__expression_ids +msgid "Expression" +msgstr "Expressió" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions" +msgstr "Expressions" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions can be any valid python expressions." +msgstr "Les expressions poden ser qualsevol expressió vàlida de Python." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Expressions can involve other KPI, sub KPI and\n" +" query results by name (eg kpi1 + " +"kpi2,\n" +" kpi2.subkpi1, query1.field1)." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__normalize_factor +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider +msgid "Factor" +msgstr "Factor" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Factor inherit" +msgstr "Factor heretat" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__normalize_factor +msgid "Factor to use to normalize the period (used in comparison" +msgstr "" +"El factor s'utilitza per a normalitzar el període (utilitzat en la comparació" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_names +msgid "Fetched fields name" +msgstr "Nom dels camps obtinguts" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_ids +msgid "Fields to fetch" +msgstr "Camps a obtenir" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "" +"Filter column on journal entries that have all these analytic tags.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" +"Filtra la columna de les entrades de diari que tenen totes aquestes " +"etiquetes analítiques. Aquest filtre es combina amb un AND amb els filtres a " +"nivell d’informe i no es pot modificar en la previsualització." + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_group_id +msgid "" +"Filter column on journal entries that match this analytic account group. " +"This filter is combined with a AND with the report-level filters and cannot " +"be modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "" +"Filter column on journal entries that match this analytic account.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" +"Filtra la columna de les entrades de diari que coincideixen amb aquest " +"compte analític. Aquest filtre es combina amb un AND amb els filtres a " +"nivell d’informe i no es pot modificar en la previsualització." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Filters" +msgstr "Filtres" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__fix +msgid "Fixed dates" +msgstr "Dates fixes" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Font" +msgstr "Font" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size +msgid "Font Size" +msgstr "Tamany del tipus de lletra" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size_inherit +msgid "Font Size Inherit" +msgstr "Tamany del tipus de lletra heretat" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style +msgid "Font Style" +msgstr "Estil del tipus de lletra" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style_inherit +msgid "Font Style Inherit" +msgstr "Estil del tipus de lletra heretat" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight +msgid "Font Weight" +msgstr "Tamany del tipus de lletra" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight_inherit +msgid "Font Weight Inherit" +msgstr "Tamany del tipus de lletra heretat" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Forces the start date to Jan 1st of the relevant year" +msgstr "Obliga la data d'inici a l'1 de gener de l'any corresponent" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_from +msgid "From" +msgstr "Des de" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_from +msgid "From (computed)" +msgstr "Des de (computat)" + +#. module: mis_builder +#: code:addons/mis_builder/report/mis_report_instance_xlsx.py:0 +#, python-format +msgid "Generated on {} at {}" +msgstr "Generat el dia {} a {}" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Help (for KPI expressions)" +msgstr "Ajuda (per a les expressions del KPI)" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always +msgid "Hide Always" +msgstr "Amagar sempre" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always_inherit +msgid "Hide Always Inherit" +msgstr "Amagar sempre heretat" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__hide_analytic_filters +msgid "Hide Analytic Filters" +msgstr "Amagar filtres analítics" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty +msgid "Hide Empty" +msgstr "Amagar buits" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty_inherit +msgid "Hide Empty Inherit" +msgstr "Amagar buits heretat" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__id +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__id +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__id +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__id +msgid "ID" +msgstr "ID" + +#. module: mis_builder +#: code:addons/mis_builder/models/aep.py:0 +#, python-format +msgid "" +"If currency_id is not provided, all companies must have the same currency." +msgstr "" +"Si no es proveeix el camp currency_id, totes les companyies han de tenir la " +"mateixa moneda." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Indent" +msgstr "Sagnat" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level +msgid "Indent Level" +msgstr "Nivell de sagnat" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level_inherit +msgid "Indent Level Inherit" +msgstr "Nivell de sagnat heretat" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "Indent level must be greater than or equal to 0" +msgstr "EL nivell de sagnat ha de ser igual o major que 0" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__italic +msgid "Italic" +msgstr "Cursiva" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__kpi_expression_id +msgid "KPI" +msgstr "KPI" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" has type {} while a tuple was expected.\n" +"\n" +"This can be fixed by either:\n" +"\t- Changing the KPI value to a tuple of length {}\n" +"or\n" +"\t- Changing the KPI to `multi` mode and giving an explicit value for each " +"sub-KPI." +msgstr "" +"El KPI \"{}\" té el tipus {} mentre s'esperava una tupla.\n" +"\n" +"Això es pot solucionar amb:\n" +"- Canviant el valor del KPI per una tupla de longitud {}\n" +"o\n" +"- Canviar el KPI al mode `multi` i donar un valor explícit a cada sub-KPI." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" is valued as a tuple of length {} while a tuple of length {} is " +"expected." +msgstr "" +"El KPI \"{}\" es valora com a tupla de longitud {} mentre que s'espera una " +"tupla de longitud {}." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq1 +msgid "KPI Sequence" +msgstr "Seqüència KPI" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "KPI name ({}) must be a valid python identifier" +msgstr "El nom del KPI ({}) ha de ser un identificador Python vàlid" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__kpi_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "KPI's" +msgstr "KPI's" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__all_kpi_ids +msgid "KPIs of this report and subreports." +msgstr "KPIs d’aquest informe i subinformes." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__kpi_id +msgid "Kpi" +msgstr "KPI" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__name +msgid "Label" +msgstr "Etiqueta" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__landscape_pdf +msgid "Landscape PDF" +msgstr "PDF apaïsat" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard____last_update +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport____last_update +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin____last_update +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx____last_update +msgid "Last Modified on" +msgstr "Última modificació el" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.last_mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.last_wizard_mis_report_instance_view_menu +msgid "Last Reports Generated" +msgstr "Últims informes generats" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_uid +msgid "Last Updated by" +msgstr "Última actualització per" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_date +msgid "Last Updated on" +msgstr "Última actualització el" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Layout" +msgstr "Disseny" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_report_mis_builder_mis_report_instance_xlsx +#, fuzzy +msgid "MIS Builder XLSX report" +msgstr "Informe XLS d'instància d'informe MIS" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_kpi_data +msgid "MIS Kpi Data Abtract class" +msgstr "Classe abstracta de dades KPI MIS" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "MIS Report" +msgstr "Informe MIS" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subreport +msgid "MIS Report - Sub Reports Relation" +msgstr "Informe MIS - Relació Subinformes" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_add_mis_report_instance_dashboard_wizard +#, fuzzy +msgid "MIS Report Add to Dashboard Wizard" +msgstr "Informe MIS Afegir a l'assistent de tauler de control" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "MIS Report Instance" +msgstr "Instància d'informe MIS" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period +#, fuzzy +msgid "MIS Report Instance Period" +msgstr "Període Instància d'Informe MIS" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period_sum +#, fuzzy +msgid "MIS Report Instance Period Sum" +msgstr "Suma Període Instància d'informe MIS" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "MIS Report Instances" +msgstr "Instàncies d'informes MIS" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "MIS Report KPI" +msgstr "KPI d'informe MIS" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi_expression +msgid "MIS Report KPI Expression" +msgstr "Expressió de KPI del informe MIS" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_query +msgid "MIS Report Query" +msgstr "Consultar informe MIS" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_result_view_form +msgid "MIS Report Result" +msgstr "Resultat d'informe MIS" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_style +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "MIS Report Style" +msgstr "Estil de format MIS" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_style_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_style_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_tree +msgid "MIS Report Styles" +msgstr "Estils d'informes MIS" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subkpi +msgid "MIS Report Sub-KPI" +msgstr "Consulta d'informe MIS" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report +msgid "MIS Report Template" +msgstr "Plantilla d'informe MIS" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_view_menu +msgid "MIS Report Templates" +msgstr "Plantilles d'informe MIS" + +#. module: mis_builder +#: model:ir.ui.menu,name:mis_builder.mis_report_conf_menu +#: model:ir.ui.menu,name:mis_builder.mis_report_finance_menu +msgid "MIS Reporting" +msgstr "MIS" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_instance_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_tree +msgid "MIS Reports" +msgstr "Informes MIS" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.qweb_pdf_export +msgid "MIS report instance QWEB PDF report" +msgstr "Informe QWeb PDF d'instància d'informe MIS" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.xls_export +msgid "MIS report instance XLS report" +msgstr "Informe XLS d'instància d'informe MIS" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__max +#, python-format +msgid "Max" +msgstr "Màx" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__min +#, python-format +msgid "Min" +msgstr "Mín" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__mode +msgid "Mode" +msgstr "Mode" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__model_id +msgid "Model" +msgstr "Model" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__m +#, python-format +msgid "Month" +msgstr "Mes" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__move_lines_source +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "Move lines source" +msgstr "Origen dels apunts" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_name +#, fuzzy +msgid "Move lines source model name" +msgstr "Mou el nom del model d'origen de les línies." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__multi +msgid "Multi" +msgstr "Multi" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__multi_company +msgid "Multiple companies" +msgstr "Múltiples companyies" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__name +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Name" +msgstr "Nom" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__none +msgid "No date filter" +msgstr "Sense filtre de dates" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "No date filter is allowed for this source in column %s." +msgstr "No es permet un filtre de data per aquesta font a la columna %s." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__none +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__none +#, python-format +msgid "None" +msgstr "Res" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__normal +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__nornal +msgid "Normal" +msgstr "Normal" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Number" +msgstr "Número" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__duration +msgid "Number of periods" +msgstr "Número de períodes" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__num +#, python-format +msgid "Numeric" +msgstr "Numèric" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__offset +msgid "Offset" +msgstr "Desplaçament" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__offset +msgid "Offset from current period" +msgstr "Desplaçament del període actual" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_id +msgid "Parent column" +msgstr "Columna pare" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__pct +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__pct +#, python-format +msgid "Percentage" +msgstr "Percentatge" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_name_unique +msgid "Period name should be unique by report" +msgstr "El nom del període ha de ser únic a cada informe" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__type +msgid "Period type" +msgstr "Tipus de període" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__period_ids +msgid "Periods" +msgstr "Períodes" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__pivot_date +msgid "Pivot date" +msgstr "Data pivot" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Please provide both columns to compare in %s." +msgstr "Si us plau, introdueixi ambdues columnes a comparar en %s." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix +msgid "Prefix" +msgstr "Prefix" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix_inherit +msgid "Prefix Inherit" +msgstr "Prefix heretat" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Preview" +msgstr "Previsualitzar" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Print" +msgstr "Imprimeix" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__query_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Queries" +msgstr "Consultes" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__query_company_ids +msgid "Query Company" +msgstr "Companyia de la consulta" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, fuzzy, python-format +msgid "Query name ({}) must be valid python identifier" +msgstr "El nom de la consulta ({}) ha de ser un identificador Python vàlid" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Refresh" +msgstr "Actualitzar" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__relative +msgid "Relative to report base date" +msgstr "Relatiu a la data base de l'informe" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__report_id +msgid "Report" +msgstr "Informe" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_ir_actions_report +msgid "Report Action" +msgstr "Informar de l'acció" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_instance_id +msgid "Report Instance" +msgstr "Instància de l'informe" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__date +msgid "Report base date (leave empty to use current date)" +msgstr "Data base de l'informe (deixar buida per a utilitzar la data actual)" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp +msgid "Rounding" +msgstr "Arrodoniment" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Rounding inherit" +msgstr "Arrodoniment heretat" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Save" +msgstr "Guardar" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__company_ids +msgid "Select companies for which data will be searched." +msgstr "Seleccioni les companyies per a les que es buscaran les dades." + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__currency_id +msgid "" +"Select target currency for the report. Required if companies have different " +"currencies." +msgstr "" +"Seleccioni la moneda objectiu per a l'informe. Es requereix si les " +"companyies tenen monedes diferents." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__sequence +msgid "Sequence" +msgstr "Seqüència" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Settings" +msgstr "Configuració" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_subreport_unique +#, fuzzy +msgid "" +"Should not include the same report more than once as sub report of a given " +"report" +msgstr "" +"No hauria d’incloure el mateix informe més d’una vegada que el subinforme " +"d’un informe determinat" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__sign +msgid "Sign" +msgstr "Símbol" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Source" +msgstr "Origen" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__str +#, python-format +msgid "String" +msgstr "Cadena" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__style_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_id +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Style" +msgstr "Estil" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_expression +msgid "Style expression" +msgstr "Expressió d'estil" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts_style_id +msgid "Style for account detail rows" +msgstr "Estil per a les files de detall de compte" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__name +msgid "Style name" +msgstr "Nom de l'estil" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subkpi_ids +msgid "Sub KPI" +msgstr "Sub KPI" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__subkpi_ids +msgid "Sub KPI Filter" +msgstr "Filtre del sub KPI" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_kpi_expression_subkpi_kpi_unique +msgid "Sub KPI must be used once and only once for each KPI" +msgstr "El sub KPI ha d'utilitzar-se només una vegada per a cada KPI" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Sub KPI's" +msgstr "Sub KPI's" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Sub Reports" +msgstr "Subinformes" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subreport_ids +msgid "Sub reports" +msgstr "Subinformes" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq2 +msgid "Sub-KPI Sequence" +msgstr "Seqüència Sub-KPI" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Sub-KPI name ({}) must be a valid python identifier" +msgstr "El nom Sub-KPI ({}) ha de ser un identificador Python vàlid" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__subkpi_id +msgid "Subkpi" +msgstr "SubKPI" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__subreport_id +msgid "Subreport" +msgstr "Subinforme" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, python-format +msgid "Subreport loop detected" +msgstr "S'ha detectat un bucle de subinforme" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, python-format +msgid "Subreport name ({}) must be a valid python identifier" +msgstr "El nom del subinforme ({}) ha de ser un identificador Python vàlid" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_name_unique +#, fuzzy +msgid "Subreport name should be unique by report" +msgstr "El nom del subinforme ha de ser únic per a cada informe" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix +msgid "Suffix" +msgstr "Sufix" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix_inherit +msgid "Suffix Inherit" +msgstr "Sufix heretat" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__sum +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__sum +#, python-format +msgid "Sum" +msgstr "Suma" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_accdet +msgid "Sum account details" +msgstr "Detalls de compte de la suma" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "" +"Sum cannot be computed in column {} because the columns to sum have no " +"common subkpis" +msgstr "" +"La suma no pot ser calculada a la columa {} perquè les columnes a sumar no " +"tenen subkpis comuns" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__sumcol +msgid "Sum columns" +msgstr "Suma de columnes" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__target_move +msgid "Target Moves" +msgstr "Apunts objectiu" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "Template" +msgstr "Plantilla" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__temporary +msgid "Temporary" +msgstr "Temporal" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color +msgid "Text color" +msgstr "Color de text" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__color +msgid "Text color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "Color de text en un codi RGB vàlid (des de #000000 fins a #FFFFFF)" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" account selector\n" +" is a like expression on the " +"account code (eg\n" +" 70%, etc)." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" journal items domain\n" +" is an Odoo domain filter on " +"journal items." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The following special elements are recognized in\n" +" the expressions to compute " +"accounting data:\n" +" \n" +" {bal|crd|deb|pbal|nbal}{pieu}" +"[account\n" +" selector][journal items domain]\n" +" \n" +" ." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_to +msgid "To" +msgstr "Fins a" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_to +msgid "To (computed)" +msgstr "Per (calculat)" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_kpi_data.py:0 +#, python-format +msgid "Unexpected accumulation method %s for %s." +msgstr "Mètode d'acumulació %s no esperat per a %s." + +#. module: mis_builder +#: code:addons/mis_builder/models/prorata_read_group_mixin.py:0 +#, python-format +msgid "Unsupported operator %s for searching on date" +msgstr "Operador %s no compatible per cercar la data" + +#. module: mis_builder +#: model:ir.actions.server,name:mis_builder.ir_cron_vacuum_temp_reports_ir_actions_server +#: model:ir.cron,cron_name:mis_builder.ir_cron_vacuum_temp_reports +#: model:ir.cron,name:mis_builder.ir_cron_vacuum_temp_reports +msgid "Vacuum temporary reports" +msgstr "Buit d'informes temporals" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__valid +msgid "Valid" +msgstr "Vàlid" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__type +msgid "Value type" +msgstr "Tipus del valor" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Visibility" +msgstr "Visibilitat" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__w +#, python-format +msgid "Week" +msgstr "Setmana" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_duration +msgid "Wrong duration, it must be positive!" +msgstr "Duració incorrecta, ha de ser positiva!" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_normalize_factor +msgid "Wrong normalize factor, it must be positive!" +msgstr "Factor de normalització incorrecte. Ha de ser positiu!" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__y +#, python-format +msgid "Year" +msgstr "Any" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Year to date" +msgstr "Any fins a la data" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "You cannot sum period %s with itself." +msgstr "No pot sumar el període %s amb ell mateix." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "from %s to %s" +msgstr "Des de %s fins a %s" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__large +msgid "large" +msgstr "gran" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__medium +msgid "medium" +msgstr "mitjana" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "or" +msgstr "o" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "pp" +msgstr "pp" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__small +msgid "small" +msgstr "petita" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_from_id +msgid "versus" +msgstr "contra" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-large +msgid "x-large" +msgstr "extra-gran" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-small +msgid "x-small" +msgstr "extra-petita" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-large +msgid "xx-large" +msgstr "extra-súper-gran" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-small +msgid "xx-small" +msgstr "extra-súper-petita" + +#~ msgid "" +#~ "AccountingNone: a null value that behaves as 0 in arithmetic " +#~ "operations." +#~ msgstr "" +#~ "AccountingNone: un valor nul que es comporta com a 0 en operacions " +#~ "aritmètiques." + +#~ msgid "" +#~ "bal, crd, deb, pbal, nbal: balance, debit, credit, positive " +#~ "balance, negative balance." +#~ msgstr "" +#~ "bal, crd, deb, pbal, nbal: saldo, deure, haver, saldo positiu, " +#~ "saldo negatiu." + +#~ msgid "" +#~ "bal[70]: variation of the balance of account 70 over the period " +#~ "(it is the same as balp[70]." +#~ msgstr "" +#~ "bal[70]: variació del saldo del compte 70 en el període (és el " +#~ "mateix que balp[70]." + +#~ msgid "" +#~ "bale[1%]: balance of accounts starting with 1 at end of period." +#~ msgstr "" +#~ "bale[1%]: saldo al final del període dels comptes que comencen amb " +#~ "1." + +#~ msgid "bali[70,60]: initial balance of accounts 70 and 60." +#~ msgstr "bali[70,60]: Saldo inicial dels comptes 70 i 60." + +#~ msgid "" +#~ "balp[('user_type_id', '=', ref('account.data_account_type_receivable')." +#~ "id)][]: variation of the balance of all receivable accounts over the " +#~ "period." +#~ msgstr "" +#~ "balp[('user_type_id', '=', ref('account.data_account_type_receivable')." +#~ "id)][]: variació del saldo de tots els comptes a cobrar en el període." + +#~ msgid "" +#~ "balp[][('tax_line_id.tag_ids', '=', ref('l10n_be.tax_tag_56').id)]: balance of move lines related to tax grid 56." +#~ msgstr "" +#~ "balp[][('tax_line_id.tag_ids', '=', ref('l10n_be.tax_tag_56').id)]: saldo dels apunts relacionats amb l'etiqueta d'impost 56." + +#~ msgid "" +#~ "balu[]: (u for unallocated) is a special expression that shows the " +#~ "unallocated profit/loss of previous\n" +#~ " fiscal years." +#~ msgstr "" +#~ "balu[]: (u for unallocated) es una expressió especial que mostra " +#~ "les pèrdues y guanys sense assignar dels exercicis fiscals\n" +#~ "anteriors." + +#~ msgid "" +#~ "crdp[40%]: sum of all credits on accounts starting with 40 during " +#~ "the period." +#~ msgstr "" +#~ "crdp[40%]: suma de tots els haver dels comptes que comencen per 40 " +#~ "durant el període." + +#~ msgid "date_from, date_to: beginning and end date of the period." +#~ msgstr "date_from, date_to: data d'inici i data de fi del període." + +#~ msgid "datetime, datetime, dateutil: the python modules." +#~ msgstr "datetime, datetime, dateutil: els mòduls python." + +#~ msgid "" +#~ "debp[55%][('journal_id.code', '=', 'BNK1')]: sum of all debits on " +#~ "accounts 55 and journal BNK1 during the period." +#~ msgstr "" +#~ "debp[55%][('journal_id.code', '=', 'BNK1')]: suma de tots els " +#~ "deure dels comptes que comencen per 55 i en el diari BNK1 durant el " +#~ "període." + +#, fuzzy +#~ msgid "" +#~ "p, i, e: respectively variation over the period, initial balance, " +#~ "ending balance" +#~ msgstr "" +#~ "p, i, e: variació sobre el període, sobre el saldo inicial o sobre " +#~ "el saldo final respectivament" + +#~ msgid "" +#~ "pbale[55%]: sum of all ending balances of accounts starting with " +#~ "55 whose\n" +#~ " ending balance is positive." +#~ msgstr "" +#~ "pbale[55%]: suma de tots els saldos finals dels comptes que " +#~ "comencen per 55\n" +#~ " el saldo final dels quals és positiu." + +#~ msgid "" +#~ "sum, min, max, len, avg: behave as expected, very similar to the " +#~ "python builtins." +#~ msgstr "" +#~ "sum, min, max, len, avg: es comporten com s'espera, molt similars " +#~ "als nadius de Python." + +#~ msgid "" +#~ "Additionally following variables are available in the evaluation context:" +#~ msgstr "" +#~ "Les següents variables addicionals estan disponibles en el context " +#~ "d'avaluació:" + +#~ msgid "" +#~ "Expressions can involve other KPI, sub KPI and query results by name (eg " +#~ "kpi1 + kpi2, kpi2.subkpi1, query1.field1)." +#~ msgstr "" +#~ "L'expressió també pot incloure altres KPI ,sub KPI i resultats de " +#~ "consulta per nom (per exemple, kpi1 + kpi2)." + +#~ msgid "" +#~ "The account selector is a like expression on the account code (eg " +#~ "70%, etc)." +#~ msgstr "" +#~ "El selector de compte és com una expressió en el codi de compte " +#~ "(per exemple, 70%, etc)." + +#~ msgid "" +#~ "The journal items domain is an Odoo domain filter on journal items." +#~ msgstr "" +#~ "El domini dels apunts és un filtre de domini Odoo sobe els apunts." + +#, fuzzy +#~ msgid "" +#~ "The following special elements are recognized in the expressions to " +#~ "compute accounting data:\n" +#~ " {bal|crd|deb|pbal|nbal}" +#~ "{pieu}[account selector][journal items domain]." +#~ msgstr "" +#~ "Els següents elements són reconeguts a les expressions per a calcular " +#~ "dades comptables:\n" +#~ " {bal|crd|deb|pbal|nbal}" +#~ "{pieu}[account selector][journal items domain]." + +#~ msgid "MIS Budget" +#~ msgstr "Pressupost MIS" + +#~ msgid "report.mis_builder.mis_report_instance_xlsx" +#~ msgstr "report.mis_builder.mis_report_instance_xlsx" + +#~ msgid "" +#~ "Probably not your fault... but I'm really curious to know how you managed " +#~ "to raise this error so I can handle one more corner case!" +#~ msgstr "" +#~ "Probablement no és culpa seva... però realment tinc curiositat per saber " +#~ "com ha aconseguit aquest error per a poder gestionar un cas extrem més!" + +#~ msgid "µ" +#~ msgstr "µ" + +#~ msgid "add.mis.report.instance.dashboard.wizard" +#~ msgstr "add.mis.report.instance.dashboard.wizard" + +#~ msgid "ir.actions.report" +#~ msgstr "ir.actions.report" + +#~ msgid "mis.report" +#~ msgstr "mis.report" + +#~ msgid "mis.report.instance" +#~ msgstr "mis.report.instance" + +#~ msgid "mis.report.instance.period" +#~ msgstr "mis.report.instance.period" + +#~ msgid "mis.report.instance.period.sum" +#~ msgstr "mis.report.instance.period.sum" + +#~ msgid "mis.report.kpi" +#~ msgstr "mis.report.kpi" + +#~ msgid "mis.report.kpi.expression" +#~ msgstr "mis.report.kpi.expression" + +#~ msgid "mis.report.query" +#~ msgstr "mis.report.query" + +#~ msgid "mis.report.style" +#~ msgstr "mis.report.style" + +#~ msgid "mis.report.subkpi" +#~ msgstr "mis.report.subkpi" diff --git a/odex25_accounting/mis_builder/i18n/de.po b/odex25_accounting/mis_builder/i18n/de.po new file mode 100644 index 000000000..6417ae909 --- /dev/null +++ b/odex25_accounting/mis_builder/i18n/de.po @@ -0,0 +1,1858 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mis_builder +# +# Translators: +# Rudolf Schnapka , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-02-05 01:43+0000\n" +"PO-Revision-Date: 2018-02-05 01:43+0000\n" +"Last-Translator: Rudolf Schnapka , 2018\n" +"Language-Team: German (https://www.transifex.com/oca/teams/23907/de/)\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "%s (copy)" +msgstr "%s (Kopie)" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[('user_type_id', '=',\n" +" ref('account.\n" +" data_account_type_receivable')." +"id)][]\n" +" \n" +" : variation of the balance of " +"all receivable\n" +" accounts over the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[][('tax_line_id." +"tag_ids', '=',\n" +" ref('l10n_be.tax_tag_56')." +"id)]\n" +" \n" +" : balance of move lines related " +"to tax grid\n" +" 56." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" debp[55%][('journal_id." +"code', '=',\n" +" 'BNK1')]\n" +" \n" +" : sum of all debits on accounts " +"55 and\n" +" journal BNK1 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"AccountingNone\n" +" : a null value that behaves as 0 " +"in\n" +" arithmetic operations." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal, crd, deb, pbal, nbal\n" +" : balance, debit, credit, " +"positive balance,\n" +" negative balance." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal[70]\n" +" : variation of the balance of " +"account 70\n" +" over the period (it is the same " +"as balp[70]." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bale[1%]\n" +" : balance of accounts starting " +"with 1 at end\n" +" of period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bali[70,60]\n" +" : initial balance of accounts 70 " +"and 60." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"balu[]\n" +" : (u for unallocated) is a " +"special\n" +" expression that shows the " +"unallocated\n" +" profit/loss of previous\n" +" fiscal years." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"crdp[40%]\n" +" : sum of all credits on accounts " +"starting\n" +" with 40 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"date_from, date_to\n" +" : beginning and end date of the " +"period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"datetime, datetime, dateutil\n" +" : the python modules." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"p, i, e\n" +" : respectively variation over " +"the period,\n" +" initial balance, ending balance" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"pbale[55%]\n" +" : sum of all ending balances of " +"accounts\n" +" starting with 55 whose\n" +" ending balance is positive." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"sum, min, max, len, avg\n" +" : behave as expected, very " +"similar to the\n" +" python builtins." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__move_lines_source +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields. This model is the data source for column Actuals." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "A date filter is mandatory for this source in column %s." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__account_model +msgid "Account model" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__accumulation_method +msgid "Accumulation Method" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "" +"Actual (alternative) models used in columns must have the same account model " +"in the Account field and must be the same defined in the report template: %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals +msgid "Actuals" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals_alt +msgid "Actuals (alternative)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source +msgid "" +"Actuals: current data, from accounting and other queries.\n" +"Actuals (alternative): current data from an alternative source (eg a " +"database view providing look-alike account move lines).\n" +"Sum columns: summation (+/-) of other columns.\n" +"Compare to column: compare to other column.\n" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_prorata_read_group_mixin +msgid "Adapt model with date_from/date_to for pro-rata temporis read_group" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_add_to_dashboard_action +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Add to dashboard" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Additionally following variables are available\n" +" in the evaluation context:" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__aggregate +msgid "Aggregate" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__all +msgid "All Entries" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__all_kpi_ids +msgid "All Kpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__posted +msgid "All Posted Entries" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__allowed_cmpcol_ids +msgid "Allowed Cmpcol" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__amount +msgid "Amount" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__style_expression +msgid "" +"An expression that returns a style depending on the KPI value. Such style is " +"applied on top of the row style." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_account_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "Analytic Account" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Account Filter" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_group_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_group_id +#, python-format +msgid "Analytic Account Group" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account Group: %s" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account: %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_tag_ids +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "Analytic Tags" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Tags Filter" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Tags: %s" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Auto expand" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__avg +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__avg +#, python-format +msgid "Average" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color +msgid "Background Color" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color_inherit +msgid "Background Color Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__background_color +msgid "Background color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date +msgid "Base date" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__bold +msgid "Bold" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Can not update a multi kpi from the kpi line" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Cancel" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__multi_company +msgid "" +"Check if you wish to specify children companies to be searched for data." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Color" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color_inherit +msgid "Color Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_to_sum_id +msgid "Column" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Column %s cannot be compared to itrec." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Column %s with move lines source must have from/to dates." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Columns" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Columns to compare must belong to the same report in %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_ids +msgid "Columns to sum" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "Columns {} and {} are not comparable" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_ids +msgid "Companies" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__query_company_ids +msgid "Companies for which data will be searched." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_id +msgid "Company" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_to_id +msgid "Compare" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__cmpcol +msgid "Compare columns" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__compare_method +msgid "Comparison Method" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__comparison_mode +msgid "Comparison Mode" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_uid +msgid "Created by" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_date +msgid "Created on" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__currency_id +msgid "Currency" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__dashboard_id +msgid "Dashboard" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date +msgid "Date" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__date_field +msgid "Date Field" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_from +msgid "Date From" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_range_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_id +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__date_range +#, python-format +msgid "Date Range" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_type_id +msgid "Date Range Type" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_to +msgid "Date To" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Dates" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__d +#, python-format +msgid "Day" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__description +msgid "Description" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__accumulation_method +msgid "" +"Determines how values of this kpi spanning over a time period are " +"transformed to match the reporting period. Sum: values of shorter period are " +"added, values of longest or partially overlapping periods are adjusted pro-" +"rata temporis.\n" +"Average: values of included period are averaged with a pro-rata temporis " +"weight." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__diff +#, python-format +msgid "Difference" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__no_auto_expand_accounts +msgid "Disable account details expansion" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display Columns Description" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__display_name +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__display_name +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__display_name +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__display_name +msgid "Display Name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts +msgid "Display details by account" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display the date range details in the column headers." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider_inherit +msgid "Divider Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__domain +msgid "Domain" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp_inherit +msgid "Dp Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_prorata_read_group_mixin__date +msgid "" +"Dummy field that adapts searches on date to searches on date_from/date_to." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__duration +msgid "Duration" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Enter expression here, for example balp[70%]. See also help tab." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Examples:" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Export" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__expression_ids +msgid "Expression" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions can be any valid python expressions." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Expressions can involve other KPI, sub KPI and\n" +" query results by name (eg kpi1 + " +"kpi2,\n" +" kpi2.subkpi1, query1.field1)." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__normalize_factor +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider +msgid "Factor" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Factor inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__normalize_factor +msgid "Factor to use to normalize the period (used in comparison" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_names +msgid "Fetched fields name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_ids +msgid "Fields to fetch" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "" +"Filter column on journal entries that have all these analytic tags.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_group_id +msgid "" +"Filter column on journal entries that match this analytic account group. " +"This filter is combined with a AND with the report-level filters and cannot " +"be modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "" +"Filter column on journal entries that match this analytic account.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Filters" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__fix +msgid "Fixed dates" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Font" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size +msgid "Font Size" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size_inherit +msgid "Font Size Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style +msgid "Font Style" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style_inherit +msgid "Font Style Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight +msgid "Font Weight" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight_inherit +msgid "Font Weight Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Forces the start date to Jan 1st of the relevant year" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_from +msgid "From" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_from +msgid "From (computed)" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/report/mis_report_instance_xlsx.py:0 +#, python-format +msgid "Generated on {} at {}" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Help (for KPI expressions)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always +msgid "Hide Always" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always_inherit +msgid "Hide Always Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__hide_analytic_filters +msgid "Hide Analytic Filters" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty +msgid "Hide Empty" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty_inherit +msgid "Hide Empty Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__id +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__id +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__id +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__id +msgid "ID" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/aep.py:0 +#, python-format +msgid "" +"If currency_id is not provided, all companies must have the same currency." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Indent" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level +msgid "Indent Level" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level_inherit +msgid "Indent Level Inherit" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "Indent level must be greater than or equal to 0" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__italic +msgid "Italic" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__kpi_expression_id +msgid "KPI" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" has type {} while a tuple was expected.\n" +"\n" +"This can be fixed by either:\n" +"\t- Changing the KPI value to a tuple of length {}\n" +"or\n" +"\t- Changing the KPI to `multi` mode and giving an explicit value for each " +"sub-KPI." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" is valued as a tuple of length {} while a tuple of length {} is " +"expected." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq1 +msgid "KPI Sequence" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "KPI name ({}) must be a valid python identifier" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__kpi_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "KPI's" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__all_kpi_ids +msgid "KPIs of this report and subreports." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__kpi_id +msgid "Kpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__name +msgid "Label" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__landscape_pdf +msgid "Landscape PDF" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard____last_update +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport____last_update +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin____last_update +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx____last_update +msgid "Last Modified on" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.last_mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.last_wizard_mis_report_instance_view_menu +msgid "Last Reports Generated" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_date +msgid "Last Updated on" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Layout" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_report_mis_builder_mis_report_instance_xlsx +msgid "MIS Builder XLSX report" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_kpi_data +msgid "MIS Kpi Data Abtract class" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "MIS Report" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subreport +msgid "MIS Report - Sub Reports Relation" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_add_mis_report_instance_dashboard_wizard +msgid "MIS Report Add to Dashboard Wizard" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "MIS Report Instance" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period +msgid "MIS Report Instance Period" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period_sum +msgid "MIS Report Instance Period Sum" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "MIS Report Instances" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "MIS Report KPI" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi_expression +msgid "MIS Report KPI Expression" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_query +msgid "MIS Report Query" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_result_view_form +msgid "MIS Report Result" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_style +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "MIS Report Style" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_style_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_style_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_tree +msgid "MIS Report Styles" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subkpi +msgid "MIS Report Sub-KPI" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report +msgid "MIS Report Template" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_view_menu +msgid "MIS Report Templates" +msgstr "" + +#. module: mis_builder +#: model:ir.ui.menu,name:mis_builder.mis_report_conf_menu +#: model:ir.ui.menu,name:mis_builder.mis_report_finance_menu +msgid "MIS Reporting" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_instance_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_tree +msgid "MIS Reports" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.qweb_pdf_export +msgid "MIS report instance QWEB PDF report" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.xls_export +msgid "MIS report instance XLS report" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__max +#, python-format +msgid "Max" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__min +#, python-format +msgid "Min" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__mode +msgid "Mode" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__model_id +msgid "Model" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__m +#, python-format +msgid "Month" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__move_lines_source +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "Move lines source" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_name +msgid "Move lines source model name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__multi +msgid "Multi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__multi_company +msgid "Multiple companies" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__name +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__none +msgid "No date filter" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "No date filter is allowed for this source in column %s." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__none +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__none +#, python-format +msgid "None" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__normal +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__nornal +msgid "Normal" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Number" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__duration +msgid "Number of periods" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__num +#, python-format +msgid "Numeric" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__offset +msgid "Offset" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__offset +msgid "Offset from current period" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_id +msgid "Parent column" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__pct +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__pct +#, python-format +msgid "Percentage" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_name_unique +msgid "Period name should be unique by report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__type +msgid "Period type" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__period_ids +msgid "Periods" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__pivot_date +msgid "Pivot date" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Please provide both columns to compare in %s." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix +msgid "Prefix" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix_inherit +msgid "Prefix Inherit" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Preview" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Print" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__query_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Queries" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__query_company_ids +msgid "Query Company" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Query name ({}) must be valid python identifier" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Refresh" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__relative +msgid "Relative to report base date" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__report_id +msgid "Report" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_ir_actions_report +msgid "Report Action" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_instance_id +msgid "Report Instance" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__date +msgid "Report base date (leave empty to use current date)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp +msgid "Rounding" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Rounding inherit" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Save" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__company_ids +msgid "Select companies for which data will be searched." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__currency_id +msgid "" +"Select target currency for the report. Required if companies have different " +"currencies." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__sequence +msgid "Sequence" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Settings" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_subreport_unique +msgid "" +"Should not include the same report more than once as sub report of a given " +"report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__sign +msgid "Sign" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Source" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__str +#, python-format +msgid "String" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__style_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_id +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Style" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_expression +msgid "Style expression" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts_style_id +msgid "Style for account detail rows" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__name +msgid "Style name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subkpi_ids +msgid "Sub KPI" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__subkpi_ids +msgid "Sub KPI Filter" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_kpi_expression_subkpi_kpi_unique +msgid "Sub KPI must be used once and only once for each KPI" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Sub KPI's" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Sub Reports" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subreport_ids +msgid "Sub reports" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq2 +msgid "Sub-KPI Sequence" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Sub-KPI name ({}) must be a valid python identifier" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__subkpi_id +msgid "Subkpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__subreport_id +msgid "Subreport" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, python-format +msgid "Subreport loop detected" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, python-format +msgid "Subreport name ({}) must be a valid python identifier" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_name_unique +msgid "Subreport name should be unique by report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix +msgid "Suffix" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix_inherit +msgid "Suffix Inherit" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__sum +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__sum +#, python-format +msgid "Sum" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_accdet +msgid "Sum account details" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "" +"Sum cannot be computed in column {} because the columns to sum have no " +"common subkpis" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__sumcol +msgid "Sum columns" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__target_move +msgid "Target Moves" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "Template" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__temporary +msgid "Temporary" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color +msgid "Text color" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__color +msgid "Text color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" account selector\n" +" is a like expression on the " +"account code (eg\n" +" 70%, etc)." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" journal items domain\n" +" is an Odoo domain filter on " +"journal items." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The following special elements are recognized in\n" +" the expressions to compute " +"accounting data:\n" +" \n" +" {bal|crd|deb|pbal|nbal}{pieu}" +"[account\n" +" selector][journal items domain]\n" +" \n" +" ." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_to +msgid "To" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_to +msgid "To (computed)" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_kpi_data.py:0 +#, python-format +msgid "Unexpected accumulation method %s for %s." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/prorata_read_group_mixin.py:0 +#, python-format +msgid "Unsupported operator %s for searching on date" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.server,name:mis_builder.ir_cron_vacuum_temp_reports_ir_actions_server +#: model:ir.cron,cron_name:mis_builder.ir_cron_vacuum_temp_reports +#: model:ir.cron,name:mis_builder.ir_cron_vacuum_temp_reports +msgid "Vacuum temporary reports" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__valid +msgid "Valid" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__type +msgid "Value type" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Visibility" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__w +#, python-format +msgid "Week" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_duration +msgid "Wrong duration, it must be positive!" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_normalize_factor +msgid "Wrong normalize factor, it must be positive!" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__y +#, python-format +msgid "Year" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Year to date" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "You cannot sum period %s with itself." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "from %s to %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__large +msgid "large" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__medium +msgid "medium" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "or" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "pp" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__small +msgid "small" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_from_id +msgid "versus" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-large +msgid "x-large" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-small +msgid "x-small" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-large +msgid "xx-large" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-small +msgid "xx-small" +msgstr "" + +#~ msgid "" +#~ "AccountingNone: a null value that behaves as 0 in arithmetic " +#~ "operations." +#~ msgstr "" +#~ "BuchhaltungsNull: Ein Null-Wert, der sich wie 0 in arithmetischen " +#~ "Berechnungen verhält." + +#, fuzzy +#~ msgid "" +#~ "bal, crd, deb, pbal, nbal: balance, debit, credit, positive " +#~ "balance, negative balance." +#~ msgstr "bal, crd, deb: Saldo, Haben, Soll." + +#~ msgid "" +#~ "bal[70]: variation of the balance of account 70 over the period " +#~ "(it is the same as balp[70]." +#~ msgstr "" +#~ "bal[70]: Abwandlung des Saldo von Konto 70 über die Zeit (Dies " +#~ "entspricht balp[70])." + +#~ msgid "" +#~ "bale[1%]: balance of accounts starting with 1 at end of period." +#~ msgstr "" +#~ "bale[1%]: Saldo der Konten die mit 1 beginnen zum Ende der Periode." + +#~ msgid "bali[70,60]: initial balance of accounts 70 and 60." +#~ msgstr "bali[70,60]: Eröffnungssaldo der Konten 70 und 60." + +#~ msgid "" +#~ "balp[('user_type_id', '=', ref('account.data_account_type_receivable')." +#~ "id)][]: variation of the balance of all receivable accounts over the " +#~ "period." +#~ msgstr "" +#~ "balp[('user_type_id', '=', ref('account.data_account_type_receivable')." +#~ "id)][]: Abwandlung des Saldo aller Forderungskonten über die Zeit." + +#~ msgid "" +#~ "balp[][('tax_line_id.tag_ids', '=', ref('l10n_be.tax_tag_56').id)]: balance of move lines related to tax grid 56." +#~ msgstr "" +#~ "balp[][('tax_line_id.tag_ids', '=', ref('l10n_be.tax_tag_56').id)]: Saldo der Buchungen mit Steuerschlüssel 56 ." + +#~ msgid "" +#~ "balu[]: (u for unallocated) is a special expression that shows the " +#~ "unallocated profit/loss of previous\n" +#~ " fiscal years." +#~ msgstr "" +#~ "balu[]: (u für nicht zugewiesen) ist ein spezieller Ausdruck, der " +#~ "nicht zugewiesene Gewinne/Verluste der Vorjahre ausweist." + +#~ msgid "" +#~ "crdp[40%]: sum of all credits on accounts starting with 40 during " +#~ "the period." +#~ msgstr "" +#~ "crdp[40%]: Summe aller Haben auf Konten, die mit 40 beginnen, über " +#~ "die Zeit." + +#~ msgid "date_from, date_to: beginning and end date of the period." +#~ msgstr "date_from, date_to: Anfangs- und Enddatum der Periode." + +#~ msgid "datetime, datetime, dateutil: the python modules." +#~ msgstr "datetime, datetime, dateutil: die Python-Methoden." + +#~ msgid "" +#~ "debp[55%][('journal_id.code', '=', 'BNK1')]: sum of all debits on " +#~ "accounts 55 and journal BNK1 during the period." +#~ msgstr "" +#~ "debp[55%][('journal_id.code', '=', 'BNK1')]: Die Summe aller Soll " +#~ "der Konten 55 und Journal BNK1 über die Periode.." + +#, fuzzy +#~ msgid "" +#~ "p, i, e: respectively variation over the period, initial balance, " +#~ "ending balance" +#~ msgstr "" +#~ "p, i, e: jeweilige Abwandlung über Zeit, Eröffnungssaldo, Endsaldo" diff --git a/odex25_accounting/mis_builder/i18n/el.po b/odex25_accounting/mis_builder/i18n/el.po new file mode 100644 index 000000000..f341dc43c --- /dev/null +++ b/odex25_accounting/mis_builder/i18n/el.po @@ -0,0 +1,1776 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mis_builder +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "%s (copy)" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[('user_type_id', '=',\n" +" ref('account.\n" +" data_account_type_receivable')." +"id)][]\n" +" \n" +" : variation of the balance of " +"all receivable\n" +" accounts over the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[][('tax_line_id." +"tag_ids', '=',\n" +" ref('l10n_be.tax_tag_56')." +"id)]\n" +" \n" +" : balance of move lines related " +"to tax grid\n" +" 56." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" debp[55%][('journal_id." +"code', '=',\n" +" 'BNK1')]\n" +" \n" +" : sum of all debits on accounts " +"55 and\n" +" journal BNK1 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"AccountingNone\n" +" : a null value that behaves as 0 " +"in\n" +" arithmetic operations." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal, crd, deb, pbal, nbal\n" +" : balance, debit, credit, " +"positive balance,\n" +" negative balance." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal[70]\n" +" : variation of the balance of " +"account 70\n" +" over the period (it is the same " +"as balp[70]." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bale[1%]\n" +" : balance of accounts starting " +"with 1 at end\n" +" of period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bali[70,60]\n" +" : initial balance of accounts 70 " +"and 60." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"balu[]\n" +" : (u for unallocated) is a " +"special\n" +" expression that shows the " +"unallocated\n" +" profit/loss of previous\n" +" fiscal years." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"crdp[40%]\n" +" : sum of all credits on accounts " +"starting\n" +" with 40 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"date_from, date_to\n" +" : beginning and end date of the " +"period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"datetime, datetime, dateutil\n" +" : the python modules." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"p, i, e\n" +" : respectively variation over " +"the period,\n" +" initial balance, ending balance" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"pbale[55%]\n" +" : sum of all ending balances of " +"accounts\n" +" starting with 55 whose\n" +" ending balance is positive." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"sum, min, max, len, avg\n" +" : behave as expected, very " +"similar to the\n" +" python builtins." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__move_lines_source +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields. This model is the data source for column Actuals." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "A date filter is mandatory for this source in column %s." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__account_model +msgid "Account model" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__accumulation_method +msgid "Accumulation Method" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "" +"Actual (alternative) models used in columns must have the same account model " +"in the Account field and must be the same defined in the report template: %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals +msgid "Actuals" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals_alt +msgid "Actuals (alternative)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source +msgid "" +"Actuals: current data, from accounting and other queries.\n" +"Actuals (alternative): current data from an alternative source (eg a " +"database view providing look-alike account move lines).\n" +"Sum columns: summation (+/-) of other columns.\n" +"Compare to column: compare to other column.\n" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_prorata_read_group_mixin +msgid "Adapt model with date_from/date_to for pro-rata temporis read_group" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_add_to_dashboard_action +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Add to dashboard" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Additionally following variables are available\n" +" in the evaluation context:" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__aggregate +msgid "Aggregate" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__all +msgid "All Entries" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__all_kpi_ids +msgid "All Kpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__posted +msgid "All Posted Entries" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__allowed_cmpcol_ids +msgid "Allowed Cmpcol" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__amount +msgid "Amount" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__style_expression +msgid "" +"An expression that returns a style depending on the KPI value. Such style is " +"applied on top of the row style." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_account_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "Analytic Account" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Account Filter" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_group_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_group_id +#, python-format +msgid "Analytic Account Group" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account Group: %s" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account: %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_tag_ids +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "Analytic Tags" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Tags Filter" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Tags: %s" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Auto expand" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__avg +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__avg +#, python-format +msgid "Average" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color +msgid "Background Color" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color_inherit +msgid "Background Color Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__background_color +msgid "Background color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date +msgid "Base date" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__bold +msgid "Bold" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Can not update a multi kpi from the kpi line" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Cancel" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__multi_company +msgid "" +"Check if you wish to specify children companies to be searched for data." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Color" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color_inherit +msgid "Color Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_to_sum_id +msgid "Column" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Column %s cannot be compared to itrec." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Column %s with move lines source must have from/to dates." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Columns" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Columns to compare must belong to the same report in %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_ids +msgid "Columns to sum" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "Columns {} and {} are not comparable" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_ids +msgid "Companies" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__query_company_ids +msgid "Companies for which data will be searched." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_id +msgid "Company" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_to_id +msgid "Compare" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__cmpcol +msgid "Compare columns" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__compare_method +msgid "Comparison Method" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__comparison_mode +msgid "Comparison Mode" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_uid +msgid "Created by" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_date +msgid "Created on" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__currency_id +msgid "Currency" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__dashboard_id +msgid "Dashboard" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date +msgid "Date" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__date_field +msgid "Date Field" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_from +msgid "Date From" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_range_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_id +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__date_range +#, python-format +msgid "Date Range" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_type_id +msgid "Date Range Type" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_to +msgid "Date To" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Dates" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__d +#, python-format +msgid "Day" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__description +msgid "Description" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__accumulation_method +msgid "" +"Determines how values of this kpi spanning over a time period are " +"transformed to match the reporting period. Sum: values of shorter period are " +"added, values of longest or partially overlapping periods are adjusted pro-" +"rata temporis.\n" +"Average: values of included period are averaged with a pro-rata temporis " +"weight." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__diff +#, python-format +msgid "Difference" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__no_auto_expand_accounts +msgid "Disable account details expansion" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display Columns Description" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__display_name +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__display_name +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__display_name +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__display_name +msgid "Display Name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts +msgid "Display details by account" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display the date range details in the column headers." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider_inherit +msgid "Divider Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__domain +msgid "Domain" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp_inherit +msgid "Dp Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_prorata_read_group_mixin__date +msgid "" +"Dummy field that adapts searches on date to searches on date_from/date_to." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__duration +msgid "Duration" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Enter expression here, for example balp[70%]. See also help tab." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Examples:" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Export" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__expression_ids +msgid "Expression" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions can be any valid python expressions." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Expressions can involve other KPI, sub KPI and\n" +" query results by name (eg kpi1 + " +"kpi2,\n" +" kpi2.subkpi1, query1.field1)." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__normalize_factor +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider +msgid "Factor" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Factor inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__normalize_factor +msgid "Factor to use to normalize the period (used in comparison" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_names +msgid "Fetched fields name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_ids +msgid "Fields to fetch" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "" +"Filter column on journal entries that have all these analytic tags.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_group_id +msgid "" +"Filter column on journal entries that match this analytic account group. " +"This filter is combined with a AND with the report-level filters and cannot " +"be modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "" +"Filter column on journal entries that match this analytic account.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Filters" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__fix +msgid "Fixed dates" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Font" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size +msgid "Font Size" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size_inherit +msgid "Font Size Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style +msgid "Font Style" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style_inherit +msgid "Font Style Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight +msgid "Font Weight" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight_inherit +msgid "Font Weight Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Forces the start date to Jan 1st of the relevant year" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_from +msgid "From" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_from +msgid "From (computed)" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/report/mis_report_instance_xlsx.py:0 +#, python-format +msgid "Generated on {} at {}" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Help (for KPI expressions)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always +msgid "Hide Always" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always_inherit +msgid "Hide Always Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__hide_analytic_filters +msgid "Hide Analytic Filters" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty +msgid "Hide Empty" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty_inherit +msgid "Hide Empty Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__id +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__id +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__id +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__id +msgid "ID" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/aep.py:0 +#, python-format +msgid "" +"If currency_id is not provided, all companies must have the same currency." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Indent" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level +msgid "Indent Level" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level_inherit +msgid "Indent Level Inherit" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "Indent level must be greater than or equal to 0" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__italic +msgid "Italic" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__kpi_expression_id +msgid "KPI" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" has type {} while a tuple was expected.\n" +"\n" +"This can be fixed by either:\n" +"\t- Changing the KPI value to a tuple of length {}\n" +"or\n" +"\t- Changing the KPI to `multi` mode and giving an explicit value for each " +"sub-KPI." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" is valued as a tuple of length {} while a tuple of length {} is " +"expected." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq1 +msgid "KPI Sequence" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "KPI name ({}) must be a valid python identifier" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__kpi_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "KPI's" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__all_kpi_ids +msgid "KPIs of this report and subreports." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__kpi_id +msgid "Kpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__name +msgid "Label" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__landscape_pdf +msgid "Landscape PDF" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard____last_update +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport____last_update +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin____last_update +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx____last_update +msgid "Last Modified on" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.last_mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.last_wizard_mis_report_instance_view_menu +msgid "Last Reports Generated" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_date +msgid "Last Updated on" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Layout" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_report_mis_builder_mis_report_instance_xlsx +msgid "MIS Builder XLSX report" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_kpi_data +msgid "MIS Kpi Data Abtract class" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "MIS Report" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subreport +msgid "MIS Report - Sub Reports Relation" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_add_mis_report_instance_dashboard_wizard +msgid "MIS Report Add to Dashboard Wizard" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "MIS Report Instance" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period +msgid "MIS Report Instance Period" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period_sum +msgid "MIS Report Instance Period Sum" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "MIS Report Instances" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "MIS Report KPI" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi_expression +msgid "MIS Report KPI Expression" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_query +msgid "MIS Report Query" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_result_view_form +msgid "MIS Report Result" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_style +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "MIS Report Style" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_style_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_style_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_tree +msgid "MIS Report Styles" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subkpi +msgid "MIS Report Sub-KPI" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report +msgid "MIS Report Template" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_view_menu +msgid "MIS Report Templates" +msgstr "" + +#. module: mis_builder +#: model:ir.ui.menu,name:mis_builder.mis_report_conf_menu +#: model:ir.ui.menu,name:mis_builder.mis_report_finance_menu +msgid "MIS Reporting" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_instance_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_tree +msgid "MIS Reports" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.qweb_pdf_export +msgid "MIS report instance QWEB PDF report" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.xls_export +msgid "MIS report instance XLS report" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__max +#, python-format +msgid "Max" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__min +#, python-format +msgid "Min" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__mode +msgid "Mode" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__model_id +msgid "Model" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__m +#, python-format +msgid "Month" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__move_lines_source +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "Move lines source" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_name +msgid "Move lines source model name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__multi +msgid "Multi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__multi_company +msgid "Multiple companies" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__name +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__none +msgid "No date filter" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "No date filter is allowed for this source in column %s." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__none +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__none +#, python-format +msgid "None" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__normal +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__nornal +msgid "Normal" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Number" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__duration +msgid "Number of periods" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__num +#, python-format +msgid "Numeric" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__offset +msgid "Offset" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__offset +msgid "Offset from current period" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_id +msgid "Parent column" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__pct +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__pct +#, python-format +msgid "Percentage" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_name_unique +msgid "Period name should be unique by report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__type +msgid "Period type" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__period_ids +msgid "Periods" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__pivot_date +msgid "Pivot date" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Please provide both columns to compare in %s." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix +msgid "Prefix" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix_inherit +msgid "Prefix Inherit" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Preview" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Print" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__query_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Queries" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__query_company_ids +msgid "Query Company" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Query name ({}) must be valid python identifier" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Refresh" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__relative +msgid "Relative to report base date" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__report_id +msgid "Report" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_ir_actions_report +msgid "Report Action" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_instance_id +msgid "Report Instance" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__date +msgid "Report base date (leave empty to use current date)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp +msgid "Rounding" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Rounding inherit" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Save" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__company_ids +msgid "Select companies for which data will be searched." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__currency_id +msgid "" +"Select target currency for the report. Required if companies have different " +"currencies." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__sequence +msgid "Sequence" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Settings" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_subreport_unique +msgid "" +"Should not include the same report more than once as sub report of a given " +"report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__sign +msgid "Sign" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Source" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__str +#, python-format +msgid "String" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__style_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_id +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Style" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_expression +msgid "Style expression" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts_style_id +msgid "Style for account detail rows" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__name +msgid "Style name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subkpi_ids +msgid "Sub KPI" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__subkpi_ids +msgid "Sub KPI Filter" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_kpi_expression_subkpi_kpi_unique +msgid "Sub KPI must be used once and only once for each KPI" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Sub KPI's" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Sub Reports" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subreport_ids +msgid "Sub reports" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq2 +msgid "Sub-KPI Sequence" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Sub-KPI name ({}) must be a valid python identifier" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__subkpi_id +msgid "Subkpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__subreport_id +msgid "Subreport" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, python-format +msgid "Subreport loop detected" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, python-format +msgid "Subreport name ({}) must be a valid python identifier" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_name_unique +msgid "Subreport name should be unique by report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix +msgid "Suffix" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix_inherit +msgid "Suffix Inherit" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__sum +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__sum +#, python-format +msgid "Sum" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_accdet +msgid "Sum account details" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "" +"Sum cannot be computed in column {} because the columns to sum have no " +"common subkpis" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__sumcol +msgid "Sum columns" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__target_move +msgid "Target Moves" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "Template" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__temporary +msgid "Temporary" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color +msgid "Text color" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__color +msgid "Text color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" account selector\n" +" is a like expression on the " +"account code (eg\n" +" 70%, etc)." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" journal items domain\n" +" is an Odoo domain filter on " +"journal items." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The following special elements are recognized in\n" +" the expressions to compute " +"accounting data:\n" +" \n" +" {bal|crd|deb|pbal|nbal}{pieu}" +"[account\n" +" selector][journal items domain]\n" +" \n" +" ." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_to +msgid "To" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_to +msgid "To (computed)" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_kpi_data.py:0 +#, python-format +msgid "Unexpected accumulation method %s for %s." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/prorata_read_group_mixin.py:0 +#, python-format +msgid "Unsupported operator %s for searching on date" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.server,name:mis_builder.ir_cron_vacuum_temp_reports_ir_actions_server +#: model:ir.cron,cron_name:mis_builder.ir_cron_vacuum_temp_reports +#: model:ir.cron,name:mis_builder.ir_cron_vacuum_temp_reports +msgid "Vacuum temporary reports" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__valid +msgid "Valid" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__type +msgid "Value type" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Visibility" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__w +#, python-format +msgid "Week" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_duration +msgid "Wrong duration, it must be positive!" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_normalize_factor +msgid "Wrong normalize factor, it must be positive!" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__y +#, python-format +msgid "Year" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Year to date" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "You cannot sum period %s with itself." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "from %s to %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__large +msgid "large" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__medium +msgid "medium" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "or" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "pp" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__small +msgid "small" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_from_id +msgid "versus" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-large +msgid "x-large" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-small +msgid "x-small" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-large +msgid "xx-large" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-small +msgid "xx-small" +msgstr "" diff --git a/odex25_accounting/mis_builder/i18n/el_GR.po b/odex25_accounting/mis_builder/i18n/el_GR.po new file mode 100644 index 000000000..bc393190e --- /dev/null +++ b/odex25_accounting/mis_builder/i18n/el_GR.po @@ -0,0 +1,1776 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mis_builder +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: el_GR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "%s (copy)" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[('user_type_id', '=',\n" +" ref('account.\n" +" data_account_type_receivable')." +"id)][]\n" +" \n" +" : variation of the balance of " +"all receivable\n" +" accounts over the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[][('tax_line_id." +"tag_ids', '=',\n" +" ref('l10n_be.tax_tag_56')." +"id)]\n" +" \n" +" : balance of move lines related " +"to tax grid\n" +" 56." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" debp[55%][('journal_id." +"code', '=',\n" +" 'BNK1')]\n" +" \n" +" : sum of all debits on accounts " +"55 and\n" +" journal BNK1 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"AccountingNone\n" +" : a null value that behaves as 0 " +"in\n" +" arithmetic operations." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal, crd, deb, pbal, nbal\n" +" : balance, debit, credit, " +"positive balance,\n" +" negative balance." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal[70]\n" +" : variation of the balance of " +"account 70\n" +" over the period (it is the same " +"as balp[70]." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bale[1%]\n" +" : balance of accounts starting " +"with 1 at end\n" +" of period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bali[70,60]\n" +" : initial balance of accounts 70 " +"and 60." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"balu[]\n" +" : (u for unallocated) is a " +"special\n" +" expression that shows the " +"unallocated\n" +" profit/loss of previous\n" +" fiscal years." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"crdp[40%]\n" +" : sum of all credits on accounts " +"starting\n" +" with 40 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"date_from, date_to\n" +" : beginning and end date of the " +"period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"datetime, datetime, dateutil\n" +" : the python modules." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"p, i, e\n" +" : respectively variation over " +"the period,\n" +" initial balance, ending balance" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"pbale[55%]\n" +" : sum of all ending balances of " +"accounts\n" +" starting with 55 whose\n" +" ending balance is positive." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"sum, min, max, len, avg\n" +" : behave as expected, very " +"similar to the\n" +" python builtins." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__move_lines_source +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields. This model is the data source for column Actuals." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "A date filter is mandatory for this source in column %s." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__account_model +msgid "Account model" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__accumulation_method +msgid "Accumulation Method" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "" +"Actual (alternative) models used in columns must have the same account model " +"in the Account field and must be the same defined in the report template: %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals +msgid "Actuals" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals_alt +msgid "Actuals (alternative)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source +msgid "" +"Actuals: current data, from accounting and other queries.\n" +"Actuals (alternative): current data from an alternative source (eg a " +"database view providing look-alike account move lines).\n" +"Sum columns: summation (+/-) of other columns.\n" +"Compare to column: compare to other column.\n" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_prorata_read_group_mixin +msgid "Adapt model with date_from/date_to for pro-rata temporis read_group" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_add_to_dashboard_action +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Add to dashboard" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Additionally following variables are available\n" +" in the evaluation context:" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__aggregate +msgid "Aggregate" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__all +msgid "All Entries" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__all_kpi_ids +msgid "All Kpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__posted +msgid "All Posted Entries" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__allowed_cmpcol_ids +msgid "Allowed Cmpcol" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__amount +msgid "Amount" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__style_expression +msgid "" +"An expression that returns a style depending on the KPI value. Such style is " +"applied on top of the row style." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_account_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "Analytic Account" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Account Filter" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_group_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_group_id +#, python-format +msgid "Analytic Account Group" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account Group: %s" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account: %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_tag_ids +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "Analytic Tags" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Tags Filter" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Tags: %s" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Auto expand" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__avg +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__avg +#, python-format +msgid "Average" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color +msgid "Background Color" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color_inherit +msgid "Background Color Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__background_color +msgid "Background color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date +msgid "Base date" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__bold +msgid "Bold" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Can not update a multi kpi from the kpi line" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Cancel" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__multi_company +msgid "" +"Check if you wish to specify children companies to be searched for data." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Color" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color_inherit +msgid "Color Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_to_sum_id +msgid "Column" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Column %s cannot be compared to itrec." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Column %s with move lines source must have from/to dates." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Columns" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Columns to compare must belong to the same report in %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_ids +msgid "Columns to sum" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "Columns {} and {} are not comparable" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_ids +msgid "Companies" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__query_company_ids +msgid "Companies for which data will be searched." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_id +msgid "Company" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_to_id +msgid "Compare" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__cmpcol +msgid "Compare columns" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__compare_method +msgid "Comparison Method" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__comparison_mode +msgid "Comparison Mode" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_uid +msgid "Created by" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_date +msgid "Created on" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__currency_id +msgid "Currency" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__dashboard_id +msgid "Dashboard" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date +msgid "Date" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__date_field +msgid "Date Field" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_from +msgid "Date From" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_range_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_id +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__date_range +#, python-format +msgid "Date Range" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_type_id +msgid "Date Range Type" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_to +msgid "Date To" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Dates" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__d +#, python-format +msgid "Day" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__description +msgid "Description" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__accumulation_method +msgid "" +"Determines how values of this kpi spanning over a time period are " +"transformed to match the reporting period. Sum: values of shorter period are " +"added, values of longest or partially overlapping periods are adjusted pro-" +"rata temporis.\n" +"Average: values of included period are averaged with a pro-rata temporis " +"weight." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__diff +#, python-format +msgid "Difference" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__no_auto_expand_accounts +msgid "Disable account details expansion" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display Columns Description" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__display_name +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__display_name +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__display_name +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__display_name +msgid "Display Name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts +msgid "Display details by account" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display the date range details in the column headers." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider_inherit +msgid "Divider Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__domain +msgid "Domain" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp_inherit +msgid "Dp Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_prorata_read_group_mixin__date +msgid "" +"Dummy field that adapts searches on date to searches on date_from/date_to." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__duration +msgid "Duration" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Enter expression here, for example balp[70%]. See also help tab." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Examples:" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Export" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__expression_ids +msgid "Expression" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions can be any valid python expressions." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Expressions can involve other KPI, sub KPI and\n" +" query results by name (eg kpi1 + " +"kpi2,\n" +" kpi2.subkpi1, query1.field1)." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__normalize_factor +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider +msgid "Factor" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Factor inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__normalize_factor +msgid "Factor to use to normalize the period (used in comparison" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_names +msgid "Fetched fields name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_ids +msgid "Fields to fetch" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "" +"Filter column on journal entries that have all these analytic tags.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_group_id +msgid "" +"Filter column on journal entries that match this analytic account group. " +"This filter is combined with a AND with the report-level filters and cannot " +"be modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "" +"Filter column on journal entries that match this analytic account.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Filters" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__fix +msgid "Fixed dates" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Font" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size +msgid "Font Size" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size_inherit +msgid "Font Size Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style +msgid "Font Style" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style_inherit +msgid "Font Style Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight +msgid "Font Weight" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight_inherit +msgid "Font Weight Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Forces the start date to Jan 1st of the relevant year" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_from +msgid "From" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_from +msgid "From (computed)" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/report/mis_report_instance_xlsx.py:0 +#, python-format +msgid "Generated on {} at {}" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Help (for KPI expressions)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always +msgid "Hide Always" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always_inherit +msgid "Hide Always Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__hide_analytic_filters +msgid "Hide Analytic Filters" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty +msgid "Hide Empty" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty_inherit +msgid "Hide Empty Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__id +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__id +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__id +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__id +msgid "ID" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/aep.py:0 +#, python-format +msgid "" +"If currency_id is not provided, all companies must have the same currency." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Indent" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level +msgid "Indent Level" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level_inherit +msgid "Indent Level Inherit" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "Indent level must be greater than or equal to 0" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__italic +msgid "Italic" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__kpi_expression_id +msgid "KPI" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" has type {} while a tuple was expected.\n" +"\n" +"This can be fixed by either:\n" +"\t- Changing the KPI value to a tuple of length {}\n" +"or\n" +"\t- Changing the KPI to `multi` mode and giving an explicit value for each " +"sub-KPI." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" is valued as a tuple of length {} while a tuple of length {} is " +"expected." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq1 +msgid "KPI Sequence" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "KPI name ({}) must be a valid python identifier" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__kpi_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "KPI's" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__all_kpi_ids +msgid "KPIs of this report and subreports." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__kpi_id +msgid "Kpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__name +msgid "Label" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__landscape_pdf +msgid "Landscape PDF" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard____last_update +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport____last_update +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin____last_update +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx____last_update +msgid "Last Modified on" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.last_mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.last_wizard_mis_report_instance_view_menu +msgid "Last Reports Generated" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_date +msgid "Last Updated on" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Layout" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_report_mis_builder_mis_report_instance_xlsx +msgid "MIS Builder XLSX report" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_kpi_data +msgid "MIS Kpi Data Abtract class" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "MIS Report" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subreport +msgid "MIS Report - Sub Reports Relation" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_add_mis_report_instance_dashboard_wizard +msgid "MIS Report Add to Dashboard Wizard" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "MIS Report Instance" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period +msgid "MIS Report Instance Period" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period_sum +msgid "MIS Report Instance Period Sum" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "MIS Report Instances" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "MIS Report KPI" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi_expression +msgid "MIS Report KPI Expression" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_query +msgid "MIS Report Query" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_result_view_form +msgid "MIS Report Result" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_style +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "MIS Report Style" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_style_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_style_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_tree +msgid "MIS Report Styles" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subkpi +msgid "MIS Report Sub-KPI" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report +msgid "MIS Report Template" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_view_menu +msgid "MIS Report Templates" +msgstr "" + +#. module: mis_builder +#: model:ir.ui.menu,name:mis_builder.mis_report_conf_menu +#: model:ir.ui.menu,name:mis_builder.mis_report_finance_menu +msgid "MIS Reporting" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_instance_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_tree +msgid "MIS Reports" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.qweb_pdf_export +msgid "MIS report instance QWEB PDF report" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.xls_export +msgid "MIS report instance XLS report" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__max +#, python-format +msgid "Max" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__min +#, python-format +msgid "Min" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__mode +msgid "Mode" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__model_id +msgid "Model" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__m +#, python-format +msgid "Month" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__move_lines_source +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "Move lines source" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_name +msgid "Move lines source model name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__multi +msgid "Multi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__multi_company +msgid "Multiple companies" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__name +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__none +msgid "No date filter" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "No date filter is allowed for this source in column %s." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__none +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__none +#, python-format +msgid "None" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__normal +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__nornal +msgid "Normal" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Number" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__duration +msgid "Number of periods" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__num +#, python-format +msgid "Numeric" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__offset +msgid "Offset" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__offset +msgid "Offset from current period" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_id +msgid "Parent column" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__pct +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__pct +#, python-format +msgid "Percentage" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_name_unique +msgid "Period name should be unique by report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__type +msgid "Period type" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__period_ids +msgid "Periods" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__pivot_date +msgid "Pivot date" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Please provide both columns to compare in %s." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix +msgid "Prefix" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix_inherit +msgid "Prefix Inherit" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Preview" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Print" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__query_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Queries" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__query_company_ids +msgid "Query Company" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Query name ({}) must be valid python identifier" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Refresh" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__relative +msgid "Relative to report base date" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__report_id +msgid "Report" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_ir_actions_report +msgid "Report Action" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_instance_id +msgid "Report Instance" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__date +msgid "Report base date (leave empty to use current date)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp +msgid "Rounding" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Rounding inherit" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Save" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__company_ids +msgid "Select companies for which data will be searched." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__currency_id +msgid "" +"Select target currency for the report. Required if companies have different " +"currencies." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__sequence +msgid "Sequence" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Settings" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_subreport_unique +msgid "" +"Should not include the same report more than once as sub report of a given " +"report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__sign +msgid "Sign" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Source" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__str +#, python-format +msgid "String" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__style_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_id +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Style" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_expression +msgid "Style expression" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts_style_id +msgid "Style for account detail rows" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__name +msgid "Style name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subkpi_ids +msgid "Sub KPI" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__subkpi_ids +msgid "Sub KPI Filter" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_kpi_expression_subkpi_kpi_unique +msgid "Sub KPI must be used once and only once for each KPI" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Sub KPI's" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Sub Reports" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subreport_ids +msgid "Sub reports" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq2 +msgid "Sub-KPI Sequence" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Sub-KPI name ({}) must be a valid python identifier" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__subkpi_id +msgid "Subkpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__subreport_id +msgid "Subreport" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, python-format +msgid "Subreport loop detected" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, python-format +msgid "Subreport name ({}) must be a valid python identifier" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_name_unique +msgid "Subreport name should be unique by report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix +msgid "Suffix" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix_inherit +msgid "Suffix Inherit" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__sum +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__sum +#, python-format +msgid "Sum" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_accdet +msgid "Sum account details" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "" +"Sum cannot be computed in column {} because the columns to sum have no " +"common subkpis" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__sumcol +msgid "Sum columns" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__target_move +msgid "Target Moves" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "Template" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__temporary +msgid "Temporary" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color +msgid "Text color" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__color +msgid "Text color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" account selector\n" +" is a like expression on the " +"account code (eg\n" +" 70%, etc)." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" journal items domain\n" +" is an Odoo domain filter on " +"journal items." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The following special elements are recognized in\n" +" the expressions to compute " +"accounting data:\n" +" \n" +" {bal|crd|deb|pbal|nbal}{pieu}" +"[account\n" +" selector][journal items domain]\n" +" \n" +" ." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_to +msgid "To" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_to +msgid "To (computed)" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_kpi_data.py:0 +#, python-format +msgid "Unexpected accumulation method %s for %s." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/prorata_read_group_mixin.py:0 +#, python-format +msgid "Unsupported operator %s for searching on date" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.server,name:mis_builder.ir_cron_vacuum_temp_reports_ir_actions_server +#: model:ir.cron,cron_name:mis_builder.ir_cron_vacuum_temp_reports +#: model:ir.cron,name:mis_builder.ir_cron_vacuum_temp_reports +msgid "Vacuum temporary reports" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__valid +msgid "Valid" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__type +msgid "Value type" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Visibility" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__w +#, python-format +msgid "Week" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_duration +msgid "Wrong duration, it must be positive!" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_normalize_factor +msgid "Wrong normalize factor, it must be positive!" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__y +#, python-format +msgid "Year" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Year to date" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "You cannot sum period %s with itself." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "from %s to %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__large +msgid "large" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__medium +msgid "medium" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "or" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "pp" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__small +msgid "small" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_from_id +msgid "versus" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-large +msgid "x-large" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-small +msgid "x-small" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-large +msgid "xx-large" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-small +msgid "xx-small" +msgstr "" diff --git a/odex25_accounting/mis_builder/i18n/es.po b/odex25_accounting/mis_builder/i18n/es.po new file mode 100644 index 000000000..61dd1cc5c --- /dev/null +++ b/odex25_accounting/mis_builder/i18n/es.po @@ -0,0 +1,2021 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mis_builder +# +# Translators: +# OCA Transbot , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-13 15:37+0000\n" +"PO-Revision-Date: 2020-07-27 10:19+0000\n" +"Last-Translator: Daniel Martinez Vila \n" +"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.10\n" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "%s (copy)" +msgstr "%s (copia)" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[('user_type_id', '=',\n" +" ref('account.\n" +" data_account_type_receivable')." +"id)][]\n" +" \n" +" : variation of the balance of " +"all receivable\n" +" accounts over the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[][('tax_line_id." +"tag_ids', '=',\n" +" ref('l10n_be.tax_tag_56')." +"id)]\n" +" \n" +" : balance of move lines related " +"to tax grid\n" +" 56." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" debp[55%][('journal_id." +"code', '=',\n" +" 'BNK1')]\n" +" \n" +" : sum of all debits on accounts " +"55 and\n" +" journal BNK1 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"AccountingNone\n" +" : a null value that behaves as 0 " +"in\n" +" arithmetic operations." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal, crd, deb, pbal, nbal\n" +" : balance, debit, credit, " +"positive balance,\n" +" negative balance." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal[70]\n" +" : variation of the balance of " +"account 70\n" +" over the period (it is the same " +"as balp[70]." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bale[1%]\n" +" : balance of accounts starting " +"with 1 at end\n" +" of period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bali[70,60]\n" +" : initial balance of accounts 70 " +"and 60." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"balu[]\n" +" : (u for unallocated) is a " +"special\n" +" expression that shows the " +"unallocated\n" +" profit/loss of previous\n" +" fiscal years." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"crdp[40%]\n" +" : sum of all credits on accounts " +"starting\n" +" with 40 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"date_from, date_to\n" +" : beginning and end date of the " +"period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"datetime, datetime, dateutil\n" +" : the python modules." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"p, i, e\n" +" : respectively variation over " +"the period,\n" +" initial balance, ending balance" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"pbale[55%]\n" +" : sum of all ending balances of " +"accounts\n" +" starting with 55 whose\n" +" ending balance is positive." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"sum, min, max, len, avg\n" +" : behave as expected, very " +"similar to the\n" +" python builtins." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields." +msgstr "" +"Modelo que sea 'de tipo apunte', es decir, que tenga al menos los campos " +"debit, credit, date, account_id y company_id." + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__move_lines_source +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields. This model is the data source for column Actuals." +msgstr "" +"Modelo que sea 'de tipo apunte', es decir, que tenga al menos los campos de " +"débito, crédito, fecha, ID de cuenta y ID de compañía. Este modelo es la " +"fuente de datos para la columna Informes estadísticos." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "A date filter is mandatory for this source in column %s." +msgstr "Un filtro de fecha es obligatorio para este origen en la columna %s." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__account_model +msgid "Account model" +msgstr "Modelo de cuenta" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__accumulation_method +msgid "Accumulation Method" +msgstr "Método de agregación" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "" +"Actual (alternative) models used in columns must have the same account model " +"in the Account field and must be the same defined in the report template: %s" +msgstr "" +"Los modelos reales (alternativos) utilizados en columnas deben tener el " +"mismo modelo de cuenta en el campo Cuenta y deben ser los mismos definidos " +"en la plantilla de informe:% s" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals +msgid "Actuals" +msgstr "Datos reales" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals_alt +msgid "Actuals (alternative)" +msgstr "Datos reales (alternativa)" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source +msgid "" +"Actuals: current data, from accounting and other queries.\n" +"Actuals (alternative): current data from an alternative source (eg a " +"database view providing look-alike account move lines).\n" +"Sum columns: summation (+/-) of other columns.\n" +"Compare to column: compare to other column.\n" +msgstr "" +"Datos reales: datos actuales provenientes de la contabilidad y otras " +"consultas.\n" +"Datos reales (alternativa): datos actuales provenientes de un origen " +"alternativo (por ejemplo, vista de la base de datos proveyendo registros de " +"\"tipo apunte\").\n" +"Suma de columnas: sumarización (+/-) de otras columnas.\n" +"Comparar columnas: comparación con otra columna.\n" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_prorata_read_group_mixin +msgid "Adapt model with date_from/date_to for pro-rata temporis read_group" +msgstr "" +"Adapte el modelo con date_from / date_to para pro-rata temporis read_group" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_add_to_dashboard_action +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Add to dashboard" +msgstr "Añadir al tablero" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Additionally following variables are available\n" +" in the evaluation context:" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__aggregate +msgid "Aggregate" +msgstr "Agregación" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__all +msgid "All Entries" +msgstr "Todos los asientos" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__all_kpi_ids +msgid "All Kpi" +msgstr "Todos los Kpi" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__posted +msgid "All Posted Entries" +msgstr "Todos los asientos asentados" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__allowed_cmpcol_ids +msgid "Allowed Cmpcol" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__amount +msgid "Amount" +msgstr "Importe" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__style_expression +msgid "" +"An expression that returns a style depending on the KPI value. Such style is " +"applied on top of the row style." +msgstr "" +"Una expresión que devuelve un estilo dependiendo del valor del KPI. Dicho " +"estilo se aplica en la parte superior del estilo de la fila." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_account_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "Analytic Account" +msgstr "Cuenta analítica" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Account Filter" +msgstr "Filtro de cuenta analítica" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_group_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_group_id +#, python-format +msgid "Analytic Account Group" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account Group: %s" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account: %s" +msgstr "Cuenta analítica: %s" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_tag_ids +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "Analytic Tags" +msgstr "Etiquetas analíticas" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Tags Filter" +msgstr "Filtro de etiquetas analíticas" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Tags: %s" +msgstr "Etiquetas analíticas: %s" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Auto expand" +msgstr "Auto expandir" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__avg +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__avg +#, python-format +msgid "Average" +msgstr "Media" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color +msgid "Background Color" +msgstr "Color de fondo" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color_inherit +msgid "Background Color Inherit" +msgstr "Color de fondo heredado" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__background_color +msgid "Background color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "Color de fondo utilizando un código RGB válido (de #000000 a #FFFFFF)" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date +msgid "Base date" +msgstr "Fecha base" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__bold +msgid "Bold" +msgstr "Negrita" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Can not update a multi kpi from the kpi line" +msgstr "No se puede actualizar un kpi múltiple desde una línea de kpi" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Cancel" +msgstr "Cancelar" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__multi_company +msgid "" +"Check if you wish to specify children companies to be searched for data." +msgstr "" +"Compruebe si desea especificar compañías hijas para buscar datos en ellas." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Color" +msgstr "Color" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color_inherit +msgid "Color Inherit" +msgstr "Color heredado" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_to_sum_id +msgid "Column" +msgstr "Columna" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Column %s cannot be compared to itrec." +msgstr "La columna %s no puede ser comparada consigo misma." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Column %s with move lines source must have from/to dates." +msgstr "La columna %s con fuente de datos reales debe tener fecha desde/hasta." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Columns" +msgstr "Columnas" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Columns to compare must belong to the same report in %s" +msgstr "Las columnas a comparar deben pertenecer al mismo informe en %s" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_ids +msgid "Columns to sum" +msgstr "Columnas a sumar" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "Columns {} and {} are not comparable" +msgstr "Las columnas {} and {} no son comparables" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_ids +msgid "Companies" +msgstr "Compañías" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__query_company_ids +msgid "Companies for which data will be searched." +msgstr "Compañías para las que se buscarán datos." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_id +msgid "Company" +msgstr "Compañía" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_to_id +msgid "Compare" +msgstr "Comparar" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__cmpcol +msgid "Compare columns" +msgstr "Comparar columnas" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__compare_method +msgid "Comparison Method" +msgstr "Método de comparación" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__comparison_mode +msgid "Comparison Mode" +msgstr "Modo de comparación" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_date +msgid "Created on" +msgstr "Creado en" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__currency_id +msgid "Currency" +msgstr "Moneda" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__dashboard_id +msgid "Dashboard" +msgstr "Tablero" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date +msgid "Date" +msgstr "Fecha" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__date_field +msgid "Date Field" +msgstr "Campo Fecha" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_from +msgid "Date From" +msgstr "Fecha De" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_range_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_id +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__date_range +#, python-format +msgid "Date Range" +msgstr "Rango de fechas" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_type_id +msgid "Date Range Type" +msgstr "Tipo de rango de fechas" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_to +msgid "Date To" +msgstr "Fecha hasta" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Dates" +msgstr "Fechas" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__d +#, python-format +msgid "Day" +msgstr "Día" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__description +msgid "Description" +msgstr "Descripción" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__accumulation_method +msgid "" +"Determines how values of this kpi spanning over a time period are " +"transformed to match the reporting period. Sum: values of shorter period are " +"added, values of longest or partially overlapping periods are adjusted pro-" +"rata temporis.\n" +"Average: values of included period are averaged with a pro-rata temporis " +"weight." +msgstr "" +"Determina cómo los valores de este kpi transcurriendo sobre el periodo de " +"tiempo son transformados para casar con el periodo del informe. Sum: se " +"añaden los valores del periodo más corto, y los valores del más largo o de " +"periodos que solapan parcialmente se ajustan prorrateándose en el tiempo.\n" +"Media: los valores del periodo incluido se promedian con el peso del " +"prorrateo temporal." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__diff +#, python-format +msgid "Difference" +msgstr "Diferencia" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__no_auto_expand_accounts +msgid "Disable account details expansion" +msgstr "Deshabilitar expansión de detalles de cuenta" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display Columns Description" +msgstr "Descripción de las columnas de visualización" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__display_name +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__display_name +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__display_name +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__display_name +msgid "Display Name" +msgstr "Nombre a mostrar" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts +msgid "Display details by account" +msgstr "Mostrar detalles por cuenta" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display the date range details in the column headers." +msgstr "" +"Mostrar los detalles del rango de fechas en los encabezados de columna." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider_inherit +msgid "Divider Inherit" +msgstr "Divisor heredado" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__domain +msgid "Domain" +msgstr "Dominio" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp_inherit +msgid "Dp Inherit" +msgstr "Dp heredado" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_prorata_read_group_mixin__date +msgid "" +"Dummy field that adapts searches on date to searches on date_from/date_to." +msgstr "" +"Campo ficticio que adapta las búsquedas en fecha a búsquedas en date_from / " +"date_to." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__duration +msgid "Duration" +msgstr "Duración" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Enter expression here, for example balp[70%]. See also help tab." +msgstr "" +"Introduzca la expresión aquí, por ejemplo balp[70%]. Vea también la pestaña " +"de ayuda." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Examples:" +msgstr "Ejemplos:" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Export" +msgstr "Exportar" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__expression_ids +msgid "Expression" +msgstr "Expresión" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions" +msgstr "Expresiones" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions can be any valid python expressions." +msgstr "Las expresiones pueden ser cualquier expresión válida de Python." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Expressions can involve other KPI, sub KPI and\n" +" query results by name (eg kpi1 + " +"kpi2,\n" +" kpi2.subkpi1, query1.field1)." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__normalize_factor +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider +msgid "Factor" +msgstr "Factor" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Factor inherit" +msgstr "Factor heredado" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__normalize_factor +msgid "Factor to use to normalize the period (used in comparison" +msgstr "El factor se usa para normalizar el periodo (usado en la comparación" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_names +msgid "Fetched fields name" +msgstr "Nombre de los campos obtenidos" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_ids +msgid "Fields to fetch" +msgstr "Campos a obtener" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "" +"Filter column on journal entries that have all these analytic tags.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" +"Filtre la columna en entradas de diario que tengan todas estas etiquetas " +"analíticas. Este filtro se combina con un AND con los filtros de nivel de " +"informe y no se puede modificar en la vista previa." + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_group_id +msgid "" +"Filter column on journal entries that match this analytic account group. " +"This filter is combined with a AND with the report-level filters and cannot " +"be modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "" +"Filter column on journal entries that match this analytic account.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" +"Filtrar columna en entradas de diario que coincidan con esta cuenta " +"analítica. Este filtro se combina con un AND con los filtros de nivel de " +"informe y no se puede modificar en la vista previa." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Filters" +msgstr "Filtros" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__fix +msgid "Fixed dates" +msgstr "Fechas fijas" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Font" +msgstr "Fuente" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size +msgid "Font Size" +msgstr "Tamaño del tipo de letra" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size_inherit +msgid "Font Size Inherit" +msgstr "Tamaño del tipo de letra heredado" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style +msgid "Font Style" +msgstr "Estilo de tipo de letra" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style_inherit +msgid "Font Style Inherit" +msgstr "Estilo de tipo de letra heredado" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight +msgid "Font Weight" +msgstr "Tamaño del tipo de letra" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight_inherit +msgid "Font Weight Inherit" +msgstr "Tamaño del tipo de letra heredado" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Forces the start date to Jan 1st of the relevant year" +msgstr "Fuerza la fecha de inicio al 1 de enero del año relevante" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_from +msgid "From" +msgstr "Desde" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_from +msgid "From (computed)" +msgstr "De (calculado)" + +#. module: mis_builder +#: code:addons/mis_builder/report/mis_report_instance_xlsx.py:0 +#, python-format +msgid "Generated on {} at {}" +msgstr "Generado el {} a las {}" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Help (for KPI expressions)" +msgstr "Ayuda (para las expresiones del KPI)" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always +msgid "Hide Always" +msgstr "Ocultar Siempre" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always_inherit +msgid "Hide Always Inherit" +msgstr "Ocultar vacíos heredados" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__hide_analytic_filters +msgid "Hide Analytic Filters" +msgstr "Ocultar filtros analíticos" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty +msgid "Hide Empty" +msgstr "Ocultar vacíos" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty_inherit +msgid "Hide Empty Inherit" +msgstr "Ocultar vacíos heredado" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__id +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__id +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__id +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__id +msgid "ID" +msgstr "ID" + +#. module: mis_builder +#: code:addons/mis_builder/models/aep.py:0 +#, python-format +msgid "" +"If currency_id is not provided, all companies must have the same currency." +msgstr "" +"Si no se provee el campo currency_id, todas las compañías deben tener la " +"misma moneda." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Indent" +msgstr "Sangría" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level +msgid "Indent Level" +msgstr "Nivel de sangría" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level_inherit +msgid "Indent Level Inherit" +msgstr "Nivel de sangría heredado" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "Indent level must be greater than or equal to 0" +msgstr "El nivel de sangría debe ser igual o mayor que 0" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__italic +msgid "Italic" +msgstr "Cursiva" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__kpi_expression_id +msgid "KPI" +msgstr "KPI" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" has type {} while a tuple was expected.\n" +"\n" +"This can be fixed by either:\n" +"\t- Changing the KPI value to a tuple of length {}\n" +"or\n" +"\t- Changing the KPI to `multi` mode and giving an explicit value for each " +"sub-KPI." +msgstr "" +"El KPI \"{}\" tiene el tipo {} mientras se esperaba una tupla.\n" +"\n" +"Esto se puede solucionar mediante:\n" +"- Cambiar el valor de KPI a una tupla de longitud {}\n" +"o\n" +"- Cambiar el KPI al modo `multi` y dar un valor explícito para cada sub-KPI." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" is valued as a tuple of length {} while a tuple of length {} is " +"expected." +msgstr "" +"El KPI \"{}\" se valora como una tupla de longitud {} mientras que se espera " +"una tupla de longitud {}." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq1 +msgid "KPI Sequence" +msgstr "KPI de Secuencia" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "KPI name ({}) must be a valid python identifier" +msgstr "El nombre de KPI ({}) debe ser un identificador de Python válido" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__kpi_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "KPI's" +msgstr "KPI's" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__all_kpi_ids +msgid "KPIs of this report and subreports." +msgstr "KPI's de este informe y subinformes." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__kpi_id +msgid "Kpi" +msgstr "KPI" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__name +msgid "Label" +msgstr "Etiqueta" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__landscape_pdf +msgid "Landscape PDF" +msgstr "PDF apaisado" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard____last_update +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport____last_update +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin____last_update +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx____last_update +msgid "Last Modified on" +msgstr "Última modificación en" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.last_mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.last_wizard_mis_report_instance_view_menu +msgid "Last Reports Generated" +msgstr "Últimos informes generados" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_uid +msgid "Last Updated by" +msgstr "Última modificación por" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_date +msgid "Last Updated on" +msgstr "Última actualización en" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Layout" +msgstr "Diseño" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_report_mis_builder_mis_report_instance_xlsx +msgid "MIS Builder XLSX report" +msgstr "Informe MIS Builder XLSX" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_kpi_data +msgid "MIS Kpi Data Abtract class" +msgstr "Clase abstracta de datos KPI MIS" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "MIS Report" +msgstr "Informe MIS" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subreport +msgid "MIS Report - Sub Reports Relation" +msgstr "Informe MIS - Relación de informes secundarios" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_add_mis_report_instance_dashboard_wizard +msgid "MIS Report Add to Dashboard Wizard" +msgstr "Informe MIS Agregar al Asistente del Tablero" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "MIS Report Instance" +msgstr "Instancia de informe MIS" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period +msgid "MIS Report Instance Period" +msgstr "Período de instancia del informe MIS" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period_sum +msgid "MIS Report Instance Period Sum" +msgstr "Suma del período de instancia del informe MIS" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "MIS Report Instances" +msgstr "Instancias de informes MIS" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "MIS Report KPI" +msgstr "KPI de informe MIS" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi_expression +msgid "MIS Report KPI Expression" +msgstr "Informe MIS - KPI Expresión" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_query +msgid "MIS Report Query" +msgstr "Consulta del informe MIS" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_result_view_form +msgid "MIS Report Result" +msgstr "Resultado del informe MIS" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_style +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "MIS Report Style" +msgstr "Estilo del informe MIS" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_style_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_style_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_tree +msgid "MIS Report Styles" +msgstr "Estilos del informe MIS" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subkpi +msgid "MIS Report Sub-KPI" +msgstr "Informe MIS Sub-KPI" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report +msgid "MIS Report Template" +msgstr "Plantilla de presupuesto MIS" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_view_menu +msgid "MIS Report Templates" +msgstr "Plantillas de informe MIS" + +#. module: mis_builder +#: model:ir.ui.menu,name:mis_builder.mis_report_conf_menu +#: model:ir.ui.menu,name:mis_builder.mis_report_finance_menu +msgid "MIS Reporting" +msgstr "MIS" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_instance_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_tree +msgid "MIS Reports" +msgstr "Informes MIS" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.qweb_pdf_export +msgid "MIS report instance QWEB PDF report" +msgstr "Informe QWeb PDF de instancia de informe MIS" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.xls_export +msgid "MIS report instance XLS report" +msgstr "Informe XLS de instancia de informe MIS" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__max +#, python-format +msgid "Max" +msgstr "Máx" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__min +#, python-format +msgid "Min" +msgstr "Mín" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__mode +msgid "Mode" +msgstr "Modo" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__model_id +msgid "Model" +msgstr "Modelo" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__m +#, python-format +msgid "Month" +msgstr "Mes" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__move_lines_source +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "Move lines source" +msgstr "Origen de los apuntes" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_name +msgid "Move lines source model name" +msgstr "Mover líneas nombre del modelo de origen" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__multi +msgid "Multi" +msgstr "Multi" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__multi_company +msgid "Multiple companies" +msgstr "Múltiples compañías" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__name +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Name" +msgstr "Nombre" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__none +msgid "No date filter" +msgstr "Sin filtro de fechas" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "No date filter is allowed for this source in column %s." +msgstr "No se permite un filtro de fecha para esta fuente en la columna %s." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__none +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__none +#, python-format +msgid "None" +msgstr "Ninguno" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__normal +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__nornal +msgid "Normal" +msgstr "Normal" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Number" +msgstr "Número" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__duration +msgid "Number of periods" +msgstr "Número de periodos" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__num +#, python-format +msgid "Numeric" +msgstr "Numérico" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__offset +msgid "Offset" +msgstr "Desplazamiento" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__offset +msgid "Offset from current period" +msgstr "Desplazamiento del periodo actual" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_id +msgid "Parent column" +msgstr "Columna padre" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__pct +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__pct +#, python-format +msgid "Percentage" +msgstr "Porcentaje" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_name_unique +msgid "Period name should be unique by report" +msgstr "El nombre del periodo debe ser único en cada informe" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__type +msgid "Period type" +msgstr "Tipo de periodo" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__period_ids +msgid "Periods" +msgstr "Periodos" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__pivot_date +msgid "Pivot date" +msgstr "Fecha pivote" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Please provide both columns to compare in %s." +msgstr "Por favor introduzca ambas columnas a comparar en %s." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix +msgid "Prefix" +msgstr "Prefijo" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix_inherit +msgid "Prefix Inherit" +msgstr "Prefijo heredado" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Preview" +msgstr "Previsualizar" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Print" +msgstr "Imprimir" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__query_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Queries" +msgstr "Consultas" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__query_company_ids +msgid "Query Company" +msgstr "Compañía de la consulta" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Query name ({}) must be valid python identifier" +msgstr "" +"El nombre de la consulta ({}) debe ser un identificador de Python válido" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Refresh" +msgstr "Actualizar" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__relative +msgid "Relative to report base date" +msgstr "Relativo a la fecha base del informe" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__report_id +msgid "Report" +msgstr "Informe" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_ir_actions_report +msgid "Report Action" +msgstr "Informar acción" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_instance_id +msgid "Report Instance" +msgstr "Instancia del informe" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__date +msgid "Report base date (leave empty to use current date)" +msgstr "Fecha base del informe (dejar vacía para usar la fecha actual)" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp +msgid "Rounding" +msgstr "Redondeo" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Rounding inherit" +msgstr "Redondeo heredado" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Save" +msgstr "Guardar" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__company_ids +msgid "Select companies for which data will be searched." +msgstr "Seleccione las compañías para las que se buscarán los datos." + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__currency_id +msgid "" +"Select target currency for the report. Required if companies have different " +"currencies." +msgstr "" +"Seleccione la moneda objetivo para el informe. Requerido si las compañías " +"tiene monedas diferentes." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__sequence +msgid "Sequence" +msgstr "Secuencia" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Settings" +msgstr "Configuración" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_subreport_unique +msgid "" +"Should not include the same report more than once as sub report of a given " +"report" +msgstr "" +"No debe incluir el mismo informe más de una vez como subinforme de un " +"informe determinado" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__sign +msgid "Sign" +msgstr "Signo" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Source" +msgstr "Origen" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__str +#, python-format +msgid "String" +msgstr "Cadena" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__style_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_id +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Style" +msgstr "Estilo" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_expression +msgid "Style expression" +msgstr "Expresión de estilo" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts_style_id +msgid "Style for account detail rows" +msgstr "Estilo para las filas de detalle de cuenta" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__name +msgid "Style name" +msgstr "Nombre del estilo" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subkpi_ids +msgid "Sub KPI" +msgstr "Sub KPI" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__subkpi_ids +msgid "Sub KPI Filter" +msgstr "Filtro del sub KPI" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_kpi_expression_subkpi_kpi_unique +msgid "Sub KPI must be used once and only once for each KPI" +msgstr "El sub KPI debe usarse solamente una vez para cada KPI" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Sub KPI's" +msgstr "Sub KPI's" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Sub Reports" +msgstr "Subinformes" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subreport_ids +msgid "Sub reports" +msgstr "Subinformes" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq2 +msgid "Sub-KPI Sequence" +msgstr "Sub-KPI Secuencia" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Sub-KPI name ({}) must be a valid python identifier" +msgstr "El nombre del Sub-KPI ({}) debe ser un identificador válido de Python" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__subkpi_id +msgid "Subkpi" +msgstr "SubKPI" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__subreport_id +msgid "Subreport" +msgstr "Subinforme" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, python-format +msgid "Subreport loop detected" +msgstr "Subinforme detectado" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, python-format +msgid "Subreport name ({}) must be a valid python identifier" +msgstr "" +"El nombre del subinforme ({}) debe ser un identificador de Python válido" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_name_unique +msgid "Subreport name should be unique by report" +msgstr "El nombre del subinforme debe ser único por informe" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix +msgid "Suffix" +msgstr "Sufijo" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix_inherit +msgid "Suffix Inherit" +msgstr "Sufijo heredado" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__sum +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__sum +#, python-format +msgid "Sum" +msgstr "Suma" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_accdet +msgid "Sum account details" +msgstr "Detalles de cuenta de la suma" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "" +"Sum cannot be computed in column {} because the columns to sum have no " +"common subkpis" +msgstr "" +"La suma no puede ser calculada en la columna {} porque las columnas a sumar " +"no tiene subkpis comunes" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__sumcol +msgid "Sum columns" +msgstr "Suma de columnas" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__target_move +msgid "Target Moves" +msgstr "Apuntes objetivo" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "Template" +msgstr "Plantilla" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__temporary +msgid "Temporary" +msgstr "Temporal" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color +msgid "Text color" +msgstr "Color del texto" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__color +msgid "Text color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "Color de texto en un código RGB válido (desde #000000 hasta #FFFFFF)" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" account selector\n" +" is a like expression on the " +"account code (eg\n" +" 70%, etc)." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" journal items domain\n" +" is an Odoo domain filter on " +"journal items." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The following special elements are recognized in\n" +" the expressions to compute " +"accounting data:\n" +" \n" +" {bal|crd|deb|pbal|nbal}{pieu}" +"[account\n" +" selector][journal items domain]\n" +" \n" +" ." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_to +msgid "To" +msgstr "Hasta" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_to +msgid "To (computed)" +msgstr "Para (calculado)" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_kpi_data.py:0 +#, python-format +msgid "Unexpected accumulation method %s for %s." +msgstr "Método de acumulación %s no esperado para %s." + +#. module: mis_builder +#: code:addons/mis_builder/models/prorata_read_group_mixin.py:0 +#, python-format +msgid "Unsupported operator %s for searching on date" +msgstr "Operador no compatible %s para buscar en fecha" + +#. module: mis_builder +#: model:ir.actions.server,name:mis_builder.ir_cron_vacuum_temp_reports_ir_actions_server +#: model:ir.cron,cron_name:mis_builder.ir_cron_vacuum_temp_reports +#: model:ir.cron,name:mis_builder.ir_cron_vacuum_temp_reports +msgid "Vacuum temporary reports" +msgstr "Vacío de informes temporales" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__valid +msgid "Valid" +msgstr "Válido" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__type +msgid "Value type" +msgstr "Tipo del valor" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Visibility" +msgstr "Visibilidad" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__w +#, python-format +msgid "Week" +msgstr "Semana" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_duration +msgid "Wrong duration, it must be positive!" +msgstr "¡Duración incorrecta, debe ser positiva!" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_normalize_factor +msgid "Wrong normalize factor, it must be positive!" +msgstr "Factor de normalización incorrecto. ¡Debe ser positivo!" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__y +#, python-format +msgid "Year" +msgstr "Año" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Year to date" +msgstr "El año hasta la fecha" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "You cannot sum period %s with itself." +msgstr "No puede sumar el periodo %s consigo mismo." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "from %s to %s" +msgstr "desde %s hasta %s" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__large +msgid "large" +msgstr "grande" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__medium +msgid "medium" +msgstr "mediana" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "or" +msgstr "o" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "pp" +msgstr "pp" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__small +msgid "small" +msgstr "pequeña" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_from_id +msgid "versus" +msgstr "contra" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-large +msgid "x-large" +msgstr "extra-grande" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-small +msgid "x-small" +msgstr "extra-pequeña" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-large +msgid "xx-large" +msgstr "extra-súper-grande" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-small +msgid "xx-small" +msgstr "extra-súper-pequeña" + +#~ msgid "" +#~ "AccountingNone: a null value that behaves as 0 in arithmetic " +#~ "operations." +#~ msgstr "" +#~ "AccountingNone: un valor nulo que se comporta como 0 en " +#~ "operaciones aritméticas." + +#~ msgid "" +#~ "bal, crd, deb, pbal, nbal: balance, debit, credit, positive " +#~ "balance, negative balance." +#~ msgstr "" +#~ " bal, crd, deb, pbal, nbal : saldo, débito, crédito, saldo " +#~ "positivo, saldo negativo." + +#~ msgid "" +#~ "bal[70]: variation of the balance of account 70 over the period " +#~ "(it is the same as balp[70]." +#~ msgstr "" +#~ "bal[70]: variación del saldo de la cuenta 70 en el periodo (es lo " +#~ "mismo que balp[70]." + +#~ msgid "" +#~ "bale[1%]: balance of accounts starting with 1 at end of period." +#~ msgstr "" +#~ "bale[1%]: saldo al final del periodo de las cuentas que empiezan " +#~ "en 1." + +#~ msgid "bali[70,60]: initial balance of accounts 70 and 60." +#~ msgstr "bali[70,60]: Saldo inicial de las cuentas 70 y 60." + +#~ msgid "" +#~ "balp[('user_type_id', '=', ref('account.data_account_type_receivable')." +#~ "id)][]: variation of the balance of all receivable accounts over the " +#~ "period." +#~ msgstr "" +#~ "balp[('user_type_id', '=', ref('account.data_account_type_receivable')." +#~ "id)][]: variación del saldo de todas las cuentas a cobrar en el " +#~ "periodo." + +#~ msgid "" +#~ "balp[][('tax_line_id.tag_ids', '=', ref('l10n_be.tax_tag_56').id)]: balance of move lines related to tax grid 56." +#~ msgstr "" +#~ "balp[][('tax_line_id.tag_ids', '=', ref('l10n_be.tax_tag_56').id)]: saldo de los apuntes relacionados con la etiqueta de impuesto 56." + +#~ msgid "" +#~ "balu[]: (u for unallocated) is a special expression that shows the " +#~ "unallocated profit/loss of previous\n" +#~ " fiscal years." +#~ msgstr "" +#~ "balu[]: (u for unallocated) es una expresión especial que muestra " +#~ "las pérdidas y ganancias sin asignar de los ejercicios fiscales " +#~ "anteriores." + +#~ msgid "" +#~ "crdp[40%]: sum of all credits on accounts starting with 40 during " +#~ "the period." +#~ msgstr "" +#~ "crdp[40%]: suma de todos los haber de las cuentas que empiezan por " +#~ "40 durante el periodo." + +#~ msgid "date_from, date_to: beginning and end date of the period." +#~ msgstr "" +#~ "date_from, date_to: fecha de inicio y fecha de fin del periodo." + +#~ msgid "datetime, datetime, dateutil: the python modules." +#~ msgstr "datetime, datetime, dateutil: los módulos python." + +#~ msgid "" +#~ "debp[55%][('journal_id.code', '=', 'BNK1')]: sum of all debits on " +#~ "accounts 55 and journal BNK1 during the period." +#~ msgstr "" +#~ "debp[55%][('journal_id.code', '=', 'BNK1')]: suma de todos los " +#~ "debe en las cuentas que empiezan por 55 y en el diario BNK1 durante el " +#~ "periodo." + +#~ msgid "" +#~ "p, i, e: respectively variation over the period, initial balance, " +#~ "ending balance" +#~ msgstr "" +#~ " p, i, e : variación respectivamente durante el período, saldo " +#~ "inicial, saldo final" + +#~ msgid "" +#~ "pbale[55%]: sum of all ending balances of accounts starting with " +#~ "55 whose\n" +#~ " ending balance is positive." +#~ msgstr "" +#~ " pbale [55%] : suma de todos los saldos finales de cuentas que " +#~ "comienzan con 55 cuyos\n" +#~ "............................................el saldo final es positivo." + +#~ msgid "" +#~ "sum, min, max, len, avg: behave as expected, very similar to the " +#~ "python builtins." +#~ msgstr "" +#~ "sum, min, max, len, avg: se comportan como se espera, muy " +#~ "similares a los nativos de Python." + +#~ msgid "" +#~ "Additionally following variables are available in the evaluation context:" +#~ msgstr "" +#~ "Las siguientes variables adicionales están disponibles en el contexto de " +#~ "evaluación:" + +#~ msgid "" +#~ "Expressions can involve other KPI, sub KPI and query results by name (eg " +#~ "kpi1 + kpi2, kpi2.subkpi1, query1.field1)." +#~ msgstr "" +#~ "La expresión también puede incluir otros KPI y resultados de consulta por " +#~ "nombre (por ejemplo, kpi1 + kpi2)." + +#~ msgid "" +#~ "The account selector is a like expression on the account code (eg " +#~ "70%, etc)." +#~ msgstr "" +#~ "El selector de cuenta es como una expresión en el código de cuenta " +#~ "(por ejemplo, 70%, etc)." + +#~ msgid "" +#~ "The journal items domain is an Odoo domain filter on journal items." +#~ msgstr "" +#~ "El dominio de apuntes es un filtro de dominio Odoo sobre los " +#~ "apuntes." + +#~ msgid "" +#~ "The following special elements are recognized in the expressions to " +#~ "compute accounting data:\n" +#~ " {bal|crd|deb|pbal|nbal}" +#~ "{pieu}[account selector][journal items domain]." +#~ msgstr "" +#~ "Los siguientes elementos especiales se reconocen en las expresiones para " +#~ "calcular los datos contables:\n" +#~ " {bal | crd | deb | pbal | nbal} {pieu} [selector de cuenta] " +#~ "[dominio de elementos de diario] ." + +#~ msgid "MIS Budget" +#~ msgstr "Presupuesto MIS" + +#~ msgid "report.mis_builder.mis_report_instance_xlsx" +#~ msgstr "report.mis_builder.mis_report_instance_xlsx" + +#~ msgid "" +#~ "Probably not your fault... but I'm really curious to know how you managed " +#~ "to raise this error so I can handle one more corner case!" +#~ msgstr "" +#~ "Probablemente no es su culpa... ¡pero realmente hay curiosidad por saber " +#~ "cómo ha conseguido este error para poder manejar un caso extremo más!" + +#~ msgid "µ" +#~ msgstr "µ" + +#~ msgid "add.mis.report.instance.dashboard.wizard" +#~ msgstr "add.mis.report.instance.dashboard.wizard" + +#~ msgid "ir.actions.report" +#~ msgstr "ir.actions.report" + +#~ msgid "mis.report" +#~ msgstr "mis.report" + +#~ msgid "mis.report.instance" +#~ msgstr "mis.report.instance" + +#~ msgid "mis.report.instance.period" +#~ msgstr "mis.report.instance.period" + +#~ msgid "mis.report.instance.period.sum" +#~ msgstr "mis.report.instance.period.sum" + +#~ msgid "mis.report.kpi" +#~ msgstr "mis.report.kpi" + +#~ msgid "mis.report.kpi.expression" +#~ msgstr "mis.report.kpi.expression" + +#~ msgid "mis.report.query" +#~ msgstr "mis.report.query" + +#~ msgid "mis.report.style" +#~ msgstr "mis.report.style" + +#~ msgid "mis.report.subkpi" +#~ msgstr "mis.report.subkpi" diff --git a/odex25_accounting/mis_builder/i18n/fr.po b/odex25_accounting/mis_builder/i18n/fr.po new file mode 100644 index 000000000..b189ed60d --- /dev/null +++ b/odex25_accounting/mis_builder/i18n/fr.po @@ -0,0 +1,1997 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mis_builder +# +# Translators: +# OCA Transbot , 2018 +# Nicolas JEUDY , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-02-10 07:59+0000\n" +"PO-Revision-Date: 2020-09-23 17:00+0000\n" +"Last-Translator: Régis Pirard (ACSONE) \n" +"Language-Team: French (https://www.transifex.com/oca/teams/23907/fr/)\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 3.10\n" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "%s (copy)" +msgstr "%s (copie)" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[('user_type_id', '=',\n" +" ref('account.\n" +" data_account_type_receivable')." +"id)][]\n" +" \n" +" : variation of the balance of " +"all receivable\n" +" accounts over the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[][('tax_line_id." +"tag_ids', '=',\n" +" ref('l10n_be.tax_tag_56')." +"id)]\n" +" \n" +" : balance of move lines related " +"to tax grid\n" +" 56." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" debp[55%][('journal_id." +"code', '=',\n" +" 'BNK1')]\n" +" \n" +" : sum of all debits on accounts " +"55 and\n" +" journal BNK1 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"AccountingNone\n" +" : a null value that behaves as 0 " +"in\n" +" arithmetic operations." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal, crd, deb, pbal, nbal\n" +" : balance, debit, credit, " +"positive balance,\n" +" negative balance." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal[70]\n" +" : variation of the balance of " +"account 70\n" +" over the period (it is the same " +"as balp[70]." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bale[1%]\n" +" : balance of accounts starting " +"with 1 at end\n" +" of period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bali[70,60]\n" +" : initial balance of accounts 70 " +"and 60." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"balu[]\n" +" : (u for unallocated) is a " +"special\n" +" expression that shows the " +"unallocated\n" +" profit/loss of previous\n" +" fiscal years." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"crdp[40%]\n" +" : sum of all credits on accounts " +"starting\n" +" with 40 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"date_from, date_to\n" +" : beginning and end date of the " +"period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"datetime, datetime, dateutil\n" +" : the python modules." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"p, i, e\n" +" : respectively variation over " +"the period,\n" +" initial balance, ending balance" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"pbale[55%]\n" +" : sum of all ending balances of " +"accounts\n" +" starting with 55 whose\n" +" ending balance is positive." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"sum, min, max, len, avg\n" +" : behave as expected, very " +"similar to the\n" +" python builtins." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields." +msgstr "" +"Un modèle 'move line like', ie ayant au moins les champs débit, crédit, " +"account_id et company_id." + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__move_lines_source +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields. This model is the data source for column Actuals." +msgstr "" +"Un modèle 'move line like', ie ayant au moins les champs débit, crédit, " +"account_id et company_id. Ce modèle est la source pour la colonne \"Réels\"." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "A date filter is mandatory for this source in column %s." +msgstr "Un filtre date est obligatoire pour cette source dans la colonne %s." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__account_model +msgid "Account model" +msgstr "Additionne le détail des comptes" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__accumulation_method +msgid "Accumulation Method" +msgstr "Méthode d'accumulation" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "" +"Actual (alternative) models used in columns must have the same account model " +"in the Account field and must be the same defined in the report template: %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals +msgid "Actuals" +msgstr "Réels" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals_alt +msgid "Actuals (alternative)" +msgstr "Réels (autre)" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source +msgid "" +"Actuals: current data, from accounting and other queries.\n" +"Actuals (alternative): current data from an alternative source (eg a " +"database view providing look-alike account move lines).\n" +"Sum columns: summation (+/-) of other columns.\n" +"Compare to column: compare to other column.\n" +msgstr "" +"Réels: données actuelles, de la comptabilité et autres requêtes.\n" +"Réels (autre): données actuelles d'une autre source (eg une vue d'une base " +"de données fournissant des lignes de mouvements de comptes similaires).\n" +"Somme colonnes: somme (+/-) d'autres colonnes.\n" +"Comparer colonnes: compare à  une autre colonne.\n" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_prorata_read_group_mixin +msgid "Adapt model with date_from/date_to for pro-rata temporis read_group" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_add_to_dashboard_action +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Add to dashboard" +msgstr "Ajouter au tableau de bord" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Additionally following variables are available\n" +" in the evaluation context:" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__aggregate +msgid "Aggregate" +msgstr "Agréger" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__all +msgid "All Entries" +msgstr "Écritures comptabilisées + non-comptabilisées" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__all_kpi_ids +msgid "All Kpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__posted +msgid "All Posted Entries" +msgstr "Écritures comptabilisées seulement" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__allowed_cmpcol_ids +msgid "Allowed Cmpcol" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__amount +msgid "Amount" +msgstr "Montant" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__style_expression +msgid "" +"An expression that returns a style depending on the KPI value. Such style is " +"applied on top of the row style." +msgstr "" +"Une expression qui retourne un style en fonction de la valeur du KPI. Un tel " +"style est appliqué au-dessus du style de la ligne." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_account_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "Analytic Account" +msgstr "Compte Analytique" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Account Filter" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_group_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_group_id +#, python-format +msgid "Analytic Account Group" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account Group: %s" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account: %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_tag_ids +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "Analytic Tags" +msgstr "Étiquettes analytiques" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Tags Filter" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Tags: %s" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Auto expand" +msgstr "Expansion automatique" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__avg +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__avg +#, python-format +msgid "Average" +msgstr "Moyenne" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color +msgid "Background Color" +msgstr "Couleur d'arrière-plan" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color_inherit +msgid "Background Color Inherit" +msgstr "Couleur d'arrière plan par défaut" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__background_color +msgid "Background color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "Couleur d'arrière-plan en code RGB valide (de #000000 à  #FFFFFF)" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date +msgid "Base date" +msgstr "Date de référence" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__bold +msgid "Bold" +msgstr "Gras" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Can not update a multi kpi from the kpi line" +msgstr "Vous ne pouvez pas mettre à  jour un kpi multi depuis la ligne de kpi" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Cancel" +msgstr "Annuler" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__multi_company +msgid "" +"Check if you wish to specify children companies to be searched for data." +msgstr "" +"Vérifiez si vous souhaitez spécifier des sociétés enfants dont les données " +"seront recherchées." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Color" +msgstr "Couleur" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color_inherit +msgid "Color Inherit" +msgstr "Couleur par défaut" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_to_sum_id +msgid "Column" +msgstr "Colonne" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, fuzzy, python-format +msgid "Column %s cannot be compared to itrec." +msgstr "Colonne %s ne peut pas être comparée à  elle-même." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, fuzzy, python-format +msgid "Column %s with move lines source must have from/to dates." +msgstr "Colonne %s avec une source pour le réel doit avoir des dates de/à ." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Columns" +msgstr "Colonnes" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Columns to compare must belong to the same report in %s" +msgstr "Les colonnes à  comparer doivent appartenir au même rapport %s" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_ids +msgid "Columns to sum" +msgstr "Colonnes à additionner" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "Columns {} and {} are not comparable" +msgstr "Les colonnes {} et {} ne sont pas comparables" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_ids +msgid "Companies" +msgstr "Sociétés" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__query_company_ids +msgid "Companies for which data will be searched." +msgstr "Sociétés pour lesquelles les données seront recherchées." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_id +msgid "Company" +msgstr "Société" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_to_id +msgid "Compare" +msgstr "Comparer" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__cmpcol +msgid "Compare columns" +msgstr "Compare colonnes" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__compare_method +msgid "Comparison Method" +msgstr "Méthode de comparaison" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__comparison_mode +msgid "Comparison Mode" +msgstr "Mode de comparaison" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_uid +msgid "Created by" +msgstr "Créé par" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_date +msgid "Created on" +msgstr "Créé le" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__currency_id +msgid "Currency" +msgstr "Devise" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__dashboard_id +msgid "Dashboard" +msgstr "Tableau de bord" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date +#, fuzzy +msgid "Date" +msgstr "Dates" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__date_field +msgid "Date Field" +msgstr "Champ date" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_from +#, fuzzy +msgid "Date From" +msgstr "Champ date" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_range_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_id +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__date_range +#, python-format +msgid "Date Range" +msgstr "Intervalle de dates" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_type_id +msgid "Date Range Type" +msgstr "Type d'intervalle de dates" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_to +#, fuzzy +msgid "Date To" +msgstr "Dates" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Dates" +msgstr "Dates" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__d +#, python-format +msgid "Day" +msgstr "Jour" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__description +msgid "Description" +msgstr "Description" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__accumulation_method +msgid "" +"Determines how values of this kpi spanning over a time period are " +"transformed to match the reporting period. Sum: values of shorter period are " +"added, values of longest or partially overlapping periods are adjusted pro-" +"rata temporis.\n" +"Average: values of included period are averaged with a pro-rata temporis " +"weight." +msgstr "" +"Détermines comment les valeurs de ce KPI, s'étendant au délà  d'une période, " +"sont transformées pour correspondre à  la période de reporting. Somme : les " +"valeurs des périodes plus courtes sont additionnées, les valeurs des " +"périodes plus longues ou se chevauchant sont ajustées au pro-rata temporis.\n" +"Moyenne : moyenne au pro-rata temporis des valeurs incluses dans la période." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__diff +#, python-format +msgid "Difference" +msgstr "Différence" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__no_auto_expand_accounts +msgid "Disable account details expansion" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display Columns Description" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__display_name +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__display_name +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__display_name +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__display_name +msgid "Display Name" +msgstr "Nom affiché" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts +msgid "Display details by account" +msgstr "Affiche les détails par compte" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display the date range details in the column headers." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider_inherit +msgid "Divider Inherit" +msgstr "Diviseur par défaut" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__domain +msgid "Domain" +msgstr "Domaine" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp_inherit +msgid "Dp Inherit" +msgstr "Dp par défaut" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_prorata_read_group_mixin__date +msgid "" +"Dummy field that adapts searches on date to searches on date_from/date_to." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__duration +msgid "Duration" +msgstr "Durée" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Enter expression here, for example balp[70%]. See also help tab." +msgstr "" +"Entrez l'expression ici, par exemple balp[70%]. Voir aussi l'onglet aide." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Examples:" +msgstr "Exemples :" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Export" +msgstr "Export" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__expression_ids +msgid "Expression" +msgstr "Expression" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions" +msgstr "Expressions" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions can be any valid python expressions." +msgstr "" +"Les expressions peuvent être n'importe quelle expression python valide." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Expressions can involve other KPI, sub KPI and\n" +" query results by name (eg kpi1 + " +"kpi2,\n" +" kpi2.subkpi1, query1.field1)." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__normalize_factor +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider +msgid "Factor" +msgstr "Facteur" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Factor inherit" +msgstr "Facteur par défaut" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__normalize_factor +msgid "Factor to use to normalize the period (used in comparison" +msgstr "Facteur à  utiliser pour normaliser la période (utilisé en comparaison" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_names +msgid "Fetched fields name" +msgstr "Nom des champs cherchés" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_ids +msgid "Fields to fetch" +msgstr "Champs à  chercher" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "" +"Filter column on journal entries that have all these analytic tags.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_group_id +msgid "" +"Filter column on journal entries that match this analytic account group. " +"This filter is combined with a AND with the report-level filters and cannot " +"be modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "" +"Filter column on journal entries that match this analytic account.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Filters" +msgstr "Filtres" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__fix +msgid "Fixed dates" +msgstr "Dates fixes" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Font" +msgstr "Police" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size +msgid "Font Size" +msgstr "Taille de police" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size_inherit +msgid "Font Size Inherit" +msgstr "Taille de police par défaut" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style +msgid "Font Style" +msgstr "Style de police" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style_inherit +msgid "Font Style Inherit" +msgstr "Style de police par défaut" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight +msgid "Font Weight" +msgstr "Poids de police de caractères" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight_inherit +msgid "Font Weight Inherit" +msgstr "Poids de police par défaut" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Forces the start date to Jan 1st of the relevant year" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_from +msgid "From" +msgstr "De" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_from +msgid "From (computed)" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/report/mis_report_instance_xlsx.py:0 +#, python-format +msgid "Generated on {} at {}" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Help (for KPI expressions)" +msgstr "Aide (pour expressions des KPI)" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always +msgid "Hide Always" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always_inherit +msgid "Hide Always Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__hide_analytic_filters +msgid "Hide Analytic Filters" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty +msgid "Hide Empty" +msgstr "Cacher les vides" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty_inherit +msgid "Hide Empty Inherit" +msgstr "Cacher les vides par défaut" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__id +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__id +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__id +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__id +msgid "ID" +msgstr "ID" + +#. module: mis_builder +#: code:addons/mis_builder/models/aep.py:0 +#, python-format +msgid "" +"If currency_id is not provided, all companies must have the same currency." +msgstr "" +"Si le currency_id n'est pas renseigné, toutes les sociétés doivent avoir la " +"même devise." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Indent" +msgstr "Alinéa" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level +msgid "Indent Level" +msgstr "Niveau de retrait" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level_inherit +msgid "Indent Level Inherit" +msgstr "Niveau de retrait par défaut" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "Indent level must be greater than or equal to 0" +msgstr "Le niveau de retrait doit être plus grand ou égal à  0" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__italic +msgid "Italic" +msgstr "Italique" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__kpi_expression_id +msgid "KPI" +msgstr "KPI" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" has type {} while a tuple was expected.\n" +"\n" +"This can be fixed by either:\n" +"\t- Changing the KPI value to a tuple of length {}\n" +"or\n" +"\t- Changing the KPI to `multi` mode and giving an explicit value for each " +"sub-KPI." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" is valued as a tuple of length {} while a tuple of length {} is " +"expected." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq1 +#, fuzzy +msgid "KPI Sequence" +msgstr "Séquence" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, fuzzy, python-format +msgid "KPI name ({}) must be a valid python identifier" +msgstr "Le nom doit être un identifiant python valide" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__kpi_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "KPI's" +msgstr "KPI's" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__all_kpi_ids +msgid "KPIs of this report and subreports." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__kpi_id +msgid "Kpi" +msgstr "Kpi" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__name +msgid "Label" +msgstr "Description" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__landscape_pdf +msgid "Landscape PDF" +msgstr "PDF paysage" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard____last_update +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport____last_update +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin____last_update +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx____last_update +msgid "Last Modified on" +msgstr "Dernière modification le" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.last_mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.last_wizard_mis_report_instance_view_menu +msgid "Last Reports Generated" +msgstr "Derniers rapports générés" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_uid +msgid "Last Updated by" +msgstr "Dernière mise à jour par" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_date +msgid "Last Updated on" +msgstr "Dernière mise à jour le" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Layout" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_report_mis_builder_mis_report_instance_xlsx +#, fuzzy +msgid "MIS Builder XLSX report" +msgstr "Instance MIS report XLS report" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_kpi_data +msgid "MIS Kpi Data Abtract class" +msgstr "Classe abstraite de données MIS KPI" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "MIS Report" +msgstr "MIS Report" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subreport +#, fuzzy +msgid "MIS Report - Sub Reports Relation" +msgstr "Résultat MIS Report" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_add_mis_report_instance_dashboard_wizard +#, fuzzy +msgid "MIS Report Add to Dashboard Wizard" +msgstr "Ajouter au tableau de bord" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "MIS Report Instance" +msgstr "Instance MIS report" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period +#, fuzzy +msgid "MIS Report Instance Period" +msgstr "Instance MIS report" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period_sum +#, fuzzy +msgid "MIS Report Instance Period Sum" +msgstr "Instance MIS report" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "MIS Report Instances" +msgstr "Instances MIS report" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "MIS Report KPI" +msgstr "MIS Report KPI" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi_expression +#, fuzzy +msgid "MIS Report KPI Expression" +msgstr "MIS Report KPI" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_query +#, fuzzy +msgid "MIS Report Query" +msgstr "MIS Report" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_result_view_form +msgid "MIS Report Result" +msgstr "Résultat MIS Report" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_style +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "MIS Report Style" +msgstr "Style MIS Report" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_style_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_style_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_tree +msgid "MIS Report Styles" +msgstr "Styles MIS Report" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subkpi +#, fuzzy +msgid "MIS Report Sub-KPI" +msgstr "MIS Report KPI" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report +#, fuzzy +msgid "MIS Report Template" +msgstr "Modèles MIS Report" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_view_menu +msgid "MIS Report Templates" +msgstr "Modèles MIS Report" + +#. module: mis_builder +#: model:ir.ui.menu,name:mis_builder.mis_report_conf_menu +#: model:ir.ui.menu,name:mis_builder.mis_report_finance_menu +msgid "MIS Reporting" +msgstr "MIS Reporting" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_instance_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_tree +msgid "MIS Reports" +msgstr "MIS Reports" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.qweb_pdf_export +msgid "MIS report instance QWEB PDF report" +msgstr "Instance MIS report QWEB PDF report" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.xls_export +msgid "MIS report instance XLS report" +msgstr "Instance MIS report XLS report" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__max +#, python-format +msgid "Max" +msgstr "Max" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__min +#, python-format +msgid "Min" +msgstr "Min" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__mode +msgid "Mode" +msgstr "Mode" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__model_id +msgid "Model" +msgstr "Modèle" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__m +#, python-format +msgid "Month" +msgstr "Mois" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__move_lines_source +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "Move lines source" +msgstr "Source des lignes d'écriture" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_name +#, fuzzy +msgid "Move lines source model name" +msgstr "Source des lignes d'écriture" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__multi +msgid "Multi" +msgstr "Multi" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__multi_company +msgid "Multiple companies" +msgstr "Sociétés multiples" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__name +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Name" +msgstr "Nom" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__none +msgid "No date filter" +msgstr "Pas de filtre date" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "No date filter is allowed for this source in column %s." +msgstr "Aucun filtre date n'est autorisé pour cette source dans la colonne %s." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__none +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__none +#, python-format +msgid "None" +msgstr "Aucun" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__normal +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__nornal +msgid "Normal" +msgstr "Normal" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Number" +msgstr "Nombre" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__duration +msgid "Number of periods" +msgstr "Nombre de périodes" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__num +#, python-format +msgid "Numeric" +msgstr "Numérique" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__offset +msgid "Offset" +msgstr "Compensation" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__offset +msgid "Offset from current period" +msgstr "Compensation depuis la période actuelle" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_id +msgid "Parent column" +msgstr "Colonne parent" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__pct +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__pct +#, python-format +msgid "Percentage" +msgstr "Pourcentage" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_name_unique +msgid "Period name should be unique by report" +msgstr "Le nom de la période doit être unique par rapport" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__type +msgid "Period type" +msgstr "Type de période" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__period_ids +msgid "Periods" +msgstr "Périodes" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__pivot_date +msgid "Pivot date" +msgstr "Date pivot" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Please provide both columns to compare in %s." +msgstr "Merci de renseigner les 2 colonnes à  comparer en %s." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix +msgid "Prefix" +msgstr "Préfixe" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix_inherit +msgid "Prefix Inherit" +msgstr "Préfixe par défaut" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Preview" +msgstr "Prévisualisation" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Print" +msgstr "Imprimer" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__query_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Queries" +msgstr "Requêtes" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__query_company_ids +msgid "Query Company" +msgstr "Société de la requête" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, fuzzy, python-format +msgid "Query name ({}) must be valid python identifier" +msgstr "Le nom doit être un identifiant python valide" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Refresh" +msgstr "Rafraîchir" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__relative +msgid "Relative to report base date" +msgstr "Relatif à  la date de référence du rapport" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__report_id +msgid "Report" +msgstr "Rapport" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_ir_actions_report +#, fuzzy +msgid "Report Action" +msgstr "Instance de rapport" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_instance_id +msgid "Report Instance" +msgstr "Instance de rapport" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__date +msgid "Report base date (leave empty to use current date)" +msgstr "" +"Date de référence du rapport (laissez vide pour utiliser la date du jour)" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp +msgid "Rounding" +msgstr "Arrondi" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Rounding inherit" +msgstr "Arrondi par défaut" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Save" +msgstr "Sauvegarder" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__company_ids +msgid "Select companies for which data will be searched." +msgstr "" +"Selectionnez les sociétés pour lesquelles les données seront cherchées." + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__currency_id +msgid "" +"Select target currency for the report. Required if companies have different " +"currencies." +msgstr "" +"Selectionnez la devise du rapport. Nécessaire si les sociétés ont des " +"devises différentes." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__sequence +msgid "Sequence" +msgstr "Séquence" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Settings" +msgstr "Paramètres" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_subreport_unique +msgid "" +"Should not include the same report more than once as sub report of a given " +"report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__sign +msgid "Sign" +msgstr "Signer" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Source" +msgstr "Source" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__str +#, python-format +msgid "String" +msgstr "Chaîne de caractères" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__style_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_id +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Style" +msgstr "Style" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_expression +msgid "Style expression" +msgstr "Expression du style" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts_style_id +msgid "Style for account detail rows" +msgstr "Style pour les lignes de détails" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__name +msgid "Style name" +msgstr "Nom du style" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subkpi_ids +msgid "Sub KPI" +msgstr "Sous KPI" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__subkpi_ids +msgid "Sub KPI Filter" +msgstr "Filtre du sous KPI" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_kpi_expression_subkpi_kpi_unique +msgid "Sub KPI must be used once and only once for each KPI" +msgstr "" +"Un sous KPI ne doit être utilisé qu'une et une seule fois pour chaque KPI" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Sub KPI's" +msgstr "Sous KPI's" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +#, fuzzy +msgid "Sub Reports" +msgstr "MIS Reports" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subreport_ids +#, fuzzy +msgid "Sub reports" +msgstr "MIS Reports" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq2 +#, fuzzy +msgid "Sub-KPI Sequence" +msgstr "Séquence" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, fuzzy, python-format +msgid "Sub-KPI name ({}) must be a valid python identifier" +msgstr "Le nom doit être un identifiant python valide" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__subkpi_id +msgid "Subkpi" +msgstr "Subkpi" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__subreport_id +#, fuzzy +msgid "Subreport" +msgstr "Rapport" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, python-format +msgid "Subreport loop detected" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, fuzzy, python-format +msgid "Subreport name ({}) must be a valid python identifier" +msgstr "Le nom doit être un identifiant python valide" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_name_unique +#, fuzzy +msgid "Subreport name should be unique by report" +msgstr "Le nom de la période doit être unique par rapport" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix +msgid "Suffix" +msgstr "Suffixe" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix_inherit +msgid "Suffix Inherit" +msgstr "Suffixe par défaut" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__sum +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__sum +#, python-format +msgid "Sum" +msgstr "Somme" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_accdet +msgid "Sum account details" +msgstr "Additionne le détail des comptes" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "" +"Sum cannot be computed in column {} because the columns to sum have no " +"common subkpis" +msgstr "" +"La somme ne peut pas être calculée dans la colonne {} car les colonnes à  " +"additionner n'ont pas de sous KPI's communs" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__sumcol +msgid "Sum columns" +msgstr "Colonnes à additionner" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__target_move +msgid "Target Moves" +msgstr "Écritures ciblées" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "Template" +msgstr "Modèle" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__temporary +msgid "Temporary" +msgstr "Temporaire" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color +msgid "Text color" +msgstr "Couleur du texte" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__color +msgid "Text color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "Couleur du texte en code RGB valide (de #000000 à  #FFFFFF)" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" account selector\n" +" is a like expression on the " +"account code (eg\n" +" 70%, etc)." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" journal items domain\n" +" is an Odoo domain filter on " +"journal items." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The following special elements are recognized in\n" +" the expressions to compute " +"accounting data:\n" +" \n" +" {bal|crd|deb|pbal|nbal}{pieu}" +"[account\n" +" selector][journal items domain]\n" +" \n" +" ." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_to +msgid "To" +msgstr "à " + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_to +msgid "To (computed)" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_kpi_data.py:0 +#, python-format +msgid "Unexpected accumulation method %s for %s." +msgstr "Méthode d'accumulation inattendue %s pour %s." + +#. module: mis_builder +#: code:addons/mis_builder/models/prorata_read_group_mixin.py:0 +#, python-format +msgid "Unsupported operator %s for searching on date" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.server,name:mis_builder.ir_cron_vacuum_temp_reports_ir_actions_server +#: model:ir.cron,cron_name:mis_builder.ir_cron_vacuum_temp_reports +#: model:ir.cron,name:mis_builder.ir_cron_vacuum_temp_reports +msgid "Vacuum temporary reports" +msgstr "Vider les rapports temporaires" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__valid +msgid "Valid" +msgstr "Valide" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__type +msgid "Value type" +msgstr "Type de valeur" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Visibility" +msgstr "Visibilité" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__w +#, python-format +msgid "Week" +msgstr "Semaine" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_duration +msgid "Wrong duration, it must be positive!" +msgstr "Durée incorrecte, elle doit être positive !" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_normalize_factor +msgid "Wrong normalize factor, it must be positive!" +msgstr "Facteur de normalisation incorrect, il doit être positif !" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__y +#, python-format +msgid "Year" +msgstr "Année" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Year to date" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "You cannot sum period %s with itself." +msgstr "Vous ne pouvez pas additionner la période %s avec elle-meme." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "from %s to %s" +msgstr "de %s à  %s" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__large +msgid "large" +msgstr "grand" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__medium +msgid "medium" +msgstr "moyen" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "or" +msgstr "ou" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "pp" +msgstr "pp" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__small +msgid "small" +msgstr "petit" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_from_id +msgid "versus" +msgstr "versus" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-large +msgid "x-large" +msgstr "x-grand" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-small +msgid "x-small" +msgstr "x-petit" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-large +msgid "xx-large" +msgstr "xx-grand" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-small +msgid "xx-small" +msgstr "xx-petit" + +#~ msgid "" +#~ "AccountingNone: a null value that behaves as 0 in arithmetic " +#~ "operations." +#~ msgstr "" +#~ "AccountingNone: une valeur nulle qui se comporte comme un zero " +#~ "dans les opérations arithmétiques." + +#~ msgid "" +#~ "bal, crd, deb, pbal, nbal: balance, debit, credit, positive " +#~ "balance, negative balance." +#~ msgstr "" +#~ "bal, crd, deb, pbal, nbal: balance, débit, crédit, balance " +#~ "positive, balance négative." + +#~ msgid "" +#~ "bal[70]: variation of the balance of account 70 over the period " +#~ "(it is the same as balp[70]." +#~ msgstr "" +#~ "1bal[70]2: variation de la balance des comptes 70 de la période " +#~ "(similaire à  balp[70]." + +#~ msgid "" +#~ "bale[1%]: balance of accounts starting with 1 at end of period." +#~ msgstr "" +#~ "1bale[1%]2: balance des comptes commençant par 1 à  la fin de la " +#~ "période." + +#~ msgid "bali[70,60]: initial balance of accounts 70 and 60." +#~ msgstr "1bali[70,60]2: balance initiale des comptes 70 et 60." + +#~ msgid "" +#~ "balp[('user_type_id', '=', ref('account.data_account_type_receivable')." +#~ "id)][]: variation of the balance of all receivable accounts over the " +#~ "period." +#~ msgstr "" +#~ "balp[('user_type_id', '=', ref('account.data_account_type_receivable')." +#~ "id)][]: variation de la balance des comptes clients durant la période." + +#~ msgid "" +#~ "balp[][('tax_line_id.tag_ids', '=', ref('l10n_be.tax_tag_56').id)]: balance of move lines related to tax grid 56." +#~ msgstr "" +#~ "balp[][('tax_line_id.tag_ids', '=', ref('l10n_be.tax_tag_56').id)]: balance des lignes d'écritures liées au code taxe 56." + +#~ msgid "" +#~ "balu[]: (u for unallocated) is a special expression that shows the " +#~ "unallocated profit/loss of previous\n" +#~ " fiscal years." +#~ msgstr "" +#~ "balu[]: (u pour non-allouée) c'est une expression spéciale qui " +#~ "montre le bénéfice/perte non-alloué des années fiscales précédentes." + +#~ msgid "" +#~ "crdp[40%]: sum of all credits on accounts starting with 40 during " +#~ "the period." +#~ msgstr "" +#~ "crdp[40%]: somme de tous les crédits des comptes commençant par 40 " +#~ "durant la période." + +#~ msgid "date_from, date_to: beginning and end date of the period." +#~ msgstr "date_from, date_to: date de début et de fin de la période." + +#~ msgid "datetime, datetime, dateutil: the python modules." +#~ msgstr "datetime, datetime, dateutil: les modules python." + +#~ msgid "" +#~ "debp[55%][('journal_id.code', '=', 'BNK1')]: sum of all debits on " +#~ "accounts 55 and journal BNK1 during the period." +#~ msgstr "" +#~ "debp[55%][('journal_id.code', '=', 'BNK1')]: somme de tous les " +#~ "débits des comptes 55 et journal BNK1 durant la période." + +#~ msgid "" +#~ "p, i, e: respectively variation over the period, initial balance, " +#~ "ending balance" +#~ msgstr "" +#~ "p, i, e: respectivement variation de la période, balance initiale, " +#~ "balance finale" + +#~ msgid "" +#~ "pbale[55%]: sum of all ending balances of accounts starting with " +#~ "55 whose\n" +#~ " ending balance is positive." +#~ msgstr "" +#~ "pbale[55%]: somme de toutes les balances finales des comptes " +#~ "débutant par 55\n" +#~ " et dont la balance finale est " +#~ "positive." + +#~ msgid "" +#~ "sum, min, max, len, avg: behave as expected, very similar to the " +#~ "python builtins." +#~ msgstr "" +#~ "sum, min, max, len, avg: se comporte comme attendu, très similaire " +#~ "aux expressions python." + +#~ msgid "" +#~ "Additionally following variables are available in the evaluation context:" +#~ msgstr "" +#~ "De plus les variables suivantes sont disponibles dans le contexte " +#~ "d'évaluation :" + +#~ msgid "" +#~ "The account selector is a like expression on the account code (eg " +#~ "70%, etc)." +#~ msgstr "" +#~ "Le sélecteur de compte est une expression Like sur le code du " +#~ "compte (eg 70%, etc)." + +#~ msgid "" +#~ "The journal items domain is an Odoo domain filter on journal items." +#~ msgstr "" +#~ "Le domaine des lignes d'écriture est un filtre de domaine Odoo sur " +#~ "les lignes d'écriture." + +#~ msgid "MIS Budget" +#~ msgstr "MIS Budget" + +#~ msgid "report.mis_builder.mis_report_instance_xlsx" +#~ msgstr "report.mis_builder.mis_report_instance_xlsx" + +#~ msgid "" +#~ "Probably not your fault... but I'm really curious to know how you managed " +#~ "to raise this error so I can handle one more corner case!" +#~ msgstr "" +#~ "Ce n'est probablement pas votre faute... mais je suis très curieux de " +#~ "savoir comment vous avez réussi à  générer cette erreur de manière à  " +#~ "traiter un nouveau problème !" + +#~ msgid "µ" +#~ msgstr "µ" + +#~ msgid "add.mis.report.instance.dashboard.wizard" +#~ msgstr "add.mis.report.instance.dashboard.wizard" + +#~ msgid "ir.actions.report" +#~ msgstr "ir.actions.report" + +#~ msgid "mis.report" +#~ msgstr "mis.report" + +#~ msgid "mis.report.instance" +#~ msgstr "mis.report.instance" + +#~ msgid "mis.report.instance.period" +#~ msgstr "mis.report.instance.period" + +#~ msgid "mis.report.instance.period.sum" +#~ msgstr "mis.report.instance.period.sum" + +#~ msgid "mis.report.kpi" +#~ msgstr "mis.report.kpi" + +#~ msgid "mis.report.kpi.expression" +#~ msgstr "mis.report.kpi.expression" + +#~ msgid "mis.report.query" +#~ msgstr "mis.report.query" + +#~ msgid "mis.report.style" +#~ msgstr "mis.report.style" + +#~ msgid "mis.report.subkpi" +#~ msgstr "mis.report.subkpi" diff --git a/odex25_accounting/mis_builder/i18n/hr.po b/odex25_accounting/mis_builder/i18n/hr.po new file mode 100644 index 000000000..c48784011 --- /dev/null +++ b/odex25_accounting/mis_builder/i18n/hr.po @@ -0,0 +1,1887 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mis_builder +# +# Translators: +# OCA Transbot , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-13 15:37+0000\n" +"PO-Revision-Date: 2020-01-28 18:13+0000\n" +"Last-Translator: Bole \n" +"Language-Team: Croatian (Croatia) (https://www.transifex.com/oca/teams/23907/" +"hr_HR/)\n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 3.10\n" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "%s (copy)" +msgstr "%s (kopija)" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[('user_type_id', '=',\n" +" ref('account.\n" +" data_account_type_receivable')." +"id)][]\n" +" \n" +" : variation of the balance of " +"all receivable\n" +" accounts over the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[][('tax_line_id." +"tag_ids', '=',\n" +" ref('l10n_be.tax_tag_56')." +"id)]\n" +" \n" +" : balance of move lines related " +"to tax grid\n" +" 56." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" debp[55%][('journal_id." +"code', '=',\n" +" 'BNK1')]\n" +" \n" +" : sum of all debits on accounts " +"55 and\n" +" journal BNK1 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"AccountingNone\n" +" : a null value that behaves as 0 " +"in\n" +" arithmetic operations." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal, crd, deb, pbal, nbal\n" +" : balance, debit, credit, " +"positive balance,\n" +" negative balance." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal[70]\n" +" : variation of the balance of " +"account 70\n" +" over the period (it is the same " +"as balp[70]." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bale[1%]\n" +" : balance of accounts starting " +"with 1 at end\n" +" of period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bali[70,60]\n" +" : initial balance of accounts 70 " +"and 60." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"balu[]\n" +" : (u for unallocated) is a " +"special\n" +" expression that shows the " +"unallocated\n" +" profit/loss of previous\n" +" fiscal years." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"crdp[40%]\n" +" : sum of all credits on accounts " +"starting\n" +" with 40 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"date_from, date_to\n" +" : beginning and end date of the " +"period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"datetime, datetime, dateutil\n" +" : the python modules." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"p, i, e\n" +" : respectively variation over " +"the period,\n" +" initial balance, ending balance" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"pbale[55%]\n" +" : sum of all ending balances of " +"accounts\n" +" starting with 55 whose\n" +" ending balance is positive." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"sum, min, max, len, avg\n" +" : behave as expected, very " +"similar to the\n" +" python builtins." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields." +msgstr "" +"Model sličan 'account move line' modelu, sadrži barem sljedeća polja: debit, " +"credit, account_id i company_id." + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__move_lines_source +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields. This model is the data source for column Actuals." +msgstr "" +"Model sličan 'account move line' modelu, sadrži barem sljedeća polja: debit, " +"credit, account_id i company_id. Ovaj model je izvor podataka za kolonu " +"Trenutno ( Actuals)." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "A date filter is mandatory for this source in column %s." +msgstr "Filter po datumu je obavezan za izvor podataka u koloni %s." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__account_model +msgid "Account model" +msgstr "Model konta" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__accumulation_method +msgid "Accumulation Method" +msgstr "Kumulativna metoda" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "" +"Actual (alternative) models used in columns must have the same account model " +"in the Account field and must be the same defined in the report template: %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals +msgid "Actuals" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals_alt +msgid "Actuals (alternative)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source +msgid "" +"Actuals: current data, from accounting and other queries.\n" +"Actuals (alternative): current data from an alternative source (eg a " +"database view providing look-alike account move lines).\n" +"Sum columns: summation (+/-) of other columns.\n" +"Compare to column: compare to other column.\n" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_prorata_read_group_mixin +msgid "Adapt model with date_from/date_to for pro-rata temporis read_group" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_add_to_dashboard_action +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Add to dashboard" +msgstr "Dodaj na nadzornu ploču" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Additionally following variables are available\n" +" in the evaluation context:" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__aggregate +msgid "Aggregate" +msgstr "Zbrajanje" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__all +msgid "All Entries" +msgstr "Sve stavke" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__all_kpi_ids +msgid "All Kpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__posted +msgid "All Posted Entries" +msgstr "Sve proknjižene stavke" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__allowed_cmpcol_ids +msgid "Allowed Cmpcol" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__amount +msgid "Amount" +msgstr "Iznos" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__style_expression +msgid "" +"An expression that returns a style depending on the KPI value. Such style is " +"applied on top of the row style." +msgstr "" +"Izraz koji vraća stil zavisno od KPI vrijednosti. Takav stil se primjenjuje " +"nakon stila retka." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_account_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "Analytic Account" +msgstr "Analitički konto" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Account Filter" +msgstr "Filter analitičkih konta" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_group_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_group_id +#, python-format +msgid "Analytic Account Group" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account Group: %s" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account: %s" +msgstr "Analitički konto: %s" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_tag_ids +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "Analytic Tags" +msgstr "Oznake analitike" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Tags Filter" +msgstr "Filter oznaka analitike" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Tags: %s" +msgstr "Oznake analitike: %s" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Auto expand" +msgstr "Automatsko širenje" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__avg +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__avg +#, python-format +msgid "Average" +msgstr "Prosjek" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color +msgid "Background Color" +msgstr "Boja pozadine" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color_inherit +msgid "Background Color Inherit" +msgstr "Nasljeđivanje boje pozadine" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__background_color +msgid "Background color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date +msgid "Base date" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__bold +msgid "Bold" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Can not update a multi kpi from the kpi line" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Cancel" +msgstr "Otkaži" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__multi_company +msgid "" +"Check if you wish to specify children companies to be searched for data." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Color" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color_inherit +msgid "Color Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_to_sum_id +msgid "Column" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Column %s cannot be compared to itrec." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Column %s with move lines source must have from/to dates." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Columns" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Columns to compare must belong to the same report in %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_ids +msgid "Columns to sum" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "Columns {} and {} are not comparable" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_ids +msgid "Companies" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__query_company_ids +msgid "Companies for which data will be searched." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_id +msgid "Company" +msgstr "Tvrtka" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_to_id +msgid "Compare" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__cmpcol +msgid "Compare columns" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__compare_method +msgid "Comparison Method" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__comparison_mode +msgid "Comparison Mode" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_uid +msgid "Created by" +msgstr "Kreirao" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_date +msgid "Created on" +msgstr "Kreirano" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__currency_id +msgid "Currency" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__dashboard_id +msgid "Dashboard" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date +msgid "Date" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__date_field +msgid "Date Field" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_from +msgid "Date From" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_range_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_id +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__date_range +#, python-format +msgid "Date Range" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_type_id +msgid "Date Range Type" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_to +msgid "Date To" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Dates" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__d +#, python-format +msgid "Day" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__description +msgid "Description" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__accumulation_method +msgid "" +"Determines how values of this kpi spanning over a time period are " +"transformed to match the reporting period. Sum: values of shorter period are " +"added, values of longest or partially overlapping periods are adjusted pro-" +"rata temporis.\n" +"Average: values of included period are averaged with a pro-rata temporis " +"weight." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__diff +#, python-format +msgid "Difference" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__no_auto_expand_accounts +msgid "Disable account details expansion" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display Columns Description" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__display_name +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__display_name +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__display_name +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__display_name +msgid "Display Name" +msgstr "Naziv " + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts +msgid "Display details by account" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display the date range details in the column headers." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider_inherit +msgid "Divider Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__domain +msgid "Domain" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp_inherit +msgid "Dp Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_prorata_read_group_mixin__date +msgid "" +"Dummy field that adapts searches on date to searches on date_from/date_to." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__duration +msgid "Duration" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Enter expression here, for example balp[70%]. See also help tab." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Examples:" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Export" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__expression_ids +msgid "Expression" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions can be any valid python expressions." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Expressions can involve other KPI, sub KPI and\n" +" query results by name (eg kpi1 + " +"kpi2,\n" +" kpi2.subkpi1, query1.field1)." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__normalize_factor +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider +msgid "Factor" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Factor inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__normalize_factor +msgid "Factor to use to normalize the period (used in comparison" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_names +msgid "Fetched fields name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_ids +msgid "Fields to fetch" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "" +"Filter column on journal entries that have all these analytic tags.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_group_id +msgid "" +"Filter column on journal entries that match this analytic account group. " +"This filter is combined with a AND with the report-level filters and cannot " +"be modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "" +"Filter column on journal entries that match this analytic account.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Filters" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__fix +msgid "Fixed dates" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Font" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size +msgid "Font Size" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size_inherit +msgid "Font Size Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style +msgid "Font Style" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style_inherit +msgid "Font Style Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight +msgid "Font Weight" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight_inherit +msgid "Font Weight Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Forces the start date to Jan 1st of the relevant year" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_from +msgid "From" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_from +msgid "From (computed)" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/report/mis_report_instance_xlsx.py:0 +#, python-format +msgid "Generated on {} at {}" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Help (for KPI expressions)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always +msgid "Hide Always" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always_inherit +msgid "Hide Always Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__hide_analytic_filters +msgid "Hide Analytic Filters" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty +msgid "Hide Empty" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty_inherit +msgid "Hide Empty Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__id +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__id +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__id +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__id +msgid "ID" +msgstr "ID" + +#. module: mis_builder +#: code:addons/mis_builder/models/aep.py:0 +#, python-format +msgid "" +"If currency_id is not provided, all companies must have the same currency." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Indent" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level +msgid "Indent Level" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level_inherit +msgid "Indent Level Inherit" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "Indent level must be greater than or equal to 0" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__italic +msgid "Italic" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__kpi_expression_id +msgid "KPI" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" has type {} while a tuple was expected.\n" +"\n" +"This can be fixed by either:\n" +"\t- Changing the KPI value to a tuple of length {}\n" +"or\n" +"\t- Changing the KPI to `multi` mode and giving an explicit value for each " +"sub-KPI." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" is valued as a tuple of length {} while a tuple of length {} is " +"expected." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq1 +msgid "KPI Sequence" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "KPI name ({}) must be a valid python identifier" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__kpi_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "KPI's" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__all_kpi_ids +msgid "KPIs of this report and subreports." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__kpi_id +msgid "Kpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__name +msgid "Label" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__landscape_pdf +msgid "Landscape PDF" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard____last_update +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport____last_update +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin____last_update +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx____last_update +msgid "Last Modified on" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.last_mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.last_wizard_mis_report_instance_view_menu +msgid "Last Reports Generated" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_date +msgid "Last Updated on" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Layout" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_report_mis_builder_mis_report_instance_xlsx +msgid "MIS Builder XLSX report" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_kpi_data +msgid "MIS Kpi Data Abtract class" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "MIS Report" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subreport +msgid "MIS Report - Sub Reports Relation" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_add_mis_report_instance_dashboard_wizard +msgid "MIS Report Add to Dashboard Wizard" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "MIS Report Instance" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period +msgid "MIS Report Instance Period" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period_sum +msgid "MIS Report Instance Period Sum" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "MIS Report Instances" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "MIS Report KPI" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi_expression +msgid "MIS Report KPI Expression" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_query +msgid "MIS Report Query" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_result_view_form +msgid "MIS Report Result" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_style +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "MIS Report Style" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_style_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_style_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_tree +msgid "MIS Report Styles" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subkpi +msgid "MIS Report Sub-KPI" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report +msgid "MIS Report Template" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_view_menu +msgid "MIS Report Templates" +msgstr "" + +#. module: mis_builder +#: model:ir.ui.menu,name:mis_builder.mis_report_conf_menu +#: model:ir.ui.menu,name:mis_builder.mis_report_finance_menu +msgid "MIS Reporting" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_instance_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_tree +msgid "MIS Reports" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.qweb_pdf_export +msgid "MIS report instance QWEB PDF report" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.xls_export +msgid "MIS report instance XLS report" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__max +#, python-format +msgid "Max" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__min +#, python-format +msgid "Min" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__mode +msgid "Mode" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__model_id +msgid "Model" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__m +#, python-format +msgid "Month" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__move_lines_source +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "Move lines source" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_name +msgid "Move lines source model name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__multi +msgid "Multi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__multi_company +msgid "Multiple companies" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__name +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Name" +msgstr "Naziv" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__none +msgid "No date filter" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "No date filter is allowed for this source in column %s." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__none +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__none +#, python-format +msgid "None" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__normal +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__nornal +msgid "Normal" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Number" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__duration +msgid "Number of periods" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__num +#, python-format +msgid "Numeric" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__offset +msgid "Offset" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__offset +msgid "Offset from current period" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_id +msgid "Parent column" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__pct +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__pct +#, python-format +msgid "Percentage" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_name_unique +msgid "Period name should be unique by report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__type +msgid "Period type" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__period_ids +msgid "Periods" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__pivot_date +msgid "Pivot date" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Please provide both columns to compare in %s." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix +msgid "Prefix" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix_inherit +msgid "Prefix Inherit" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Preview" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Print" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__query_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Queries" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__query_company_ids +msgid "Query Company" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Query name ({}) must be valid python identifier" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Refresh" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__relative +msgid "Relative to report base date" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__report_id +msgid "Report" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_ir_actions_report +msgid "Report Action" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_instance_id +msgid "Report Instance" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__date +msgid "Report base date (leave empty to use current date)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp +msgid "Rounding" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Rounding inherit" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Save" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__company_ids +msgid "Select companies for which data will be searched." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__currency_id +msgid "" +"Select target currency for the report. Required if companies have different " +"currencies." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__sequence +msgid "Sequence" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Settings" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_subreport_unique +msgid "" +"Should not include the same report more than once as sub report of a given " +"report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__sign +msgid "Sign" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Source" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__str +#, python-format +msgid "String" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__style_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_id +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Style" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_expression +msgid "Style expression" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts_style_id +msgid "Style for account detail rows" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__name +msgid "Style name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subkpi_ids +msgid "Sub KPI" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__subkpi_ids +msgid "Sub KPI Filter" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_kpi_expression_subkpi_kpi_unique +msgid "Sub KPI must be used once and only once for each KPI" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Sub KPI's" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Sub Reports" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subreport_ids +msgid "Sub reports" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq2 +msgid "Sub-KPI Sequence" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Sub-KPI name ({}) must be a valid python identifier" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__subkpi_id +msgid "Subkpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__subreport_id +msgid "Subreport" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, python-format +msgid "Subreport loop detected" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, python-format +msgid "Subreport name ({}) must be a valid python identifier" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_name_unique +msgid "Subreport name should be unique by report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix +msgid "Suffix" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix_inherit +msgid "Suffix Inherit" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__sum +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__sum +#, python-format +msgid "Sum" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_accdet +msgid "Sum account details" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "" +"Sum cannot be computed in column {} because the columns to sum have no " +"common subkpis" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__sumcol +msgid "Sum columns" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__target_move +msgid "Target Moves" +msgstr "Ciljane stavke" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "Template" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__temporary +msgid "Temporary" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color +msgid "Text color" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__color +msgid "Text color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" account selector\n" +" is a like expression on the " +"account code (eg\n" +" 70%, etc)." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" journal items domain\n" +" is an Odoo domain filter on " +"journal items." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The following special elements are recognized in\n" +" the expressions to compute " +"accounting data:\n" +" \n" +" {bal|crd|deb|pbal|nbal}{pieu}" +"[account\n" +" selector][journal items domain]\n" +" \n" +" ." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_to +msgid "To" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_to +msgid "To (computed)" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_kpi_data.py:0 +#, python-format +msgid "Unexpected accumulation method %s for %s." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/prorata_read_group_mixin.py:0 +#, python-format +msgid "Unsupported operator %s for searching on date" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.server,name:mis_builder.ir_cron_vacuum_temp_reports_ir_actions_server +#: model:ir.cron,cron_name:mis_builder.ir_cron_vacuum_temp_reports +#: model:ir.cron,name:mis_builder.ir_cron_vacuum_temp_reports +msgid "Vacuum temporary reports" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__valid +msgid "Valid" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__type +msgid "Value type" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Visibility" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__w +#, python-format +msgid "Week" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_duration +msgid "Wrong duration, it must be positive!" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_normalize_factor +msgid "Wrong normalize factor, it must be positive!" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__y +#, python-format +msgid "Year" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Year to date" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "You cannot sum period %s with itself." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "from %s to %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__large +msgid "large" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__medium +msgid "medium" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "or" +msgstr "ili" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "pp" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__small +msgid "small" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_from_id +msgid "versus" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-large +msgid "x-large" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-small +msgid "x-small" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-large +msgid "xx-large" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-small +msgid "xx-small" +msgstr "" + +#~ msgid "" +#~ "AccountingNone: a null value that behaves as 0 in arithmetic " +#~ "operations." +#~ msgstr "" +#~ "RačunovodstvenaNula: null vrijednost koja se ponaša kao 0 u " +#~ "aritmetičkim operacijama." + +#~ msgid "" +#~ "bal, crd, deb, pbal, nbal: balance, debit, credit, positive " +#~ "balance, negative balance." +#~ msgstr "" +#~ "bal, crd, deb, pbal, nbal: saldo, duguje, potražuje, pozitivan " +#~ "saldo, negativan saldo." + +#~ msgid "" +#~ "bal[70]: variation of the balance of account 70 over the period " +#~ "(it is the same as balp[70]." +#~ msgstr "" +#~ "bal[70]: varijanta salda konta 70 u periodu (isto kao balp[70]." + +#~ msgid "" +#~ "bale[1%]: balance of accounts starting with 1 at end of period." +#~ msgstr "bale[1%]: saldo konta koja počinju sa 1 na kraju perioda." + +#~ msgid "bali[70,60]: initial balance of accounts 70 and 60." +#~ msgstr "bali[70,60]: početni saldo konta 70 i 60." + +#~ msgid "" +#~ "balp[('user_type_id', '=', ref('account.data_account_type_receivable')." +#~ "id)][]: variation of the balance of all receivable accounts over the " +#~ "period." +#~ msgstr "" +#~ "balp[('user_type_id', '=', ref('account.data_account_type_receivable')." +#~ "id)][]: varijacija slada svih potražnih konta kroz period.." + +#~ msgid "" +#~ "balp[][('tax_line_id.tag_ids', '=', ref('l10n_be.tax_tag_56').id)]: balance of move lines related to tax grid 56." +#~ msgstr "" +#~ "balp[][('tax_line_id.tag_ids', '=', ref('l10n_be.tax_tag_56').id)]: saldo svih temeljnica povezanih sa poreznom skupinom 56." + +#~ msgid "" +#~ "balu[]: (u for unallocated) is a special expression that shows the " +#~ "unallocated profit/loss of previous\n" +#~ " fiscal years." +#~ msgstr "" +#~ "balu[]: (u za neraspoređene) je specijalni izraz koji prikazuje " +#~ "nerspoređeni prihod/rashod prehodne fiskalne godine." + +#~ msgid "" +#~ "crdp[40%]: sum of all credits on accounts starting with 40 during " +#~ "the period." +#~ msgstr "" +#~ "crdp[40%]: suma svih potražnih konta koja počinju sa 40 kroz " +#~ "zadani period.." + +#~ msgid "date_from, date_to: beginning and end date of the period." +#~ msgstr "date_from, date_to: početni i završni datumi perioda." + +#~ msgid "datetime, datetime, dateutil: the python modules." +#~ msgstr "datetime, datetime, dateutil: python moduli." + +#~ msgid "" +#~ "debp[55%][('journal_id.code', '=', 'BNK1')]: sum of all debits on " +#~ "accounts 55 and journal BNK1 during the period." +#~ msgstr "" +#~ "debp[55%][('journal_id.code', '=', 'BNK1')]: suma svih dugovnih " +#~ "iznosa konta 55 knjiženih u dnevniku BNK1 kroz period.." + +#~ msgid "" +#~ "p, i, e: respectively variation over the period, initial balance, " +#~ "ending balance" +#~ msgstr "" +#~ "p, i, e: varijacija kroz period, i - početno stanje, e - završno " +#~ "stanje" + +#~ msgid "" +#~ "pbale[55%]: sum of all ending balances of accounts starting with " +#~ "55 whose\n" +#~ " ending balance is positive." +#~ msgstr "" +#~ "pbale[55%]: suma svih završnih salda konta koja počinju sa 55 " +#~ "čiji\n" +#~ " završni saldo je pozitivan." + +#~ msgid "" +#~ "sum, min, max, len, avg: behave as expected, very similar to the " +#~ "python builtins." +#~ msgstr "" +#~ "sum, min, max, len, avg: očenikano ponašanje operatora, vrlo " +#~ "slično kao i u pythonu." + +#~ msgid "" +#~ "Additionally following variables are available in the evaluation context:" +#~ msgstr "Dodatno sljedeće varijable su dostupne u kontekstu:" diff --git a/odex25_accounting/mis_builder/i18n/it.po b/odex25_accounting/mis_builder/i18n/it.po new file mode 100644 index 000000000..93ce621cd --- /dev/null +++ b/odex25_accounting/mis_builder/i18n/it.po @@ -0,0 +1,1776 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mis_builder +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "%s (copy)" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[('user_type_id', '=',\n" +" ref('account.\n" +" data_account_type_receivable')." +"id)][]\n" +" \n" +" : variation of the balance of " +"all receivable\n" +" accounts over the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[][('tax_line_id." +"tag_ids', '=',\n" +" ref('l10n_be.tax_tag_56')." +"id)]\n" +" \n" +" : balance of move lines related " +"to tax grid\n" +" 56." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" debp[55%][('journal_id." +"code', '=',\n" +" 'BNK1')]\n" +" \n" +" : sum of all debits on accounts " +"55 and\n" +" journal BNK1 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"AccountingNone\n" +" : a null value that behaves as 0 " +"in\n" +" arithmetic operations." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal, crd, deb, pbal, nbal\n" +" : balance, debit, credit, " +"positive balance,\n" +" negative balance." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal[70]\n" +" : variation of the balance of " +"account 70\n" +" over the period (it is the same " +"as balp[70]." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bale[1%]\n" +" : balance of accounts starting " +"with 1 at end\n" +" of period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bali[70,60]\n" +" : initial balance of accounts 70 " +"and 60." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"balu[]\n" +" : (u for unallocated) is a " +"special\n" +" expression that shows the " +"unallocated\n" +" profit/loss of previous\n" +" fiscal years." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"crdp[40%]\n" +" : sum of all credits on accounts " +"starting\n" +" with 40 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"date_from, date_to\n" +" : beginning and end date of the " +"period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"datetime, datetime, dateutil\n" +" : the python modules." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"p, i, e\n" +" : respectively variation over " +"the period,\n" +" initial balance, ending balance" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"pbale[55%]\n" +" : sum of all ending balances of " +"accounts\n" +" starting with 55 whose\n" +" ending balance is positive." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"sum, min, max, len, avg\n" +" : behave as expected, very " +"similar to the\n" +" python builtins." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__move_lines_source +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields. This model is the data source for column Actuals." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "A date filter is mandatory for this source in column %s." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__account_model +msgid "Account model" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__accumulation_method +msgid "Accumulation Method" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "" +"Actual (alternative) models used in columns must have the same account model " +"in the Account field and must be the same defined in the report template: %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals +msgid "Actuals" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals_alt +msgid "Actuals (alternative)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source +msgid "" +"Actuals: current data, from accounting and other queries.\n" +"Actuals (alternative): current data from an alternative source (eg a " +"database view providing look-alike account move lines).\n" +"Sum columns: summation (+/-) of other columns.\n" +"Compare to column: compare to other column.\n" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_prorata_read_group_mixin +msgid "Adapt model with date_from/date_to for pro-rata temporis read_group" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_add_to_dashboard_action +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Add to dashboard" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Additionally following variables are available\n" +" in the evaluation context:" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__aggregate +msgid "Aggregate" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__all +msgid "All Entries" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__all_kpi_ids +msgid "All Kpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__posted +msgid "All Posted Entries" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__allowed_cmpcol_ids +msgid "Allowed Cmpcol" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__amount +msgid "Amount" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__style_expression +msgid "" +"An expression that returns a style depending on the KPI value. Such style is " +"applied on top of the row style." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_account_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "Analytic Account" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Account Filter" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_group_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_group_id +#, python-format +msgid "Analytic Account Group" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account Group: %s" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account: %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_tag_ids +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "Analytic Tags" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Tags Filter" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Tags: %s" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Auto expand" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__avg +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__avg +#, python-format +msgid "Average" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color +msgid "Background Color" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color_inherit +msgid "Background Color Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__background_color +msgid "Background color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date +msgid "Base date" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__bold +msgid "Bold" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Can not update a multi kpi from the kpi line" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Cancel" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__multi_company +msgid "" +"Check if you wish to specify children companies to be searched for data." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Color" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color_inherit +msgid "Color Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_to_sum_id +msgid "Column" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Column %s cannot be compared to itrec." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Column %s with move lines source must have from/to dates." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Columns" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Columns to compare must belong to the same report in %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_ids +msgid "Columns to sum" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "Columns {} and {} are not comparable" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_ids +msgid "Companies" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__query_company_ids +msgid "Companies for which data will be searched." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_id +msgid "Company" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_to_id +msgid "Compare" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__cmpcol +msgid "Compare columns" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__compare_method +msgid "Comparison Method" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__comparison_mode +msgid "Comparison Mode" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_uid +msgid "Created by" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_date +msgid "Created on" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__currency_id +msgid "Currency" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__dashboard_id +msgid "Dashboard" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date +msgid "Date" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__date_field +msgid "Date Field" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_from +msgid "Date From" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_range_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_id +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__date_range +#, python-format +msgid "Date Range" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_type_id +msgid "Date Range Type" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_to +msgid "Date To" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Dates" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__d +#, python-format +msgid "Day" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__description +msgid "Description" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__accumulation_method +msgid "" +"Determines how values of this kpi spanning over a time period are " +"transformed to match the reporting period. Sum: values of shorter period are " +"added, values of longest or partially overlapping periods are adjusted pro-" +"rata temporis.\n" +"Average: values of included period are averaged with a pro-rata temporis " +"weight." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__diff +#, python-format +msgid "Difference" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__no_auto_expand_accounts +msgid "Disable account details expansion" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display Columns Description" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__display_name +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__display_name +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__display_name +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__display_name +msgid "Display Name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts +msgid "Display details by account" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display the date range details in the column headers." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider_inherit +msgid "Divider Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__domain +msgid "Domain" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp_inherit +msgid "Dp Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_prorata_read_group_mixin__date +msgid "" +"Dummy field that adapts searches on date to searches on date_from/date_to." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__duration +msgid "Duration" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Enter expression here, for example balp[70%]. See also help tab." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Examples:" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Export" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__expression_ids +msgid "Expression" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions can be any valid python expressions." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Expressions can involve other KPI, sub KPI and\n" +" query results by name (eg kpi1 + " +"kpi2,\n" +" kpi2.subkpi1, query1.field1)." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__normalize_factor +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider +msgid "Factor" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Factor inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__normalize_factor +msgid "Factor to use to normalize the period (used in comparison" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_names +msgid "Fetched fields name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_ids +msgid "Fields to fetch" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "" +"Filter column on journal entries that have all these analytic tags.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_group_id +msgid "" +"Filter column on journal entries that match this analytic account group. " +"This filter is combined with a AND with the report-level filters and cannot " +"be modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "" +"Filter column on journal entries that match this analytic account.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Filters" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__fix +msgid "Fixed dates" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Font" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size +msgid "Font Size" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size_inherit +msgid "Font Size Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style +msgid "Font Style" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style_inherit +msgid "Font Style Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight +msgid "Font Weight" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight_inherit +msgid "Font Weight Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Forces the start date to Jan 1st of the relevant year" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_from +msgid "From" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_from +msgid "From (computed)" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/report/mis_report_instance_xlsx.py:0 +#, python-format +msgid "Generated on {} at {}" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Help (for KPI expressions)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always +msgid "Hide Always" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always_inherit +msgid "Hide Always Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__hide_analytic_filters +msgid "Hide Analytic Filters" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty +msgid "Hide Empty" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty_inherit +msgid "Hide Empty Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__id +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__id +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__id +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__id +msgid "ID" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/aep.py:0 +#, python-format +msgid "" +"If currency_id is not provided, all companies must have the same currency." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Indent" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level +msgid "Indent Level" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level_inherit +msgid "Indent Level Inherit" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "Indent level must be greater than or equal to 0" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__italic +msgid "Italic" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__kpi_expression_id +msgid "KPI" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" has type {} while a tuple was expected.\n" +"\n" +"This can be fixed by either:\n" +"\t- Changing the KPI value to a tuple of length {}\n" +"or\n" +"\t- Changing the KPI to `multi` mode and giving an explicit value for each " +"sub-KPI." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" is valued as a tuple of length {} while a tuple of length {} is " +"expected." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq1 +msgid "KPI Sequence" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "KPI name ({}) must be a valid python identifier" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__kpi_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "KPI's" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__all_kpi_ids +msgid "KPIs of this report and subreports." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__kpi_id +msgid "Kpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__name +msgid "Label" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__landscape_pdf +msgid "Landscape PDF" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard____last_update +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport____last_update +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin____last_update +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx____last_update +msgid "Last Modified on" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.last_mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.last_wizard_mis_report_instance_view_menu +msgid "Last Reports Generated" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_date +msgid "Last Updated on" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Layout" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_report_mis_builder_mis_report_instance_xlsx +msgid "MIS Builder XLSX report" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_kpi_data +msgid "MIS Kpi Data Abtract class" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "MIS Report" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subreport +msgid "MIS Report - Sub Reports Relation" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_add_mis_report_instance_dashboard_wizard +msgid "MIS Report Add to Dashboard Wizard" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "MIS Report Instance" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period +msgid "MIS Report Instance Period" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period_sum +msgid "MIS Report Instance Period Sum" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "MIS Report Instances" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "MIS Report KPI" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi_expression +msgid "MIS Report KPI Expression" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_query +msgid "MIS Report Query" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_result_view_form +msgid "MIS Report Result" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_style +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "MIS Report Style" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_style_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_style_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_tree +msgid "MIS Report Styles" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subkpi +msgid "MIS Report Sub-KPI" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report +msgid "MIS Report Template" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_view_menu +msgid "MIS Report Templates" +msgstr "" + +#. module: mis_builder +#: model:ir.ui.menu,name:mis_builder.mis_report_conf_menu +#: model:ir.ui.menu,name:mis_builder.mis_report_finance_menu +msgid "MIS Reporting" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_instance_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_tree +msgid "MIS Reports" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.qweb_pdf_export +msgid "MIS report instance QWEB PDF report" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.xls_export +msgid "MIS report instance XLS report" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__max +#, python-format +msgid "Max" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__min +#, python-format +msgid "Min" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__mode +msgid "Mode" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__model_id +msgid "Model" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__m +#, python-format +msgid "Month" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__move_lines_source +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "Move lines source" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_name +msgid "Move lines source model name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__multi +msgid "Multi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__multi_company +msgid "Multiple companies" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__name +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__none +msgid "No date filter" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "No date filter is allowed for this source in column %s." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__none +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__none +#, python-format +msgid "None" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__normal +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__nornal +msgid "Normal" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Number" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__duration +msgid "Number of periods" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__num +#, python-format +msgid "Numeric" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__offset +msgid "Offset" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__offset +msgid "Offset from current period" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_id +msgid "Parent column" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__pct +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__pct +#, python-format +msgid "Percentage" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_name_unique +msgid "Period name should be unique by report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__type +msgid "Period type" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__period_ids +msgid "Periods" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__pivot_date +msgid "Pivot date" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Please provide both columns to compare in %s." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix +msgid "Prefix" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix_inherit +msgid "Prefix Inherit" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Preview" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Print" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__query_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Queries" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__query_company_ids +msgid "Query Company" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Query name ({}) must be valid python identifier" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Refresh" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__relative +msgid "Relative to report base date" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__report_id +msgid "Report" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_ir_actions_report +msgid "Report Action" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_instance_id +msgid "Report Instance" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__date +msgid "Report base date (leave empty to use current date)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp +msgid "Rounding" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Rounding inherit" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Save" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__company_ids +msgid "Select companies for which data will be searched." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__currency_id +msgid "" +"Select target currency for the report. Required if companies have different " +"currencies." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__sequence +msgid "Sequence" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Settings" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_subreport_unique +msgid "" +"Should not include the same report more than once as sub report of a given " +"report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__sign +msgid "Sign" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Source" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__str +#, python-format +msgid "String" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__style_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_id +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Style" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_expression +msgid "Style expression" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts_style_id +msgid "Style for account detail rows" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__name +msgid "Style name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subkpi_ids +msgid "Sub KPI" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__subkpi_ids +msgid "Sub KPI Filter" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_kpi_expression_subkpi_kpi_unique +msgid "Sub KPI must be used once and only once for each KPI" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Sub KPI's" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Sub Reports" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subreport_ids +msgid "Sub reports" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq2 +msgid "Sub-KPI Sequence" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Sub-KPI name ({}) must be a valid python identifier" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__subkpi_id +msgid "Subkpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__subreport_id +msgid "Subreport" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, python-format +msgid "Subreport loop detected" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, python-format +msgid "Subreport name ({}) must be a valid python identifier" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_name_unique +msgid "Subreport name should be unique by report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix +msgid "Suffix" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix_inherit +msgid "Suffix Inherit" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__sum +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__sum +#, python-format +msgid "Sum" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_accdet +msgid "Sum account details" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "" +"Sum cannot be computed in column {} because the columns to sum have no " +"common subkpis" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__sumcol +msgid "Sum columns" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__target_move +msgid "Target Moves" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "Template" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__temporary +msgid "Temporary" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color +msgid "Text color" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__color +msgid "Text color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" account selector\n" +" is a like expression on the " +"account code (eg\n" +" 70%, etc)." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" journal items domain\n" +" is an Odoo domain filter on " +"journal items." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The following special elements are recognized in\n" +" the expressions to compute " +"accounting data:\n" +" \n" +" {bal|crd|deb|pbal|nbal}{pieu}" +"[account\n" +" selector][journal items domain]\n" +" \n" +" ." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_to +msgid "To" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_to +msgid "To (computed)" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_kpi_data.py:0 +#, python-format +msgid "Unexpected accumulation method %s for %s." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/prorata_read_group_mixin.py:0 +#, python-format +msgid "Unsupported operator %s for searching on date" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.server,name:mis_builder.ir_cron_vacuum_temp_reports_ir_actions_server +#: model:ir.cron,cron_name:mis_builder.ir_cron_vacuum_temp_reports +#: model:ir.cron,name:mis_builder.ir_cron_vacuum_temp_reports +msgid "Vacuum temporary reports" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__valid +msgid "Valid" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__type +msgid "Value type" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Visibility" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__w +#, python-format +msgid "Week" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_duration +msgid "Wrong duration, it must be positive!" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_normalize_factor +msgid "Wrong normalize factor, it must be positive!" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__y +#, python-format +msgid "Year" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Year to date" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "You cannot sum period %s with itself." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "from %s to %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__large +msgid "large" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__medium +msgid "medium" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "or" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "pp" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__small +msgid "small" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_from_id +msgid "versus" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-large +msgid "x-large" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-small +msgid "x-small" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-large +msgid "xx-large" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-small +msgid "xx-small" +msgstr "" diff --git a/odex25_accounting/mis_builder/i18n/nl.po b/odex25_accounting/mis_builder/i18n/nl.po new file mode 100644 index 000000000..6e743bf28 --- /dev/null +++ b/odex25_accounting/mis_builder/i18n/nl.po @@ -0,0 +1,2009 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mis_builder +# +# Translators: +# Frank Schellenberg , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-13 15:37+0000\n" +"PO-Revision-Date: 2018-01-13 15:37+0000\n" +"Last-Translator: Frank Schellenberg , 2018\n" +"Language-Team: Dutch (https://www.transifex.com/oca/teams/23907/nl/)\n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "%s (copy)" +msgstr "%s (kopie)" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[('user_type_id', '=',\n" +" ref('account.\n" +" data_account_type_receivable')." +"id)][]\n" +" \n" +" : variation of the balance of " +"all receivable\n" +" accounts over the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[][('tax_line_id." +"tag_ids', '=',\n" +" ref('l10n_be.tax_tag_56')." +"id)]\n" +" \n" +" : balance of move lines related " +"to tax grid\n" +" 56." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" debp[55%][('journal_id." +"code', '=',\n" +" 'BNK1')]\n" +" \n" +" : sum of all debits on accounts " +"55 and\n" +" journal BNK1 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"AccountingNone\n" +" : a null value that behaves as 0 " +"in\n" +" arithmetic operations." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal, crd, deb, pbal, nbal\n" +" : balance, debit, credit, " +"positive balance,\n" +" negative balance." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal[70]\n" +" : variation of the balance of " +"account 70\n" +" over the period (it is the same " +"as balp[70]." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bale[1%]\n" +" : balance of accounts starting " +"with 1 at end\n" +" of period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bali[70,60]\n" +" : initial balance of accounts 70 " +"and 60." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"balu[]\n" +" : (u for unallocated) is a " +"special\n" +" expression that shows the " +"unallocated\n" +" profit/loss of previous\n" +" fiscal years." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"crdp[40%]\n" +" : sum of all credits on accounts " +"starting\n" +" with 40 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"date_from, date_to\n" +" : beginning and end date of the " +"period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"datetime, datetime, dateutil\n" +" : the python modules." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"p, i, e\n" +" : respectively variation over " +"the period,\n" +" initial balance, ending balance" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"pbale[55%]\n" +" : sum of all ending balances of " +"accounts\n" +" starting with 55 whose\n" +" ending balance is positive." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"sum, min, max, len, avg\n" +" : behave as expected, very " +"similar to the\n" +" python builtins." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields." +msgstr "" +"Een 'boekingsregel-achtig' model, d.w.z. heeft minimaal debet, credit, " +"datum, account_id en company_id velden" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__move_lines_source +#, fuzzy +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields. This model is the data source for column Actuals." +msgstr "" +"Een 'boekingsregel-achtig' model, d.w.z. heeft minimaal debet, credit, " +"datum, account_id en company_id velden" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "A date filter is mandatory for this source in column %s." +msgstr "Een datum filter is verplicht voor deze bron in kolom %s." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__account_model +#, fuzzy +msgid "Account model" +msgstr "Rekening details optellen" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__accumulation_method +msgid "Accumulation Method" +msgstr "Accumulatiemethode" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "" +"Actual (alternative) models used in columns must have the same account model " +"in the Account field and must be the same defined in the report template: %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals +msgid "Actuals" +msgstr "Actuele" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals_alt +msgid "Actuals (alternative)" +msgstr "Actuele (alternatief)" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source +msgid "" +"Actuals: current data, from accounting and other queries.\n" +"Actuals (alternative): current data from an alternative source (eg a " +"database view providing look-alike account move lines).\n" +"Sum columns: summation (+/-) of other columns.\n" +"Compare to column: compare to other column.\n" +msgstr "" +"Actuele: Huidige data, van boekhouding en andere queries.\n" +"Actuele (alternatief): Huidige data van een alternatieve bron (eg een " +"database view welke ook boekingsregels kan laten zien).\n" +"Kolommen optellen: sommatie (+/-) van andere kolommen.\n" +"Vergelijk kolommen: vergelijk met andere kolom.\n" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_prorata_read_group_mixin +msgid "Adapt model with date_from/date_to for pro-rata temporis read_group" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_add_to_dashboard_action +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Add to dashboard" +msgstr "Voeg toe aan dashboard" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Additionally following variables are available\n" +" in the evaluation context:" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__aggregate +msgid "Aggregate" +msgstr "Samenvoegen" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__all +msgid "All Entries" +msgstr "Alle boekingen" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__all_kpi_ids +msgid "All Kpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__posted +msgid "All Posted Entries" +msgstr "Alle Geboekte Regels" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__allowed_cmpcol_ids +msgid "Allowed Cmpcol" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__amount +msgid "Amount" +msgstr "Hoeveelheid" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__style_expression +msgid "" +"An expression that returns a style depending on the KPI value. Such style is " +"applied on top of the row style." +msgstr "" +"Een uitdrukking die een stijl retourneert afhankelijk van de KPI-waarde. Een " +"dergelijke stijl wordt toegepast bovenop de regelstijl." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_account_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "Analytic Account" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Account Filter" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_group_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_group_id +#, python-format +msgid "Analytic Account Group" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account Group: %s" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account: %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_tag_ids +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "Analytic Tags" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Tags Filter" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Tags: %s" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Auto expand" +msgstr "automatisch uitbreiden" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__avg +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__avg +#, python-format +msgid "Average" +msgstr "Gemiddelde" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color +msgid "Background Color" +msgstr "Achtergrond Kleur" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color_inherit +msgid "Background Color Inherit" +msgstr "Achtergrond Kleur Overerven" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__background_color +msgid "Background color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "Achtergrondkleur als geldige HEX code (van #000000 tot #FFFFFF)" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date +msgid "Base date" +msgstr "Uitgangsdatum" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__bold +msgid "Bold" +msgstr "Vet" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Can not update a multi kpi from the kpi line" +msgstr "Kan een multi-kpi niet bijwerken vanaf de kpi-regel" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Cancel" +msgstr "Annuleer" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__multi_company +msgid "" +"Check if you wish to specify children companies to be searched for data." +msgstr "" +"Controleer of u dochterbedrijven wilt selecteren waarvan de data moet worden " +"meegenomen." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Color" +msgstr "Kleur" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color_inherit +msgid "Color Inherit" +msgstr "Kleur Overerven" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_to_sum_id +msgid "Column" +msgstr "Kolom" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, fuzzy, python-format +msgid "Column %s cannot be compared to itrec." +msgstr "Kolom %skan niet met zichzelf worden vergeleken." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, fuzzy, python-format +msgid "Column %s with move lines source must have from/to dates." +msgstr "Kolom %s met Actuele waardes moet van/tot data hebben." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Columns" +msgstr "Kolommen" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Columns to compare must belong to the same report in %s" +msgstr "Te vergelijken kolommen moeten tot hetzelfde rapport in %s behoren" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_ids +msgid "Columns to sum" +msgstr "Op te sommen kolommen" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "Columns {} and {} are not comparable" +msgstr "Kolommen {} en {} zijn niet vergelijkbaar" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_ids +msgid "Companies" +msgstr "Bedrijven" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__query_company_ids +msgid "Companies for which data will be searched." +msgstr "Bedrijven waarvoor de data wordt doorzocht." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_id +msgid "Company" +msgstr "Bedrijf" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_to_id +msgid "Compare" +msgstr "Vergelijk" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__cmpcol +msgid "Compare columns" +msgstr "Vergelijk kolommen" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__compare_method +msgid "Comparison Method" +msgstr "Vergelijkingsmethode" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__comparison_mode +msgid "Comparison Mode" +msgstr "Vergelijkingsmodus" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_uid +msgid "Created by" +msgstr "Aangemaakt door" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_date +msgid "Created on" +msgstr "Aangemaakt op" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__currency_id +msgid "Currency" +msgstr "Valuta" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__dashboard_id +msgid "Dashboard" +msgstr "Dashboard" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date +#, fuzzy +msgid "Date" +msgstr "Data" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__date_field +msgid "Date Field" +msgstr "Datumveld" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_from +#, fuzzy +msgid "Date From" +msgstr "Datumveld" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_range_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_id +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__date_range +#, python-format +msgid "Date Range" +msgstr "Datumbereik" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_type_id +msgid "Date Range Type" +msgstr "Datumbereik Type" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_to +#, fuzzy +msgid "Date To" +msgstr "Data" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Dates" +msgstr "Data" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__d +#, python-format +msgid "Day" +msgstr "Dag" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__description +msgid "Description" +msgstr "Omschrijving" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__accumulation_method +msgid "" +"Determines how values of this kpi spanning over a time period are " +"transformed to match the reporting period. Sum: values of shorter period are " +"added, values of longest or partially overlapping periods are adjusted pro-" +"rata temporis.\n" +"Average: values of included period are averaged with a pro-rata temporis " +"weight." +msgstr "" +"Bepaalt hoe waarden van deze kpi over een periode worden omgezet in " +"overeenstemming met de rapportageperiode. \n" +"Som: waarden van kortere periode worden toegevoegd, waarden van langste of " +"gedeeltelijk overlappende perioden worden pro-rata temporis aangepast.\n" +"Gemiddelde: waarden van de opgenomen periode worden gemiddeld met een pro-" +"rata temporis-gewicht." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__diff +#, python-format +msgid "Difference" +msgstr "Verschil" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__no_auto_expand_accounts +#, fuzzy +msgid "Disable account details expansion" +msgstr "Rekening details optellen" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display Columns Description" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__display_name +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__display_name +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__display_name +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__display_name +msgid "Display Name" +msgstr "Weergavenaam" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts +msgid "Display details by account" +msgstr "Laat details per rekening zien" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display the date range details in the column headers." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider_inherit +msgid "Divider Inherit" +msgstr "Verdeler Overerven" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__domain +msgid "Domain" +msgstr "Domein" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp_inherit +msgid "Dp Inherit" +msgstr "Dp Overerven" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_prorata_read_group_mixin__date +msgid "" +"Dummy field that adapts searches on date to searches on date_from/date_to." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__duration +msgid "Duration" +msgstr "Duur" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Enter expression here, for example balp[70%]. See also help tab." +msgstr "" +"Vul hier een uitdrukking in, bijvoorbeeld balp[70%]. Zie ook het help " +"tabblad." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Examples:" +msgstr "Voorbeelden:" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Export" +msgstr "Exporteer" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__expression_ids +msgid "Expression" +msgstr "Uitdrukking" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions" +msgstr "Uitdrukkingen" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions can be any valid python expressions." +msgstr "Uitdrukkingen kunnen alle geldige python uitdrukkingen zijn." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Expressions can involve other KPI, sub KPI and\n" +" query results by name (eg kpi1 + " +"kpi2,\n" +" kpi2.subkpi1, query1.field1)." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__normalize_factor +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider +msgid "Factor" +msgstr "Factor" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Factor inherit" +msgstr "Factor overerven" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__normalize_factor +msgid "Factor to use to normalize the period (used in comparison" +msgstr "" +"Te gebruiken factor om de periode te normaliseren (wordt gebruikt bij " +"vergelijking" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_names +msgid "Fetched fields name" +msgstr "Opgehaalde veld namen" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_ids +msgid "Fields to fetch" +msgstr "Op te halen velden" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "" +"Filter column on journal entries that have all these analytic tags.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_group_id +msgid "" +"Filter column on journal entries that match this analytic account group. " +"This filter is combined with a AND with the report-level filters and cannot " +"be modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "" +"Filter column on journal entries that match this analytic account.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Filters" +msgstr "Filters" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__fix +msgid "Fixed dates" +msgstr "Vaste data" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Font" +msgstr "Lettertype" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size +msgid "Font Size" +msgstr "Lettertypegrootte" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size_inherit +msgid "Font Size Inherit" +msgstr "Lettertypegrootte Overerven" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style +msgid "Font Style" +msgstr "Letterstijl" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style_inherit +msgid "Font Style Inherit" +msgstr "Letterstijl Overerven" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight +msgid "Font Weight" +msgstr "Lettertype Dikte" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight_inherit +msgid "Font Weight Inherit" +msgstr "Lettertype Dikte Overerven" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Forces the start date to Jan 1st of the relevant year" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_from +msgid "From" +msgstr "Van" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_from +msgid "From (computed)" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/report/mis_report_instance_xlsx.py:0 +#, python-format +msgid "Generated on {} at {}" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Help (for KPI expressions)" +msgstr "Help (voor KPI uitdrukkingen)" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always +msgid "Hide Always" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always_inherit +#, fuzzy +msgid "Hide Always Inherit" +msgstr "Verberg Leeg Overerven" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__hide_analytic_filters +msgid "Hide Analytic Filters" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty +msgid "Hide Empty" +msgstr "Verberg Leeg" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty_inherit +msgid "Hide Empty Inherit" +msgstr "Verberg Leeg Overerven" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__id +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__id +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__id +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__id +msgid "ID" +msgstr "ID" + +#. module: mis_builder +#: code:addons/mis_builder/models/aep.py:0 +#, python-format +msgid "" +"If currency_id is not provided, all companies must have the same currency." +msgstr "" +"Als currency_id niet bekend is, alle bedrijven moeten dezelfde valuta hebben." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Indent" +msgstr "Inspringen" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level +msgid "Indent Level" +msgstr "Inspring Niveau" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level_inherit +msgid "Indent Level Inherit" +msgstr "Inspring Niveau Overerven" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "Indent level must be greater than or equal to 0" +msgstr "Inspring niveau moet groter of gelijk zijn aan 0" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__italic +msgid "Italic" +msgstr "Cursief" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__kpi_expression_id +msgid "KPI" +msgstr "KPI" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" has type {} while a tuple was expected.\n" +"\n" +"This can be fixed by either:\n" +"\t- Changing the KPI value to a tuple of length {}\n" +"or\n" +"\t- Changing the KPI to `multi` mode and giving an explicit value for each " +"sub-KPI." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" is valued as a tuple of length {} while a tuple of length {} is " +"expected." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq1 +#, fuzzy +msgid "KPI Sequence" +msgstr "Reeks" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, fuzzy, python-format +msgid "KPI name ({}) must be a valid python identifier" +msgstr "De naam moet een geldige python identifier zijn" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__kpi_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "KPI's" +msgstr "KPI's" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__all_kpi_ids +msgid "KPIs of this report and subreports." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__kpi_id +msgid "Kpi" +msgstr "Kpi" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__name +msgid "Label" +msgstr "Label" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__landscape_pdf +msgid "Landscape PDF" +msgstr "Landschap PDF" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard____last_update +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport____last_update +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin____last_update +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx____last_update +msgid "Last Modified on" +msgstr "Voor het laatst aangepast op" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.last_mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.last_wizard_mis_report_instance_view_menu +msgid "Last Reports Generated" +msgstr "Laatste Gegenereerde Rapport" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_uid +msgid "Last Updated by" +msgstr "Voor het laatst geüpdatet door" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_date +msgid "Last Updated on" +msgstr "Voor het laatst geüpdatet op" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Layout" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_report_mis_builder_mis_report_instance_xlsx +#, fuzzy +msgid "MIS Builder XLSX report" +msgstr "MIS rapportage instantie XLS rapport" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_kpi_data +msgid "MIS Kpi Data Abtract class" +msgstr "MIS Kpi Data Abtract class" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "MIS Report" +msgstr "MIS Rapport" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subreport +#, fuzzy +msgid "MIS Report - Sub Reports Relation" +msgstr "MIS Rapport Resultaat" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_add_mis_report_instance_dashboard_wizard +#, fuzzy +msgid "MIS Report Add to Dashboard Wizard" +msgstr "Voeg toe aan dashboard" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "MIS Report Instance" +msgstr "MIS Rapport Instantie" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period +#, fuzzy +msgid "MIS Report Instance Period" +msgstr "MIS Rapport Instantie" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period_sum +#, fuzzy +msgid "MIS Report Instance Period Sum" +msgstr "MIS Rapport Instantie" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "MIS Report Instances" +msgstr "MIS Rapport Instanties" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "MIS Report KPI" +msgstr "MIS Rapport KPI" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi_expression +#, fuzzy +msgid "MIS Report KPI Expression" +msgstr "MIS Rapport KPI" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_query +#, fuzzy +msgid "MIS Report Query" +msgstr "MIS Rapport" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_result_view_form +msgid "MIS Report Result" +msgstr "MIS Rapport Resultaat" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_style +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "MIS Report Style" +msgstr "MIS Rapport Stijl" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_style_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_style_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_tree +msgid "MIS Report Styles" +msgstr "MIS Rapport Stijlen" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subkpi +#, fuzzy +msgid "MIS Report Sub-KPI" +msgstr "MIS Rapport KPI" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report +#, fuzzy +msgid "MIS Report Template" +msgstr "MIS Rapport Templates" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_view_menu +msgid "MIS Report Templates" +msgstr "MIS Rapport Templates" + +#. module: mis_builder +#: model:ir.ui.menu,name:mis_builder.mis_report_conf_menu +#: model:ir.ui.menu,name:mis_builder.mis_report_finance_menu +msgid "MIS Reporting" +msgstr "MIS Rapportage" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_instance_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_tree +msgid "MIS Reports" +msgstr "MIS Rapporten" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.qweb_pdf_export +msgid "MIS report instance QWEB PDF report" +msgstr "MIS rapportage instantie QWEB PDF rapport" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.xls_export +msgid "MIS report instance XLS report" +msgstr "MIS rapportage instantie XLS rapport" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__max +#, python-format +msgid "Max" +msgstr "Max" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__min +#, python-format +msgid "Min" +msgstr "Min" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__mode +msgid "Mode" +msgstr "Modus" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__model_id +msgid "Model" +msgstr "Model" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__m +#, python-format +msgid "Month" +msgstr "Maand" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__move_lines_source +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "Move lines source" +msgstr "Bron boekingsregels" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_name +#, fuzzy +msgid "Move lines source model name" +msgstr "Bron boekingsregels" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__multi +msgid "Multi" +msgstr "Meerdere" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__multi_company +msgid "Multiple companies" +msgstr "Meerdere bedrijven" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__name +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Name" +msgstr "Naam" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__none +msgid "No date filter" +msgstr "Geen datum filter" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "No date filter is allowed for this source in column %s." +msgstr "Een datum filter is niet toegestaan voor deze bron in kolom %s." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__none +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__none +#, python-format +msgid "None" +msgstr "Geen" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__normal +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__nornal +msgid "Normal" +msgstr "Normaal" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Number" +msgstr "Aantal" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__duration +msgid "Number of periods" +msgstr "Aantal periodes" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__num +#, python-format +msgid "Numeric" +msgstr "Numeriek" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__offset +msgid "Offset" +msgstr "Offset" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__offset +msgid "Offset from current period" +msgstr "Offset t.o.v. huidige periode" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_id +msgid "Parent column" +msgstr "Bovenliggende kolom" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__pct +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__pct +#, python-format +msgid "Percentage" +msgstr "Percentage" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_name_unique +msgid "Period name should be unique by report" +msgstr "Periode naam dient per rapport uniek te zijn" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__type +msgid "Period type" +msgstr "Periode duur" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__period_ids +msgid "Periods" +msgstr "Periodes" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__pivot_date +msgid "Pivot date" +msgstr "Uitgangsdatum" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Please provide both columns to compare in %s." +msgstr "Geef beide kolommen op om te vergelijken in %s." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix +msgid "Prefix" +msgstr "Voorvoegsel" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix_inherit +msgid "Prefix Inherit" +msgstr "Voorvoegsel Overerven" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Preview" +msgstr "Voorbeeld" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Print" +msgstr "Print" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__query_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Queries" +msgstr "Queries" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__query_company_ids +msgid "Query Company" +msgstr "Query Bedrijf" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, fuzzy, python-format +msgid "Query name ({}) must be valid python identifier" +msgstr "De naam moet een geldige python identifier zijn" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Refresh" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__relative +msgid "Relative to report base date" +msgstr "Ten opzichte van de rapport uitgangsdatum" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__report_id +msgid "Report" +msgstr "Rapport" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_ir_actions_report +#, fuzzy +msgid "Report Action" +msgstr "Rapport instantie" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_instance_id +msgid "Report Instance" +msgstr "Rapport instantie" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__date +msgid "Report base date (leave empty to use current date)" +msgstr "Uitgangsdatum Rapport (voor vandaag laat leeg)" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp +msgid "Rounding" +msgstr "Afronding" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Rounding inherit" +msgstr "Afronding overerven" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Save" +msgstr "Opslaan" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__company_ids +msgid "Select companies for which data will be searched." +msgstr "Selecteer de bedrijven waarvoor de data moet worden doorzocht." + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__currency_id +msgid "" +"Select target currency for the report. Required if companies have different " +"currencies." +msgstr "" +"Selecteer de hoofdvaluta voor het rapport. Vereist als bedrijven " +"verschillende valuta hebben." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__sequence +msgid "Sequence" +msgstr "Reeks" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Settings" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_subreport_unique +msgid "" +"Should not include the same report more than once as sub report of a given " +"report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__sign +msgid "Sign" +msgstr "Teken" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Source" +msgstr "Bron" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__str +#, python-format +msgid "String" +msgstr "String" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__style_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_id +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Style" +msgstr "Stijl" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_expression +msgid "Style expression" +msgstr "Stijl uitdrukking" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts_style_id +msgid "Style for account detail rows" +msgstr "Stijl voor detail rekening regels" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__name +msgid "Style name" +msgstr "Stijl naam" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subkpi_ids +msgid "Sub KPI" +msgstr "Sub KPI" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__subkpi_ids +msgid "Sub KPI Filter" +msgstr "Sub KPI filter" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_kpi_expression_subkpi_kpi_unique +msgid "Sub KPI must be used once and only once for each KPI" +msgstr "Sub KPI moet één keer worden gebruikt voor iedere KPI" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Sub KPI's" +msgstr "Sub KPI's" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +#, fuzzy +msgid "Sub Reports" +msgstr "MIS Rapporten" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subreport_ids +#, fuzzy +msgid "Sub reports" +msgstr "MIS Rapporten" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq2 +#, fuzzy +msgid "Sub-KPI Sequence" +msgstr "Reeks" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, fuzzy, python-format +msgid "Sub-KPI name ({}) must be a valid python identifier" +msgstr "De naam moet een geldige python identifier zijn" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__subkpi_id +msgid "Subkpi" +msgstr "Subkpi" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__subreport_id +#, fuzzy +msgid "Subreport" +msgstr "Rapport" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, python-format +msgid "Subreport loop detected" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, fuzzy, python-format +msgid "Subreport name ({}) must be a valid python identifier" +msgstr "De naam moet een geldige python identifier zijn" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_name_unique +#, fuzzy +msgid "Subreport name should be unique by report" +msgstr "Periode naam dient per rapport uniek te zijn" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix +msgid "Suffix" +msgstr "Achtervoegsel" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix_inherit +msgid "Suffix Inherit" +msgstr "Achtervoegsel Overerven" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__sum +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__sum +#, python-format +msgid "Sum" +msgstr "Optellen" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_accdet +msgid "Sum account details" +msgstr "Rekening details optellen" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "" +"Sum cannot be computed in column {} because the columns to sum have no " +"common subkpis" +msgstr "" +"Som kan niet worden berekend in kolom {} omdat de kolommen die moeten worden " +"opgeteld geen gemeenschappelijke subkpis hebben" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__sumcol +msgid "Sum columns" +msgstr "Kolommen optellen" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__target_move +msgid "Target Moves" +msgstr "Doel Boekingen" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "Template" +msgstr "Template" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__temporary +msgid "Temporary" +msgstr "Tijdelijk" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color +msgid "Text color" +msgstr "Tekst kleur" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__color +msgid "Text color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "Tekst kleur in geldige HEX code (van #000000 tot #FFFFFF)" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" account selector\n" +" is a like expression on the " +"account code (eg\n" +" 70%, etc)." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" journal items domain\n" +" is an Odoo domain filter on " +"journal items." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The following special elements are recognized in\n" +" the expressions to compute " +"accounting data:\n" +" \n" +" {bal|crd|deb|pbal|nbal}{pieu}" +"[account\n" +" selector][journal items domain]\n" +" \n" +" ." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_to +msgid "To" +msgstr "Tot" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_to +msgid "To (computed)" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_kpi_data.py:0 +#, python-format +msgid "Unexpected accumulation method %s for %s." +msgstr "Onverwachte accumulatiemethode %s voor %s." + +#. module: mis_builder +#: code:addons/mis_builder/models/prorata_read_group_mixin.py:0 +#, python-format +msgid "Unsupported operator %s for searching on date" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.server,name:mis_builder.ir_cron_vacuum_temp_reports_ir_actions_server +#: model:ir.cron,cron_name:mis_builder.ir_cron_vacuum_temp_reports +#: model:ir.cron,name:mis_builder.ir_cron_vacuum_temp_reports +msgid "Vacuum temporary reports" +msgstr "Ledig tijdelijke rapporten" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__valid +msgid "Valid" +msgstr "Geldig" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__type +msgid "Value type" +msgstr "Waarde type" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Visibility" +msgstr "Zichtbaarheid" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__w +#, python-format +msgid "Week" +msgstr "Week" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_duration +msgid "Wrong duration, it must be positive!" +msgstr "Ongeldige duur, moet positief zijn!" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_normalize_factor +msgid "Wrong normalize factor, it must be positive!" +msgstr "Ongeldige normalisatie factor, moet positief zijn!" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__y +#, python-format +msgid "Year" +msgstr "Jaar" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Year to date" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "You cannot sum period %s with itself." +msgstr "Periode %s kan niet bij zichzelf worden opgeteld." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "from %s to %s" +msgstr "van %s tot %s" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__large +msgid "large" +msgstr "L" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__medium +msgid "medium" +msgstr "M" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "or" +msgstr "of" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "pp" +msgstr "pp" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__small +msgid "small" +msgstr "S" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_from_id +msgid "versus" +msgstr "versus" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-large +msgid "x-large" +msgstr "XL" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-small +msgid "x-small" +msgstr "XS" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-large +msgid "xx-large" +msgstr "XXL" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-small +msgid "xx-small" +msgstr "XXS" + +#~ msgid "" +#~ "AccountingNone: a null value that behaves as 0 in arithmetic " +#~ "operations." +#~ msgstr "" +#~ "AccountingNone: een null waarde welke zich gedraagt als een 0 in " +#~ "rekenkundige bewerkingen." + +#, fuzzy +#~ msgid "" +#~ "bal, crd, deb, pbal, nbal: balance, debit, credit, positive " +#~ "balance, negative balance." +#~ msgstr "bal, crd, deb: balans, debet, credit." + +#~ msgid "" +#~ "bal[70]: variation of the balance of account 70 over the period " +#~ "(it is the same as balp[70]." +#~ msgstr "" +#~ "bal[70]: variatie van de balans van rekening 70 over de periode " +#~ "(is hetzelfde als balp[70]." + +#~ msgid "" +#~ "bale[1%]: balance of accounts starting with 1 at end of period." +#~ msgstr "" +#~ "bale[1%]: balans van de rekeningen beginnend met een 1 aan het " +#~ "einde van de periode." + +#~ msgid "bali[70,60]: initial balance of accounts 70 and 60." +#~ msgstr "bali[70,60]: openingsbalans van de rekeningen 70 en 60." + +#~ msgid "" +#~ "balp[('user_type_id', '=', ref('account.data_account_type_receivable')." +#~ "id)][]: variation of the balance of all receivable accounts over the " +#~ "period." +#~ msgstr "" +#~ "balp[('user_type_id', '=', ref('account.data_account_type_receivable')." +#~ "id)][]: variatie van de balans bam alle te ontvangen rekeningen over " +#~ "de periode." + +#~ msgid "" +#~ "balp[][('tax_line_id.tag_ids', '=', ref('l10n_be.tax_tag_56').id)]: balance of move lines related to tax grid 56." +#~ msgstr "" +#~ "balp[][('tax_line_id.tag_ids', '=', ref('l10n_be.tax_tag_56').id)]: balans van de boekingsregels gerelateerd aan de belastingraster 56." + +#~ msgid "" +#~ "balu[]: (u for unallocated) is a special expression that shows the " +#~ "unallocated profit/loss of previous\n" +#~ " fiscal years." +#~ msgstr "" +#~ "balu[]: (u voor unallocated) is een speciale uitdrukking welke " +#~ "niet toegewezen winst/verlies van vorige\n" +#~ " fiscale jaren laat zien." + +#~ msgid "" +#~ "crdp[40%]: sum of all credits on accounts starting with 40 during " +#~ "the period." +#~ msgstr "" +#~ "crdp[40%]: som van alle kredieten op rekeningen beginnend met 40 " +#~ "over de periode." + +#~ msgid "date_from, date_to: beginning and end date of the period." +#~ msgstr "date_from, date_to: begin- en einddatum van de periode." + +#~ msgid "datetime, datetime, dateutil: the python modules." +#~ msgstr "datetime, datetime, dateutil: de python modules." + +#~ msgid "" +#~ "debp[55%][('journal_id.code', '=', 'BNK1')]: sum of all debits on " +#~ "accounts 55 and journal BNK1 during the period." +#~ msgstr "" +#~ "debp[55%][('journal_id.code', '=', 'BNK1')]: som van alle debet op " +#~ "rekening 55 en journaal BNK1 over de periode." + +#, fuzzy +#~ msgid "" +#~ "p, i, e: respectively variation over the period, initial balance, " +#~ "ending balance" +#~ msgstr "" +#~ "p, i, e: respectievelijk de variatie over; de periode, " +#~ "beginbalans, eindsaldo" + +#~ msgid "" +#~ "sum, min, max, len, avg: behave as expected, very similar to the " +#~ "python builtins." +#~ msgstr "" +#~ "sum, min, max, len, avg: Standaard werking, zeer vergelijkbaar met " +#~ "de python-builtins." + +#~ msgid "" +#~ "Additionally following variables are available in the evaluation context:" +#~ msgstr "" +#~ "Daarnaast zijn de volgende variabelen beschikbaar in de evaluatiecontext:" + +#, fuzzy +#~ msgid "" +#~ "Expressions can involve other KPI, sub KPI and query results by name (eg " +#~ "kpi1 + kpi2, kpi2.subkpi1, query1.field1)." +#~ msgstr "" +#~ "Uitdrukking kan ook andere KPI- en queryresultaten met naam omvatten " +#~ "(bijv. Kpi1 + kpi2)." + +#~ msgid "" +#~ "The account selector is a like expression on the account code (eg " +#~ "70%, etc)." +#~ msgstr "" +#~ "De account selector is een like uitdrukking op de rekening code " +#~ "(bv 70%, etc)." + +#~ msgid "" +#~ "The journal items domain is an Odoo domain filter on journal items." +#~ msgstr "" +#~ "De journal items domain is een Odoo domein filter op journaal " +#~ "items." + +#, fuzzy +#~ msgid "" +#~ "The following special elements are recognized in the expressions to " +#~ "compute accounting data:\n" +#~ " {bal|crd|deb|pbal|nbal}" +#~ "{pieu}[account selector][journal items domain]." +#~ msgstr "" +#~ "De volgende speciale elementen worden herkend in de uitdrukkingen om " +#~ "boekhoudgegevens te berekenen: \n" +#~ " {bal|crd|deb}{pieu}" +#~ "[account selecor][journal items domain]." + +#~ msgid "MIS Budget" +#~ msgstr "MIS Budgetten" + +#~ msgid "report.mis_builder.mis_report_instance_xlsx" +#~ msgstr "report.mis_builder.mis_report_instance_xlsx" + +#~ msgid "" +#~ "Probably not your fault... but I'm really curious to know how you managed " +#~ "to raise this error so I can handle one more corner case!" +#~ msgstr "" +#~ "Waarschijnlijk niet jouw schuld... maar we zijn erg benieuwd wat je hebt " +#~ "gedaan om deze fout te veroorzaken. Dan kunnen we dit probleem proberen " +#~ "te verhelpen!" + +#~ msgid "µ" +#~ msgstr "µ" + +#~ msgid "add.mis.report.instance.dashboard.wizard" +#~ msgstr "add.mis.report.instance.dashboard.wizard" + +#~ msgid "ir.actions.report" +#~ msgstr "ir.actions.report" + +#~ msgid "mis.report" +#~ msgstr "mis.report" + +#~ msgid "mis.report.instance" +#~ msgstr "mis.report.instance" + +#~ msgid "mis.report.instance.period" +#~ msgstr "mis.report.instance.period" + +#~ msgid "mis.report.instance.period.sum" +#~ msgstr "mis.report.instance.period.sum" + +#~ msgid "mis.report.kpi" +#~ msgstr "mis.report.kpi" + +#~ msgid "mis.report.kpi.expression" +#~ msgstr "mis.report.kpi.expression" + +#~ msgid "mis.report.query" +#~ msgstr "mis.report.query" + +#~ msgid "mis.report.style" +#~ msgstr "mis.report.style" + +#~ msgid "mis.report.subkpi" +#~ msgstr "mis.report.subkpi" diff --git a/odex25_accounting/mis_builder/i18n/nl_NL.po b/odex25_accounting/mis_builder/i18n/nl_NL.po new file mode 100644 index 000000000..1e78a7ceb --- /dev/null +++ b/odex25_accounting/mis_builder/i18n/nl_NL.po @@ -0,0 +1,2012 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mis_builder +# +# Translators: +# OCA Transbot , 2018 +# Frank Schellenberg , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-13 15:37+0000\n" +"PO-Revision-Date: 2018-07-07 15:10+0000\n" +"Last-Translator: Thomas Pot \n" +"Language-Team: Dutch (Netherlands) (https://www.transifex.com/oca/" +"teams/23907/nl_NL/)\n" +"Language: nl_NL\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.0.1\n" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "%s (copy)" +msgstr "%s (kopie)" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[('user_type_id', '=',\n" +" ref('account.\n" +" data_account_type_receivable')." +"id)][]\n" +" \n" +" : variation of the balance of " +"all receivable\n" +" accounts over the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[][('tax_line_id." +"tag_ids', '=',\n" +" ref('l10n_be.tax_tag_56')." +"id)]\n" +" \n" +" : balance of move lines related " +"to tax grid\n" +" 56." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" debp[55%][('journal_id." +"code', '=',\n" +" 'BNK1')]\n" +" \n" +" : sum of all debits on accounts " +"55 and\n" +" journal BNK1 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"AccountingNone\n" +" : a null value that behaves as 0 " +"in\n" +" arithmetic operations." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal, crd, deb, pbal, nbal\n" +" : balance, debit, credit, " +"positive balance,\n" +" negative balance." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal[70]\n" +" : variation of the balance of " +"account 70\n" +" over the period (it is the same " +"as balp[70]." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bale[1%]\n" +" : balance of accounts starting " +"with 1 at end\n" +" of period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bali[70,60]\n" +" : initial balance of accounts 70 " +"and 60." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"balu[]\n" +" : (u for unallocated) is a " +"special\n" +" expression that shows the " +"unallocated\n" +" profit/loss of previous\n" +" fiscal years." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"crdp[40%]\n" +" : sum of all credits on accounts " +"starting\n" +" with 40 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"date_from, date_to\n" +" : beginning and end date of the " +"period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"datetime, datetime, dateutil\n" +" : the python modules." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"p, i, e\n" +" : respectively variation over " +"the period,\n" +" initial balance, ending balance" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"pbale[55%]\n" +" : sum of all ending balances of " +"accounts\n" +" starting with 55 whose\n" +" ending balance is positive." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"sum, min, max, len, avg\n" +" : behave as expected, very " +"similar to the\n" +" python builtins." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields." +msgstr "" +"Een 'boekingsregel-achtig' model, d.w.z. heeft minimaal debet, credit, " +"datum, account_id en company_id velden" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__move_lines_source +#, fuzzy +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields. This model is the data source for column Actuals." +msgstr "" +"Een 'boekingsregel-achtig' model, d.w.z. heeft minimaal debet, credit, " +"datum, account_id en company_id velden" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "A date filter is mandatory for this source in column %s." +msgstr "Een datum filter is verplicht voor deze bron in kolom %s." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__account_model +#, fuzzy +msgid "Account model" +msgstr "Rekening details optellen" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__accumulation_method +msgid "Accumulation Method" +msgstr "Accumulatiemethode" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "" +"Actual (alternative) models used in columns must have the same account model " +"in the Account field and must be the same defined in the report template: %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals +msgid "Actuals" +msgstr "Actuele" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals_alt +msgid "Actuals (alternative)" +msgstr "Actuele (alternatief)" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source +msgid "" +"Actuals: current data, from accounting and other queries.\n" +"Actuals (alternative): current data from an alternative source (eg a " +"database view providing look-alike account move lines).\n" +"Sum columns: summation (+/-) of other columns.\n" +"Compare to column: compare to other column.\n" +msgstr "" +"Actuele: Huidige data, van boekhouding en andere queries.\n" +"Actuele (alternatief): Huidige data van een alternatieve bron (eg een " +"database view welke ook boekingsregels kan laten zien).\n" +"Kolommen optellen: sommatie (+/-) van andere kolommen.\n" +"Vergelijk kolommen: vergelijk met andere kolom.\n" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_prorata_read_group_mixin +msgid "Adapt model with date_from/date_to for pro-rata temporis read_group" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_add_to_dashboard_action +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Add to dashboard" +msgstr "Voeg toe aan dashboard" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Additionally following variables are available\n" +" in the evaluation context:" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__aggregate +msgid "Aggregate" +msgstr "Samenvoegen" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__all +msgid "All Entries" +msgstr "Alle boekingen" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__all_kpi_ids +msgid "All Kpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__posted +msgid "All Posted Entries" +msgstr "Alle Geboekte Regels" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__allowed_cmpcol_ids +msgid "Allowed Cmpcol" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__amount +msgid "Amount" +msgstr "Hoeveelheid" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__style_expression +msgid "" +"An expression that returns a style depending on the KPI value. Such style is " +"applied on top of the row style." +msgstr "" +"Een uitdrukking die een stijl retourneert afhankelijk van de KPI-waarde. Een " +"dergelijke stijl wordt toegepast bovenop de regelstijl." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_account_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "Analytic Account" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Account Filter" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_group_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_group_id +#, python-format +msgid "Analytic Account Group" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account Group: %s" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account: %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_tag_ids +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "Analytic Tags" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Tags Filter" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Tags: %s" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Auto expand" +msgstr "automatisch uitbreiden" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__avg +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__avg +#, python-format +msgid "Average" +msgstr "Gemiddelde" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color +msgid "Background Color" +msgstr "Achtergrond Kleur" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color_inherit +msgid "Background Color Inherit" +msgstr "Achtergrond Kleur Overerven" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__background_color +msgid "Background color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "Achtergrondkleur als geldige HEX code (van #000000 tot #FFFFFF)" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date +msgid "Base date" +msgstr "Uitgangsdatum" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__bold +msgid "Bold" +msgstr "Vet" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Can not update a multi kpi from the kpi line" +msgstr "Kan een multi-kpi niet bijwerken vanaf de kpi-regel" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Cancel" +msgstr "Annuleer" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__multi_company +msgid "" +"Check if you wish to specify children companies to be searched for data." +msgstr "" +"Controleer of u dochterbedrijven wilt selecteren waarvan de data moet worden " +"meegenomen." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Color" +msgstr "Kleur" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color_inherit +msgid "Color Inherit" +msgstr "Kleur Overerven" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_to_sum_id +msgid "Column" +msgstr "Kolom" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, fuzzy, python-format +msgid "Column %s cannot be compared to itrec." +msgstr "Kolom %skan niet met zichzelf worden vergeleken." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, fuzzy, python-format +msgid "Column %s with move lines source must have from/to dates." +msgstr "Kolom %s met Actuele waardes moet van/tot data hebben." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Columns" +msgstr "Kolommen" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Columns to compare must belong to the same report in %s" +msgstr "Te vergelijken kolommen moeten tot hetzelfde rapport in %s behoren" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_ids +msgid "Columns to sum" +msgstr "Op te sommen kolommen" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "Columns {} and {} are not comparable" +msgstr "Kolommen {} en {} zijn niet vergelijkbaar" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_ids +msgid "Companies" +msgstr "Bedrijven" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__query_company_ids +msgid "Companies for which data will be searched." +msgstr "Bedrijven waarvoor de data wordt doorzocht." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_id +msgid "Company" +msgstr "Bedrijf" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_to_id +msgid "Compare" +msgstr "Vergelijk" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__cmpcol +msgid "Compare columns" +msgstr "Vergelijk kolommen" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__compare_method +msgid "Comparison Method" +msgstr "Vergelijkingsmethode" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__comparison_mode +msgid "Comparison Mode" +msgstr "Vergelijkingsmodus" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_uid +msgid "Created by" +msgstr "Aangemaakt door" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_date +msgid "Created on" +msgstr "Aangemaakt op" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__currency_id +msgid "Currency" +msgstr "Valuta" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__dashboard_id +msgid "Dashboard" +msgstr "Dashboard" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date +#, fuzzy +msgid "Date" +msgstr "Data" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__date_field +msgid "Date Field" +msgstr "Datumveld" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_from +#, fuzzy +msgid "Date From" +msgstr "Datumveld" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_range_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_id +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__date_range +#, python-format +msgid "Date Range" +msgstr "Datumbereik" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_type_id +msgid "Date Range Type" +msgstr "Datumbereik Type" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_to +#, fuzzy +msgid "Date To" +msgstr "Data" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Dates" +msgstr "Data" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__d +#, python-format +msgid "Day" +msgstr "Dag" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__description +msgid "Description" +msgstr "Omschrijving" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__accumulation_method +msgid "" +"Determines how values of this kpi spanning over a time period are " +"transformed to match the reporting period. Sum: values of shorter period are " +"added, values of longest or partially overlapping periods are adjusted pro-" +"rata temporis.\n" +"Average: values of included period are averaged with a pro-rata temporis " +"weight." +msgstr "" +"Bepaalt hoe waarden van deze kpi over een periode worden omgezet in " +"overeenstemming met de rapportageperiode. \n" +"Som: waarden van kortere periode worden toegevoegd, waarden van langste of " +"gedeeltelijk overlappende perioden worden pro-rata temporis aangepast.\n" +"Gemiddelde: waarden van de opgenomen periode worden gemiddeld met een pro-" +"rata temporis-gewicht." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__diff +#, python-format +msgid "Difference" +msgstr "Verschil" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__no_auto_expand_accounts +#, fuzzy +msgid "Disable account details expansion" +msgstr "Rekening details optellen" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display Columns Description" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__display_name +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__display_name +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__display_name +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__display_name +msgid "Display Name" +msgstr "Weergavenaam" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts +msgid "Display details by account" +msgstr "Laat details per rekening zien" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display the date range details in the column headers." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider_inherit +msgid "Divider Inherit" +msgstr "Verdeler Overerven" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__domain +msgid "Domain" +msgstr "Domein" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp_inherit +msgid "Dp Inherit" +msgstr "Dp Overerven" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_prorata_read_group_mixin__date +msgid "" +"Dummy field that adapts searches on date to searches on date_from/date_to." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__duration +msgid "Duration" +msgstr "Duur" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Enter expression here, for example balp[70%]. See also help tab." +msgstr "" +"Vul hier een uitdrukking in, bijvoorbeeld balp[70%]. Zie ook het help " +"tabblad." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Examples:" +msgstr "Voorbeelden:" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Export" +msgstr "Exporteer" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__expression_ids +msgid "Expression" +msgstr "Uitdrukking" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions" +msgstr "Uitdrukkingen" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions can be any valid python expressions." +msgstr "Uitdrukkingen kunnen alle geldige python uitdrukkingen zijn." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Expressions can involve other KPI, sub KPI and\n" +" query results by name (eg kpi1 + " +"kpi2,\n" +" kpi2.subkpi1, query1.field1)." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__normalize_factor +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider +msgid "Factor" +msgstr "Factor" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Factor inherit" +msgstr "Factor overerven" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__normalize_factor +msgid "Factor to use to normalize the period (used in comparison" +msgstr "" +"Te gebruiken factor om de periode te normaliseren (wordt gebruikt bij " +"vergelijking" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_names +msgid "Fetched fields name" +msgstr "Opgehaalde veld namen" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_ids +msgid "Fields to fetch" +msgstr "Op te halen velden" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "" +"Filter column on journal entries that have all these analytic tags.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_group_id +msgid "" +"Filter column on journal entries that match this analytic account group. " +"This filter is combined with a AND with the report-level filters and cannot " +"be modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "" +"Filter column on journal entries that match this analytic account.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Filters" +msgstr "Filters" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__fix +msgid "Fixed dates" +msgstr "Vaste data" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Font" +msgstr "Lettertype" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size +msgid "Font Size" +msgstr "Lettertypegrootte" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size_inherit +msgid "Font Size Inherit" +msgstr "Lettertypegrootte Overerven" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style +msgid "Font Style" +msgstr "Letterstijl" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style_inherit +msgid "Font Style Inherit" +msgstr "Letterstijl Overerven" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight +msgid "Font Weight" +msgstr "Lettertype Dikte" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight_inherit +msgid "Font Weight Inherit" +msgstr "Lettertype Dikte Overerven" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Forces the start date to Jan 1st of the relevant year" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_from +msgid "From" +msgstr "Van" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_from +msgid "From (computed)" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/report/mis_report_instance_xlsx.py:0 +#, python-format +msgid "Generated on {} at {}" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Help (for KPI expressions)" +msgstr "Help (voor KPI uitdrukkingen)" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always +msgid "Hide Always" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always_inherit +#, fuzzy +msgid "Hide Always Inherit" +msgstr "Verberg Leeg Overerven" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__hide_analytic_filters +msgid "Hide Analytic Filters" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty +msgid "Hide Empty" +msgstr "Verberg Leeg" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty_inherit +msgid "Hide Empty Inherit" +msgstr "Verberg Leeg Overerven" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__id +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__id +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__id +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__id +msgid "ID" +msgstr "ID" + +#. module: mis_builder +#: code:addons/mis_builder/models/aep.py:0 +#, python-format +msgid "" +"If currency_id is not provided, all companies must have the same currency." +msgstr "" +"Als currency_id niet bekend is, alle bedrijven moeten dezelfde valuta hebben." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Indent" +msgstr "Inspringen" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level +msgid "Indent Level" +msgstr "Inspring Niveau" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level_inherit +msgid "Indent Level Inherit" +msgstr "Inspring Niveau Overerven" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "Indent level must be greater than or equal to 0" +msgstr "Inspring niveau moet groter of gelijk zijn aan 0" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__italic +msgid "Italic" +msgstr "Cursief" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__kpi_expression_id +msgid "KPI" +msgstr "KPI" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" has type {} while a tuple was expected.\n" +"\n" +"This can be fixed by either:\n" +"\t- Changing the KPI value to a tuple of length {}\n" +"or\n" +"\t- Changing the KPI to `multi` mode and giving an explicit value for each " +"sub-KPI." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" is valued as a tuple of length {} while a tuple of length {} is " +"expected." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq1 +#, fuzzy +msgid "KPI Sequence" +msgstr "Reeks" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, fuzzy, python-format +msgid "KPI name ({}) must be a valid python identifier" +msgstr "De naam moet een geldige python identifier zijn" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__kpi_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "KPI's" +msgstr "KPI's" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__all_kpi_ids +msgid "KPIs of this report and subreports." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__kpi_id +msgid "Kpi" +msgstr "Kpi" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__name +msgid "Label" +msgstr "Label" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__landscape_pdf +msgid "Landscape PDF" +msgstr "Landschap PDF" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard____last_update +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport____last_update +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin____last_update +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx____last_update +msgid "Last Modified on" +msgstr "Voor het laatst aangepast op" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.last_mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.last_wizard_mis_report_instance_view_menu +msgid "Last Reports Generated" +msgstr "Laatste Gegenereerde Rapport" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_uid +msgid "Last Updated by" +msgstr "Voor het laatst geüpdatet door" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_date +msgid "Last Updated on" +msgstr "Voor het laatst geüpdatet op" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Layout" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_report_mis_builder_mis_report_instance_xlsx +#, fuzzy +msgid "MIS Builder XLSX report" +msgstr "MIS rapportage instantie XLS rapport" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_kpi_data +msgid "MIS Kpi Data Abtract class" +msgstr "MIS Kpi Data Abtract class" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "MIS Report" +msgstr "MIS Rapport" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subreport +#, fuzzy +msgid "MIS Report - Sub Reports Relation" +msgstr "MIS Rapport Resultaat" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_add_mis_report_instance_dashboard_wizard +#, fuzzy +msgid "MIS Report Add to Dashboard Wizard" +msgstr "Voeg toe aan dashboard" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "MIS Report Instance" +msgstr "MIS Rapport Instantie" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period +#, fuzzy +msgid "MIS Report Instance Period" +msgstr "MIS Rapport Instantie" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period_sum +#, fuzzy +msgid "MIS Report Instance Period Sum" +msgstr "MIS Rapport Instantie" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "MIS Report Instances" +msgstr "MIS Rapport Instanties" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "MIS Report KPI" +msgstr "MIS Rapport KPI" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi_expression +#, fuzzy +msgid "MIS Report KPI Expression" +msgstr "MIS Rapport KPI" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_query +#, fuzzy +msgid "MIS Report Query" +msgstr "MIS Rapport" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_result_view_form +msgid "MIS Report Result" +msgstr "MIS Rapport Resultaat" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_style +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "MIS Report Style" +msgstr "MIS Rapport Stijl" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_style_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_style_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_tree +msgid "MIS Report Styles" +msgstr "MIS Rapport Stijlen" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subkpi +#, fuzzy +msgid "MIS Report Sub-KPI" +msgstr "MIS Rapport KPI" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report +#, fuzzy +msgid "MIS Report Template" +msgstr "MIS Rapport Templates" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_view_menu +msgid "MIS Report Templates" +msgstr "MIS Rapport Templates" + +#. module: mis_builder +#: model:ir.ui.menu,name:mis_builder.mis_report_conf_menu +#: model:ir.ui.menu,name:mis_builder.mis_report_finance_menu +msgid "MIS Reporting" +msgstr "MIS Rapportage" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_instance_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_tree +msgid "MIS Reports" +msgstr "MIS Rapporten" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.qweb_pdf_export +msgid "MIS report instance QWEB PDF report" +msgstr "MIS rapportage instantie QWEB PDF rapport" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.xls_export +msgid "MIS report instance XLS report" +msgstr "MIS rapportage instantie XLS rapport" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__max +#, python-format +msgid "Max" +msgstr "Max" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__min +#, python-format +msgid "Min" +msgstr "Min" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__mode +msgid "Mode" +msgstr "Modus" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__model_id +msgid "Model" +msgstr "Model" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__m +#, python-format +msgid "Month" +msgstr "Maand" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__move_lines_source +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "Move lines source" +msgstr "Bron boekingsregels" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_name +#, fuzzy +msgid "Move lines source model name" +msgstr "Bron boekingsregels" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__multi +msgid "Multi" +msgstr "Meerdere" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__multi_company +msgid "Multiple companies" +msgstr "Meerdere bedrijven" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__name +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Name" +msgstr "Naam" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__none +msgid "No date filter" +msgstr "Geen datum filter" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "No date filter is allowed for this source in column %s." +msgstr "Een datum filter is niet toegestaan voor deze bron in kolom %s." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__none +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__none +#, python-format +msgid "None" +msgstr "Geen" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__normal +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__nornal +msgid "Normal" +msgstr "Normaal" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Number" +msgstr "Aantal" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__duration +msgid "Number of periods" +msgstr "Aantal periodes" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__num +#, python-format +msgid "Numeric" +msgstr "Numeriek" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__offset +msgid "Offset" +msgstr "Offset" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__offset +msgid "Offset from current period" +msgstr "Offset t.o.v. huidige periode" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_id +msgid "Parent column" +msgstr "Bovenliggende kolom" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__pct +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__pct +#, python-format +msgid "Percentage" +msgstr "Percentage" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_name_unique +msgid "Period name should be unique by report" +msgstr "Periode naam dient per rapport uniek te zijn" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__type +msgid "Period type" +msgstr "Periode duur" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__period_ids +msgid "Periods" +msgstr "Periodes" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__pivot_date +msgid "Pivot date" +msgstr "Uitgangsdatum" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Please provide both columns to compare in %s." +msgstr "Geef beide kolommen op om te vergelijken in %s." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix +msgid "Prefix" +msgstr "Voorvoegsel" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix_inherit +msgid "Prefix Inherit" +msgstr "Voorvoegsel Overerven" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Preview" +msgstr "Voorbeeld" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Print" +msgstr "Afdrukken" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__query_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Queries" +msgstr "Query's" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__query_company_ids +msgid "Query Company" +msgstr "Query Bedrijf" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, fuzzy, python-format +msgid "Query name ({}) must be valid python identifier" +msgstr "De naam moet een geldige python identifier zijn" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Refresh" +msgstr "Ververs" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__relative +msgid "Relative to report base date" +msgstr "Ten opzichte van de rapport uitgangsdatum" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__report_id +msgid "Report" +msgstr "Rapport" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_ir_actions_report +#, fuzzy +msgid "Report Action" +msgstr "Rapport instantie" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_instance_id +msgid "Report Instance" +msgstr "Rapport instantie" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__date +msgid "Report base date (leave empty to use current date)" +msgstr "Uitgangsdatum Rapport (voor vandaag laat leeg)" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp +msgid "Rounding" +msgstr "Afronding" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Rounding inherit" +msgstr "Afronding overerven" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Save" +msgstr "Opslaan" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__company_ids +msgid "Select companies for which data will be searched." +msgstr "Selecteer de bedrijven waarvoor de data moet worden doorzocht." + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__currency_id +msgid "" +"Select target currency for the report. Required if companies have different " +"currencies." +msgstr "" +"Selecteer de hoofdvaluta voor het rapport. Vereist als bedrijven " +"verschillende valuta hebben." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__sequence +msgid "Sequence" +msgstr "Reeks" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Settings" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_subreport_unique +msgid "" +"Should not include the same report more than once as sub report of a given " +"report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__sign +msgid "Sign" +msgstr "Teken" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Source" +msgstr "Bron" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__str +#, python-format +msgid "String" +msgstr "String" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__style_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_id +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Style" +msgstr "Stijl" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_expression +msgid "Style expression" +msgstr "Stijl uitdrukking" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts_style_id +msgid "Style for account detail rows" +msgstr "Stijl voor detail rekening regels" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__name +msgid "Style name" +msgstr "Stijl naam" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subkpi_ids +msgid "Sub KPI" +msgstr "Sub KPI" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__subkpi_ids +msgid "Sub KPI Filter" +msgstr "Sub KPI filter" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_kpi_expression_subkpi_kpi_unique +msgid "Sub KPI must be used once and only once for each KPI" +msgstr "Sub KPI moet één keer worden gebruikt voor iedere KPI" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Sub KPI's" +msgstr "Sub KPI's" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +#, fuzzy +msgid "Sub Reports" +msgstr "MIS Rapporten" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subreport_ids +#, fuzzy +msgid "Sub reports" +msgstr "MIS Rapporten" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq2 +#, fuzzy +msgid "Sub-KPI Sequence" +msgstr "Reeks" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, fuzzy, python-format +msgid "Sub-KPI name ({}) must be a valid python identifier" +msgstr "De naam moet een geldige python identifier zijn" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__subkpi_id +msgid "Subkpi" +msgstr "Subkpi" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__subreport_id +#, fuzzy +msgid "Subreport" +msgstr "Rapport" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, python-format +msgid "Subreport loop detected" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, fuzzy, python-format +msgid "Subreport name ({}) must be a valid python identifier" +msgstr "De naam moet een geldige python identifier zijn" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_name_unique +#, fuzzy +msgid "Subreport name should be unique by report" +msgstr "Periode naam dient per rapport uniek te zijn" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix +msgid "Suffix" +msgstr "Achtervoegsel" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix_inherit +msgid "Suffix Inherit" +msgstr "Achtervoegsel Overerven" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__sum +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__sum +#, python-format +msgid "Sum" +msgstr "Optellen" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_accdet +msgid "Sum account details" +msgstr "Rekening details optellen" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "" +"Sum cannot be computed in column {} because the columns to sum have no " +"common subkpis" +msgstr "" +"Som kan niet worden berekend in kolom {} omdat de kolommen die moeten worden " +"opgeteld geen gemeenschappelijke subkpis hebben" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__sumcol +msgid "Sum columns" +msgstr "Kolommen optellen" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__target_move +msgid "Target Moves" +msgstr "Doel Boekingen" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "Template" +msgstr "Template" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__temporary +msgid "Temporary" +msgstr "Tijdelijk" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color +msgid "Text color" +msgstr "Tekst kleur" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__color +msgid "Text color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "Tekst kleur in geldige HEX code (van #000000 tot #FFFFFF)" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" account selector\n" +" is a like expression on the " +"account code (eg\n" +" 70%, etc)." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" journal items domain\n" +" is an Odoo domain filter on " +"journal items." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The following special elements are recognized in\n" +" the expressions to compute " +"accounting data:\n" +" \n" +" {bal|crd|deb|pbal|nbal}{pieu}" +"[account\n" +" selector][journal items domain]\n" +" \n" +" ." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_to +msgid "To" +msgstr "Tot" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_to +msgid "To (computed)" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_kpi_data.py:0 +#, python-format +msgid "Unexpected accumulation method %s for %s." +msgstr "Onverwachte accumulatiemethode %s voor %s." + +#. module: mis_builder +#: code:addons/mis_builder/models/prorata_read_group_mixin.py:0 +#, python-format +msgid "Unsupported operator %s for searching on date" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.server,name:mis_builder.ir_cron_vacuum_temp_reports_ir_actions_server +#: model:ir.cron,cron_name:mis_builder.ir_cron_vacuum_temp_reports +#: model:ir.cron,name:mis_builder.ir_cron_vacuum_temp_reports +msgid "Vacuum temporary reports" +msgstr "Ledig tijdelijke rapporten" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__valid +msgid "Valid" +msgstr "Geldig" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__type +msgid "Value type" +msgstr "Waarde type" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Visibility" +msgstr "Zichtbaarheid" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__w +#, python-format +msgid "Week" +msgstr "Week" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_duration +msgid "Wrong duration, it must be positive!" +msgstr "Ongeldige duur, moet positief zijn!" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_normalize_factor +msgid "Wrong normalize factor, it must be positive!" +msgstr "Ongeldige normalisatie factor, moet positief zijn!" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__y +#, python-format +msgid "Year" +msgstr "Jaar" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Year to date" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "You cannot sum period %s with itself." +msgstr "Periode %s kan niet bij zichzelf worden opgeteld." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "from %s to %s" +msgstr "van %s tot %s" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__large +msgid "large" +msgstr "L" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__medium +msgid "medium" +msgstr "M" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "or" +msgstr "of" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "pp" +msgstr "pp" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__small +msgid "small" +msgstr "S" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_from_id +msgid "versus" +msgstr "versus" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-large +msgid "x-large" +msgstr "XL" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-small +msgid "x-small" +msgstr "XS" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-large +msgid "xx-large" +msgstr "XXL" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-small +msgid "xx-small" +msgstr "XXS" + +#~ msgid "" +#~ "AccountingNone: a null value that behaves as 0 in arithmetic " +#~ "operations." +#~ msgstr "" +#~ "AccountingNone: een null waarde welke zich gedraagt als een 0 in " +#~ "rekenkundige bewerkingen." + +#, fuzzy +#~ msgid "" +#~ "bal, crd, deb, pbal, nbal: balance, debit, credit, positive " +#~ "balance, negative balance." +#~ msgstr "bal, crd, deb: balans, debet, credit." + +#~ msgid "" +#~ "bal[70]: variation of the balance of account 70 over the period " +#~ "(it is the same as balp[70]." +#~ msgstr "" +#~ "bal[70]: variatie van de balans van rekening 70 over de periode " +#~ "(is hetzelfde als balp[70]." + +#~ msgid "" +#~ "bale[1%]: balance of accounts starting with 1 at end of period." +#~ msgstr "" +#~ "bale[1%]: balans van de rekeningen beginnend met een 1 aan het " +#~ "einde van de periode." + +#~ msgid "bali[70,60]: initial balance of accounts 70 and 60." +#~ msgstr "bali[70,60]: openingsbalans van de rekeningen 70 en 60." + +#~ msgid "" +#~ "balp[('user_type_id', '=', ref('account.data_account_type_receivable')." +#~ "id)][]: variation of the balance of all receivable accounts over the " +#~ "period." +#~ msgstr "" +#~ "balp[('user_type_id', '=', ref('account.data_account_type_receivable')." +#~ "id)][]: variatie van de balans bam alle te ontvangen rekeningen over " +#~ "de periode." + +#~ msgid "" +#~ "balp[][('tax_line_id.tag_ids', '=', ref('l10n_be.tax_tag_56').id)]: balance of move lines related to tax grid 56." +#~ msgstr "" +#~ "balp[][('tax_line_id.tag_ids', '=', ref('l10n_be.tax_tag_56').id)]: balans van de boekingsregels gerelateerd aan de belastingraster 56." + +#~ msgid "" +#~ "balu[]: (u for unallocated) is a special expression that shows the " +#~ "unallocated profit/loss of previous\n" +#~ " fiscal years." +#~ msgstr "" +#~ "balu[]: (u voor unallocated) is een speciale uitdrukking welke " +#~ "niet toegewezen winst/verlies van vorige\n" +#~ " fiscale jaren laat zien." + +#~ msgid "" +#~ "crdp[40%]: sum of all credits on accounts starting with 40 during " +#~ "the period." +#~ msgstr "" +#~ "crdp[40%]: som van alle kredieten op rekeningen beginnend met 40 " +#~ "over de periode." + +#~ msgid "date_from, date_to: beginning and end date of the period." +#~ msgstr "date_from, date_to: begin- en einddatum van de periode." + +#~ msgid "datetime, datetime, dateutil: the python modules." +#~ msgstr "datetime, datetime, dateutil: de python modules." + +#~ msgid "" +#~ "debp[55%][('journal_id.code', '=', 'BNK1')]: sum of all debits on " +#~ "accounts 55 and journal BNK1 during the period." +#~ msgstr "" +#~ "debp[55%][('journal_id.code', '=', 'BNK1')]: som van alle debet op " +#~ "rekening 55 en journaal BNK1 over de periode." + +#, fuzzy +#~ msgid "" +#~ "p, i, e: respectively variation over the period, initial balance, " +#~ "ending balance" +#~ msgstr "" +#~ "p, i, e: respectievelijk de variatie over; de periode, " +#~ "beginbalans, eindsaldo" + +#~ msgid "" +#~ "sum, min, max, len, avg: behave as expected, very similar to the " +#~ "python builtins." +#~ msgstr "" +#~ "sum, min, max, len, avg: Standaard werking, zeer vergelijkbaar met " +#~ "de python-builtins." + +#~ msgid "" +#~ "Additionally following variables are available in the evaluation context:" +#~ msgstr "" +#~ "Daarnaast zijn de volgende variabelen beschikbaar in de evaluatiecontext:" + +#, fuzzy +#~ msgid "" +#~ "Expressions can involve other KPI, sub KPI and query results by name (eg " +#~ "kpi1 + kpi2, kpi2.subkpi1, query1.field1)." +#~ msgstr "" +#~ "Uitdrukking kan ook andere KPI- en queryresultaten met naam omvatten " +#~ "(bijv. Kpi1 + kpi2)." + +#~ msgid "" +#~ "The account selector is a like expression on the account code (eg " +#~ "70%, etc)." +#~ msgstr "" +#~ "De account selector is een like uitdrukking op de rekening code " +#~ "(bv 70%, etc)." + +#~ msgid "" +#~ "The journal items domain is an Odoo domain filter on journal items." +#~ msgstr "" +#~ "De journal items domain is een Odoo domein filter op journaal " +#~ "items." + +#, fuzzy +#~ msgid "" +#~ "The following special elements are recognized in the expressions to " +#~ "compute accounting data:\n" +#~ " {bal|crd|deb|pbal|nbal}" +#~ "{pieu}[account selector][journal items domain]." +#~ msgstr "" +#~ "De volgende speciale elementen worden herkend in de uitdrukkingen om " +#~ "boekhoudgegevens te berekenen: \n" +#~ " {bal|crd|deb}{pieu}" +#~ "[account selecor][journal items domain]." + +#~ msgid "MIS Budget" +#~ msgstr "MIS Budgetten" + +#~ msgid "report.mis_builder.mis_report_instance_xlsx" +#~ msgstr "report.mis_builder.mis_report_instance_xlsx" + +#~ msgid "" +#~ "Probably not your fault... but I'm really curious to know how you managed " +#~ "to raise this error so I can handle one more corner case!" +#~ msgstr "" +#~ "Waarschijnlijk niet jouw schuld... maar we zijn erg benieuwd wat je hebt " +#~ "gedaan om deze fout te veroorzaken. Dan kunnen we dit probleem proberen " +#~ "te verhelpen!" + +#~ msgid "µ" +#~ msgstr "µ" + +#~ msgid "add.mis.report.instance.dashboard.wizard" +#~ msgstr "add.mis.report.instance.dashboard.wizard" + +#~ msgid "ir.actions.report" +#~ msgstr "ir.actions.report" + +#~ msgid "mis.report" +#~ msgstr "mis.report" + +#~ msgid "mis.report.instance" +#~ msgstr "mis.report.instance" + +#~ msgid "mis.report.instance.period" +#~ msgstr "mis.report.instance.period" + +#~ msgid "mis.report.instance.period.sum" +#~ msgstr "mis.report.instance.period.sum" + +#~ msgid "mis.report.kpi" +#~ msgstr "mis.report.kpi" + +#~ msgid "mis.report.kpi.expression" +#~ msgstr "mis.report.kpi.expression" + +#~ msgid "mis.report.query" +#~ msgstr "mis.report.query" + +#~ msgid "mis.report.style" +#~ msgstr "mis.report.style" + +#~ msgid "mis.report.subkpi" +#~ msgstr "mis.report.subkpi" diff --git a/odex25_accounting/mis_builder/i18n/pt.po b/odex25_accounting/mis_builder/i18n/pt.po new file mode 100644 index 000000000..f0269d3fb --- /dev/null +++ b/odex25_accounting/mis_builder/i18n/pt.po @@ -0,0 +1,1780 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mis_builder +# +# Translators: +# OCA Transbot , 2018 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-01-13 15:37+0000\n" +"PO-Revision-Date: 2018-01-13 15:37+0000\n" +"Last-Translator: OCA Transbot , 2018\n" +"Language-Team: Portuguese (https://www.transifex.com/oca/teams/23907/pt/)\n" +"Language: pt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "%s (copy)" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[('user_type_id', '=',\n" +" ref('account.\n" +" data_account_type_receivable')." +"id)][]\n" +" \n" +" : variation of the balance of " +"all receivable\n" +" accounts over the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[][('tax_line_id." +"tag_ids', '=',\n" +" ref('l10n_be.tax_tag_56')." +"id)]\n" +" \n" +" : balance of move lines related " +"to tax grid\n" +" 56." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" debp[55%][('journal_id." +"code', '=',\n" +" 'BNK1')]\n" +" \n" +" : sum of all debits on accounts " +"55 and\n" +" journal BNK1 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"AccountingNone\n" +" : a null value that behaves as 0 " +"in\n" +" arithmetic operations." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal, crd, deb, pbal, nbal\n" +" : balance, debit, credit, " +"positive balance,\n" +" negative balance." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal[70]\n" +" : variation of the balance of " +"account 70\n" +" over the period (it is the same " +"as balp[70]." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bale[1%]\n" +" : balance of accounts starting " +"with 1 at end\n" +" of period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bali[70,60]\n" +" : initial balance of accounts 70 " +"and 60." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"balu[]\n" +" : (u for unallocated) is a " +"special\n" +" expression that shows the " +"unallocated\n" +" profit/loss of previous\n" +" fiscal years." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"crdp[40%]\n" +" : sum of all credits on accounts " +"starting\n" +" with 40 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"date_from, date_to\n" +" : beginning and end date of the " +"period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"datetime, datetime, dateutil\n" +" : the python modules." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"p, i, e\n" +" : respectively variation over " +"the period,\n" +" initial balance, ending balance" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"pbale[55%]\n" +" : sum of all ending balances of " +"accounts\n" +" starting with 55 whose\n" +" ending balance is positive." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"sum, min, max, len, avg\n" +" : behave as expected, very " +"similar to the\n" +" python builtins." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__move_lines_source +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields. This model is the data source for column Actuals." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "A date filter is mandatory for this source in column %s." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__account_model +msgid "Account model" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__accumulation_method +msgid "Accumulation Method" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "" +"Actual (alternative) models used in columns must have the same account model " +"in the Account field and must be the same defined in the report template: %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals +msgid "Actuals" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals_alt +msgid "Actuals (alternative)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source +msgid "" +"Actuals: current data, from accounting and other queries.\n" +"Actuals (alternative): current data from an alternative source (eg a " +"database view providing look-alike account move lines).\n" +"Sum columns: summation (+/-) of other columns.\n" +"Compare to column: compare to other column.\n" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_prorata_read_group_mixin +msgid "Adapt model with date_from/date_to for pro-rata temporis read_group" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_add_to_dashboard_action +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Add to dashboard" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Additionally following variables are available\n" +" in the evaluation context:" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__aggregate +msgid "Aggregate" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__all +msgid "All Entries" +msgstr "Todos os lançamentos" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__all_kpi_ids +msgid "All Kpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__posted +msgid "All Posted Entries" +msgstr "Todos os lançamentos publicados" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__allowed_cmpcol_ids +msgid "Allowed Cmpcol" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__amount +msgid "Amount" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__style_expression +msgid "" +"An expression that returns a style depending on the KPI value. Such style is " +"applied on top of the row style." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_account_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "Analytic Account" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Account Filter" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_group_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_group_id +#, python-format +msgid "Analytic Account Group" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account Group: %s" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account: %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_tag_ids +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "Analytic Tags" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Tags Filter" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Tags: %s" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Auto expand" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__avg +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__avg +#, python-format +msgid "Average" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color +msgid "Background Color" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color_inherit +msgid "Background Color Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__background_color +msgid "Background color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date +msgid "Base date" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__bold +msgid "Bold" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Can not update a multi kpi from the kpi line" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Cancel" +msgstr "Cancelar" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__multi_company +msgid "" +"Check if you wish to specify children companies to be searched for data." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Color" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color_inherit +msgid "Color Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_to_sum_id +msgid "Column" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Column %s cannot be compared to itrec." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Column %s with move lines source must have from/to dates." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Columns" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Columns to compare must belong to the same report in %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_ids +msgid "Columns to sum" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "Columns {} and {} are not comparable" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_ids +msgid "Companies" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__query_company_ids +msgid "Companies for which data will be searched." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_id +msgid "Company" +msgstr "Empresa" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_to_id +msgid "Compare" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__cmpcol +msgid "Compare columns" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__compare_method +msgid "Comparison Method" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__comparison_mode +msgid "Comparison Mode" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_uid +msgid "Created by" +msgstr "Criado por" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_date +msgid "Created on" +msgstr "Criado em" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__currency_id +msgid "Currency" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__dashboard_id +msgid "Dashboard" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date +msgid "Date" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__date_field +msgid "Date Field" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_from +msgid "Date From" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_range_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_id +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__date_range +#, python-format +msgid "Date Range" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_type_id +msgid "Date Range Type" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_to +msgid "Date To" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Dates" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__d +#, python-format +msgid "Day" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__description +msgid "Description" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__accumulation_method +msgid "" +"Determines how values of this kpi spanning over a time period are " +"transformed to match the reporting period. Sum: values of shorter period are " +"added, values of longest or partially overlapping periods are adjusted pro-" +"rata temporis.\n" +"Average: values of included period are averaged with a pro-rata temporis " +"weight." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__diff +#, python-format +msgid "Difference" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__no_auto_expand_accounts +msgid "Disable account details expansion" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display Columns Description" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__display_name +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__display_name +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__display_name +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__display_name +msgid "Display Name" +msgstr "Nome a exibir" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts +msgid "Display details by account" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display the date range details in the column headers." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider_inherit +msgid "Divider Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__domain +msgid "Domain" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp_inherit +msgid "Dp Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_prorata_read_group_mixin__date +msgid "" +"Dummy field that adapts searches on date to searches on date_from/date_to." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__duration +msgid "Duration" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Enter expression here, for example balp[70%]. See also help tab." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Examples:" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Export" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__expression_ids +msgid "Expression" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions can be any valid python expressions." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Expressions can involve other KPI, sub KPI and\n" +" query results by name (eg kpi1 + " +"kpi2,\n" +" kpi2.subkpi1, query1.field1)." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__normalize_factor +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider +msgid "Factor" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Factor inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__normalize_factor +msgid "Factor to use to normalize the period (used in comparison" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_names +msgid "Fetched fields name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_ids +msgid "Fields to fetch" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "" +"Filter column on journal entries that have all these analytic tags.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_group_id +msgid "" +"Filter column on journal entries that match this analytic account group. " +"This filter is combined with a AND with the report-level filters and cannot " +"be modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "" +"Filter column on journal entries that match this analytic account.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Filters" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__fix +msgid "Fixed dates" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Font" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size +msgid "Font Size" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size_inherit +msgid "Font Size Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style +msgid "Font Style" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style_inherit +msgid "Font Style Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight +msgid "Font Weight" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight_inherit +msgid "Font Weight Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Forces the start date to Jan 1st of the relevant year" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_from +msgid "From" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_from +msgid "From (computed)" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/report/mis_report_instance_xlsx.py:0 +#, python-format +msgid "Generated on {} at {}" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Help (for KPI expressions)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always +msgid "Hide Always" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always_inherit +msgid "Hide Always Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__hide_analytic_filters +msgid "Hide Analytic Filters" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty +msgid "Hide Empty" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty_inherit +msgid "Hide Empty Inherit" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__id +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__id +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__id +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__id +msgid "ID" +msgstr "ID" + +#. module: mis_builder +#: code:addons/mis_builder/models/aep.py:0 +#, python-format +msgid "" +"If currency_id is not provided, all companies must have the same currency." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Indent" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level +msgid "Indent Level" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level_inherit +msgid "Indent Level Inherit" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "Indent level must be greater than or equal to 0" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__italic +msgid "Italic" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__kpi_expression_id +msgid "KPI" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" has type {} while a tuple was expected.\n" +"\n" +"This can be fixed by either:\n" +"\t- Changing the KPI value to a tuple of length {}\n" +"or\n" +"\t- Changing the KPI to `multi` mode and giving an explicit value for each " +"sub-KPI." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" is valued as a tuple of length {} while a tuple of length {} is " +"expected." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq1 +msgid "KPI Sequence" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "KPI name ({}) must be a valid python identifier" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__kpi_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "KPI's" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__all_kpi_ids +msgid "KPIs of this report and subreports." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__kpi_id +msgid "Kpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__name +msgid "Label" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__landscape_pdf +msgid "Landscape PDF" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard____last_update +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport____last_update +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin____last_update +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx____last_update +msgid "Last Modified on" +msgstr "Última Modificação em" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.last_mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.last_wizard_mis_report_instance_view_menu +msgid "Last Reports Generated" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_uid +msgid "Last Updated by" +msgstr "Última atualização por" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_date +msgid "Last Updated on" +msgstr "Última atualização em" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Layout" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_report_mis_builder_mis_report_instance_xlsx +msgid "MIS Builder XLSX report" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_kpi_data +msgid "MIS Kpi Data Abtract class" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "MIS Report" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subreport +msgid "MIS Report - Sub Reports Relation" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_add_mis_report_instance_dashboard_wizard +msgid "MIS Report Add to Dashboard Wizard" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "MIS Report Instance" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period +msgid "MIS Report Instance Period" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period_sum +msgid "MIS Report Instance Period Sum" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "MIS Report Instances" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "MIS Report KPI" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi_expression +msgid "MIS Report KPI Expression" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_query +msgid "MIS Report Query" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_result_view_form +msgid "MIS Report Result" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_style +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "MIS Report Style" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_style_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_style_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_tree +msgid "MIS Report Styles" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subkpi +msgid "MIS Report Sub-KPI" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report +msgid "MIS Report Template" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_view_menu +msgid "MIS Report Templates" +msgstr "" + +#. module: mis_builder +#: model:ir.ui.menu,name:mis_builder.mis_report_conf_menu +#: model:ir.ui.menu,name:mis_builder.mis_report_finance_menu +msgid "MIS Reporting" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_instance_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_tree +msgid "MIS Reports" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.qweb_pdf_export +msgid "MIS report instance QWEB PDF report" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.xls_export +msgid "MIS report instance XLS report" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__max +#, python-format +msgid "Max" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__min +#, python-format +msgid "Min" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__mode +msgid "Mode" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__model_id +msgid "Model" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__m +#, python-format +msgid "Month" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__move_lines_source +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "Move lines source" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_name +msgid "Move lines source model name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__multi +msgid "Multi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__multi_company +msgid "Multiple companies" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__name +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Name" +msgstr "Nome" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__none +msgid "No date filter" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "No date filter is allowed for this source in column %s." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__none +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__none +#, python-format +msgid "None" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__normal +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__nornal +msgid "Normal" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Number" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__duration +msgid "Number of periods" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__num +#, python-format +msgid "Numeric" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__offset +msgid "Offset" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__offset +msgid "Offset from current period" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_id +msgid "Parent column" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__pct +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__pct +#, python-format +msgid "Percentage" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_name_unique +msgid "Period name should be unique by report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__type +msgid "Period type" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__period_ids +msgid "Periods" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__pivot_date +msgid "Pivot date" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Please provide both columns to compare in %s." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix +msgid "Prefix" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix_inherit +msgid "Prefix Inherit" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Preview" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Print" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__query_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Queries" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__query_company_ids +msgid "Query Company" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Query name ({}) must be valid python identifier" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Refresh" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__relative +msgid "Relative to report base date" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__report_id +msgid "Report" +msgstr "" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_ir_actions_report +msgid "Report Action" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_instance_id +msgid "Report Instance" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__date +msgid "Report base date (leave empty to use current date)" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp +msgid "Rounding" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Rounding inherit" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Save" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__company_ids +msgid "Select companies for which data will be searched." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__currency_id +msgid "" +"Select target currency for the report. Required if companies have different " +"currencies." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__sequence +msgid "Sequence" +msgstr "" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Settings" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_subreport_unique +msgid "" +"Should not include the same report more than once as sub report of a given " +"report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__sign +msgid "Sign" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Source" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__str +#, python-format +msgid "String" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__style_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_id +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Style" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_expression +msgid "Style expression" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts_style_id +msgid "Style for account detail rows" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__name +msgid "Style name" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subkpi_ids +msgid "Sub KPI" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__subkpi_ids +msgid "Sub KPI Filter" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_kpi_expression_subkpi_kpi_unique +msgid "Sub KPI must be used once and only once for each KPI" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Sub KPI's" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Sub Reports" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subreport_ids +msgid "Sub reports" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq2 +msgid "Sub-KPI Sequence" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Sub-KPI name ({}) must be a valid python identifier" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__subkpi_id +msgid "Subkpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__subreport_id +msgid "Subreport" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, python-format +msgid "Subreport loop detected" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, python-format +msgid "Subreport name ({}) must be a valid python identifier" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_name_unique +msgid "Subreport name should be unique by report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix +msgid "Suffix" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix_inherit +msgid "Suffix Inherit" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__sum +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__sum +#, python-format +msgid "Sum" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_accdet +msgid "Sum account details" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "" +"Sum cannot be computed in column {} because the columns to sum have no " +"common subkpis" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__sumcol +msgid "Sum columns" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__target_move +msgid "Target Moves" +msgstr "Movimentos alvo" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "Template" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__temporary +msgid "Temporary" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color +msgid "Text color" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__color +msgid "Text color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" account selector\n" +" is a like expression on the " +"account code (eg\n" +" 70%, etc)." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" journal items domain\n" +" is an Odoo domain filter on " +"journal items." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The following special elements are recognized in\n" +" the expressions to compute " +"accounting data:\n" +" \n" +" {bal|crd|deb|pbal|nbal}{pieu}" +"[account\n" +" selector][journal items domain]\n" +" \n" +" ." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_to +msgid "To" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_to +msgid "To (computed)" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_kpi_data.py:0 +#, python-format +msgid "Unexpected accumulation method %s for %s." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/prorata_read_group_mixin.py:0 +#, python-format +msgid "Unsupported operator %s for searching on date" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.server,name:mis_builder.ir_cron_vacuum_temp_reports_ir_actions_server +#: model:ir.cron,cron_name:mis_builder.ir_cron_vacuum_temp_reports +#: model:ir.cron,name:mis_builder.ir_cron_vacuum_temp_reports +msgid "Vacuum temporary reports" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__valid +msgid "Valid" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__type +msgid "Value type" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Visibility" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__w +#, python-format +msgid "Week" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_duration +msgid "Wrong duration, it must be positive!" +msgstr "" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_normalize_factor +msgid "Wrong normalize factor, it must be positive!" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__y +#, python-format +msgid "Year" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Year to date" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "You cannot sum period %s with itself." +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "from %s to %s" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__large +msgid "large" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__medium +msgid "medium" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "or" +msgstr "ou" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "pp" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__small +msgid "small" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_from_id +msgid "versus" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-large +msgid "x-large" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-small +msgid "x-small" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-large +msgid "xx-large" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-small +msgid "xx-small" +msgstr "" diff --git a/odex25_accounting/mis_builder/i18n/pt_BR.po b/odex25_accounting/mis_builder/i18n/pt_BR.po new file mode 100644 index 000000000..c254d058f --- /dev/null +++ b/odex25_accounting/mis_builder/i18n/pt_BR.po @@ -0,0 +1,1965 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mis_builder +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2019-12-20 04:05+0000\n" +"Last-Translator: Eder Brito \n" +"Language-Team: none\n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 3.9.1\n" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "%s (copy)" +msgstr "%s (cópia)" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[('user_type_id', '=',\n" +" ref('account.\n" +" data_account_type_receivable')." +"id)][]\n" +" \n" +" : variation of the balance of " +"all receivable\n" +" accounts over the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" balp[][('tax_line_id." +"tag_ids', '=',\n" +" ref('l10n_be.tax_tag_56')." +"id)]\n" +" \n" +" : balance of move lines related " +"to tax grid\n" +" 56." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"\n" +" debp[55%][('journal_id." +"code', '=',\n" +" 'BNK1')]\n" +" \n" +" : sum of all debits on accounts " +"55 and\n" +" journal BNK1 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"AccountingNone\n" +" : a null value that behaves as 0 " +"in\n" +" arithmetic operations." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal, crd, deb, pbal, nbal\n" +" : balance, debit, credit, " +"positive balance,\n" +" negative balance." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bal[70]\n" +" : variation of the balance of " +"account 70\n" +" over the period (it is the same " +"as balp[70]." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bale[1%]\n" +" : balance of accounts starting " +"with 1 at end\n" +" of period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"bali[70,60]\n" +" : initial balance of accounts 70 " +"and 60." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"balu[]\n" +" : (u for unallocated) is a " +"special\n" +" expression that shows the " +"unallocated\n" +" profit/loss of previous\n" +" fiscal years." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"crdp[40%]\n" +" : sum of all credits on accounts " +"starting\n" +" with 40 during the period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"date_from, date_to\n" +" : beginning and end date of the " +"period." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"datetime, datetime, dateutil\n" +" : the python modules." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"p, i, e\n" +" : respectively variation over " +"the period,\n" +" initial balance, ending balance" +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"pbale[55%]\n" +" : sum of all ending balances of " +"accounts\n" +" starting with 55 whose\n" +" ending balance is positive." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"sum, min, max, len, avg\n" +" : behave as expected, very " +"similar to the\n" +" python builtins." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields." +msgstr "" +"Um modelo 'mova a linha como', ou seja, com ao menos os campos debit, " +"credit, date, account_id e company_id." + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__move_lines_source +msgid "" +"A 'move line like' model, ie having at least debit, credit, date, account_id " +"and company_id fields. This model is the data source for column Actuals." +msgstr "" +"Um modelo 'mover linha como', ou seja, com ao menos os campos debit, credit, " +"date, account_id e company_id. Este modelo é a fonte de dados da coluna " +"Reais." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "A date filter is mandatory for this source in column %s." +msgstr "Um filtro de data é obrigatório para esta fonte na coluna %s." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__account_model +msgid "Account model" +msgstr "Modelo de conta" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__accumulation_method +msgid "Accumulation Method" +msgstr "Método de Acumulação" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "" +"Actual (alternative) models used in columns must have the same account model " +"in the Account field and must be the same defined in the report template: %s" +msgstr "" +"Real (alternativa) modelos usados em colunas devem possuir a mesma conta do " +"modelo no campo Conta e devem ter a mesma definição no modelo do relatório: " +"%s" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals +msgid "Actuals" +msgstr "Atuais" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__actuals_alt +msgid "Actuals (alternative)" +msgstr "Atuais (alternativa)" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__source +msgid "" +"Actuals: current data, from accounting and other queries.\n" +"Actuals (alternative): current data from an alternative source (eg a " +"database view providing look-alike account move lines).\n" +"Sum columns: summation (+/-) of other columns.\n" +"Compare to column: compare to other column.\n" +msgstr "" +"Atuais: dados atuais, de contabilidade e outras consultas.\n" +"Atuais (alternativas): dados atuais de uma fonte alternativa (por exemplo, " +"uma exibição de banco de dados que fornece linhas de movimentação de conta " +"semelhantes).\n" +"Soma de Colunas: Soma (+/-) de outras colunas.\n" +"Comparar a Columa: Compare com outra coluna.\n" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_prorata_read_group_mixin +msgid "Adapt model with date_from/date_to for pro-rata temporis read_group" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_add_to_dashboard_action +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Add to dashboard" +msgstr "Adicionar ao Painel" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Additionally following variables are available\n" +" in the evaluation context:" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__aggregate +msgid "Aggregate" +msgstr "Agregado" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__all +msgid "All Entries" +msgstr "Todas as Entradas" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__all_kpi_ids +msgid "All Kpi" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance__target_move__posted +msgid "All Posted Entries" +msgstr "Todas as Entradas Postadas" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__allowed_cmpcol_ids +msgid "Allowed Cmpcol" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__amount +msgid "Amount" +msgstr "Montante" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__style_expression +msgid "" +"An expression that returns a style depending on the KPI value. Such style is " +"applied on top of the row style." +msgstr "" +"Uma expressão que retorna um estilo dependendo do valor KPI. Esse estilo é " +"aplicado no topo do estilo da linha." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_account_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "Analytic Account" +msgstr "Conta Analítica" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Account Filter" +msgstr "Filtro de Conta Analítica" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_group_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_group_id +#, python-format +msgid "Analytic Account Group" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account Group: %s" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Account: %s" +msgstr "Conta Analítica: %s" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__analytic_tag_ids +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "Analytic Tags" +msgstr "Marcador de Conta Analítica" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/js/mis_report_widget.js:0 +#, python-format +msgid "Analytic Tags Filter" +msgstr "Filtro de Marcadores Analíticos" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Analytic Tags: %s" +msgstr "Marcadores Analíticos: %s" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Auto expand" +msgstr "Expandir Automaticamente" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__avg +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__avg +#, python-format +msgid "Average" +msgstr "Média" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color +msgid "Background Color" +msgstr "Cor de Fundo" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__background_color_inherit +msgid "Background Color Inherit" +msgstr "Cor de Fundo Herdada" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__background_color +msgid "Background color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "Cor de fundo em código RGB válido (de #000000 a #FFFFFF)" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date +msgid "Base date" +msgstr "Data base" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__bold +msgid "Bold" +msgstr "Negrito" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "Can not update a multi kpi from the kpi line" +msgstr "Não é possível atualizar um multi kpi da linha kpi" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Cancel" +msgstr "Cancelar" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__multi_company +msgid "" +"Check if you wish to specify children companies to be searched for data." +msgstr "" +"Verifique se deseja especificar empresas filhas para serem pesquisadas por " +"dados." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Color" +msgstr "Cor" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color_inherit +msgid "Color Inherit" +msgstr "Cor Herdada" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_to_sum_id +msgid "Column" +msgstr "Coluna" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Column %s cannot be compared to itrec." +msgstr "Coluna %s não pode ser comparada a itrec." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, fuzzy, python-format +msgid "Column %s with move lines source must have from/to dates." +msgstr "Coluna %s com pesquisas atuais devem ter datas de/para." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Columns" +msgstr "Colunas" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Columns to compare must belong to the same report in %s" +msgstr "Colunas para comparar devem pertencer ao mesmo relatório em %s" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_ids +msgid "Columns to sum" +msgstr "Colunas para somar" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "Columns {} and {} are not comparable" +msgstr "Colunas {} e {} não são comparáveis" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_ids +msgid "Companies" +msgstr "Empresas" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__query_company_ids +msgid "Companies for which data will be searched." +msgstr "Empresas para as quais os dados serão pesquisados." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__company_id +msgid "Company" +msgstr "Empresa" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_to_id +msgid "Compare" +msgstr "Comparar" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__cmpcol +msgid "Compare columns" +msgstr "Comparar colunas" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__compare_method +msgid "Comparison Method" +msgstr "Método de Comparação" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__comparison_mode +msgid "Comparison Mode" +msgstr "Modo de Comparação" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_uid +msgid "Created by" +msgstr "Criado por" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__create_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__create_date +msgid "Created on" +msgstr "Criado em" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__currency_id +msgid "Currency" +msgstr "Moeda" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__dashboard_id +msgid "Dashboard" +msgstr "Painel" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date +#, fuzzy +msgid "Date" +msgstr "Datas" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__date_field +msgid "Date Field" +msgstr "Campo de Data" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_from +#, fuzzy +msgid "Date From" +msgstr "Campo de Data" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_range_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_id +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__date_range +#, python-format +msgid "Date Range" +msgstr "Intervalo de Data" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_range_type_id +msgid "Date Range Type" +msgstr "Tipo de Intervalo de Data" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__date_to +#, fuzzy +msgid "Date To" +msgstr "Datas" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Dates" +msgstr "Datas" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__d +#, python-format +msgid "Day" +msgstr "Dia" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__description +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__description +msgid "Description" +msgstr "Descrição" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_kpi__accumulation_method +msgid "" +"Determines how values of this kpi spanning over a time period are " +"transformed to match the reporting period. Sum: values of shorter period are " +"added, values of longest or partially overlapping periods are adjusted pro-" +"rata temporis.\n" +"Average: values of included period are averaged with a pro-rata temporis " +"weight." +msgstr "" +"Determina como os valores deste kpi abrangendo um período de tempo são " +"transformados para corresponder ao período do relatório. Soma: são " +"adicionados valores de período mais curto, valores de períodos mais longos " +"ou parcialmente sobrepostos são ajustados pro-rata temporis." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__diff +#, python-format +msgid "Difference" +msgstr "Diferença" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__no_auto_expand_accounts +msgid "Disable account details expansion" +msgstr "Desabilitar expansão de detalhes de conta" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display Columns Description" +msgstr "Exibir Descrição de Colunas" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__display_name +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__display_name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__display_name +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__display_name +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__display_name +msgid "Display Name" +msgstr "Exibir Nome" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts +msgid "Display details by account" +msgstr "Exibir detalhes por conta" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__display_columns_description +msgid "Display the date range details in the column headers." +msgstr "Exibir os detalhes de intervalo de data nas colunas de cabeçalhos." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider_inherit +msgid "Divider Inherit" +msgstr "Divisor de Herança" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__domain +msgid "Domain" +msgstr "Domínio" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp_inherit +msgid "Dp Inherit" +msgstr "Herança Dp" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_prorata_read_group_mixin__date +msgid "" +"Dummy field that adapts searches on date to searches on date_from/date_to." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__duration +msgid "Duration" +msgstr "Duração" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Enter expression here, for example balp[70%]. See also help tab." +msgstr "" +"Digite a expressão aqui, por exemplo balp[70%]. Veja também a guia ajuda." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Examples:" +msgstr "Exemplos:" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Export" +msgstr "Exportar" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__expression_ids +msgid "Expression" +msgstr "Expressão" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__expression_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions" +msgstr "Expressões" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Expressions can be any valid python expressions." +msgstr "Expressões podem ser qualquer expressão python válida." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"Expressions can involve other KPI, sub KPI and\n" +" query results by name (eg kpi1 + " +"kpi2,\n" +" kpi2.subkpi1, query1.field1)." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__normalize_factor +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__divider +msgid "Factor" +msgstr "Fator" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Factor inherit" +msgstr "Fator herdado" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__normalize_factor +msgid "Factor to use to normalize the period (used in comparison" +msgstr "Fator para usar para normalizar o período (usado em comparação" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_names +msgid "Fetched fields name" +msgstr "Nome de campos buscados" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__field_ids +msgid "Fields to fetch" +msgstr "Campos para buscar" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_tag_ids +msgid "" +"Filter column on journal entries that have all these analytic tags.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_group_id +msgid "" +"Filter column on journal entries that match this analytic account group. " +"This filter is combined with a AND with the report-level filters and cannot " +"be modified in the preview." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__analytic_account_id +msgid "" +"Filter column on journal entries that match this analytic account.This " +"filter is combined with a AND with the report-level filters and cannot be " +"modified in the preview." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Filters" +msgstr "Filtros" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__fix +msgid "Fixed dates" +msgstr "Datas fixas" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Font" +msgstr "Fonte" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size +msgid "Font Size" +msgstr "Tamanho da Fonte" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_size_inherit +msgid "Font Size Inherit" +msgstr "Tamanho da Fonte Herdada" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style +msgid "Font Style" +msgstr "Estilo da Fonte" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_style_inherit +msgid "Font Style Inherit" +msgstr "Estilo da Fonte Herdada" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight +msgid "Font Weight" +msgstr "Espessura da Fonte" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__font_weight_inherit +msgid "Font Weight Inherit" +msgstr "Espessura da Fonte Herdada" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Forces the start date to Jan 1st of the relevant year" +msgstr "Force a data inicial para 1 Jan do respectivo ano" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_from +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_from +msgid "From" +msgstr "De" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_from +msgid "From (computed)" +msgstr "De (computado)" + +#. module: mis_builder +#: code:addons/mis_builder/report/mis_report_instance_xlsx.py:0 +#, python-format +msgid "Generated on {} at {}" +msgstr "Gerado em {} às {}" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "Help (for KPI expressions)" +msgstr "Ajuda (para expressões KPI)" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always +msgid "Hide Always" +msgstr "Sempre Esconder" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_always_inherit +msgid "Hide Always Inherit" +msgstr "Sempre Esconder Herdado" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__hide_analytic_filters +msgid "Hide Analytic Filters" +msgstr "Esconder Filtros Analíticos" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty +msgid "Hide Empty" +msgstr "Esconder Vazio" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__hide_empty_inherit +msgid "Hide Empty Inherit" +msgstr "Esconder Vazio Herdado" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__id +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__id +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin__id +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx__id +msgid "ID" +msgstr "ID" + +#. module: mis_builder +#: code:addons/mis_builder/models/aep.py:0 +#, python-format +msgid "" +"If currency_id is not provided, all companies must have the same currency." +msgstr "" +"Se id da moeda(currency_id) não é fornecido, todas as empresas devem possuir " +"a mesma moeda." + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Indent" +msgstr "Endentação" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level +msgid "Indent Level" +msgstr "Nível de endentação" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__indent_level_inherit +msgid "Indent Level Inherit" +msgstr "Herança do Nível de Recuo" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "Indent level must be greater than or equal to 0" +msgstr "Nível de recuo deve ser maior ou igual a 0" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__italic +msgid "Italic" +msgstr "Itálico" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__kpi_expression_id +msgid "KPI" +msgstr "KPI" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" has type {} while a tuple was expected.\n" +"\n" +"This can be fixed by either:\n" +"\t- Changing the KPI value to a tuple of length {}\n" +"or\n" +"\t- Changing the KPI to `multi` mode and giving an explicit value for each " +"sub-KPI." +msgstr "" +"KPI \"{}\" possui o tipo {} enquanto uma tupla era o esperado.\n" +"\n" +"Isso pode ser corrigido assim:\n" +"\t- Alterando o valor do KPI para uma tupla de comprimento {}\n" +"ou\n" +"\t- Alterando o KPI para modo `multi` e dando um valor explícito para cada " +"sub-KPI." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, python-format +msgid "" +"KPI \"{}\" is valued as a tuple of length {} while a tuple of length {} is " +"expected." +msgstr "" +"O KPI \"{}\" esta definido como uma tupla de comprimento {} enquanto uma " +"tupla de comprimento {} era esperada." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq1 +msgid "KPI Sequence" +msgstr "KPI sequencia" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, fuzzy, python-format +msgid "KPI name ({}) must be a valid python identifier" +msgstr "O nome deve ser um identificador python válido" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__kpi_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "KPI's" +msgstr "KPI's" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report__all_kpi_ids +msgid "KPIs of this report and subreports." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__kpi_id +msgid "Kpi" +msgstr "Kpi" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__name +msgid "Label" +msgstr "Campo (Rotulo)" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__landscape_pdf +msgid "Landscape PDF" +msgstr "PDF em modo paisagem" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard____last_update +#: model:ir.model.fields,field_description:mis_builder.field_ir_actions_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi____last_update +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport____last_update +#: model:ir.model.fields,field_description:mis_builder.field_prorata_read_group_mixin____last_update +#: model:ir.model.fields,field_description:mis_builder.field_report_mis_builder_mis_report_instance_xlsx____last_update +msgid "Last Modified on" +msgstr "Última atualização em" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.last_mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.last_wizard_mis_report_instance_view_menu +msgid "Last Reports Generated" +msgstr "Últimos relatórios gerados" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_uid +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_uid +msgid "Last Updated by" +msgstr "Última atualização por" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__write_date +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__write_date +msgid "Last Updated on" +msgstr "Última atualização em" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Layout" +msgstr "Layout" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_report_mis_builder_mis_report_instance_xlsx +#, fuzzy +msgid "MIS Builder XLSX report" +msgstr "Instância de Relatório XLS" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_kpi_data +msgid "MIS Kpi Data Abtract class" +msgstr "MIS Kpi Data Abtract class" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "MIS Report" +msgstr "Relatório SIG" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subreport +#, fuzzy +msgid "MIS Report - Sub Reports Relation" +msgstr "Resultado do Relatório SIG" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_add_mis_report_instance_dashboard_wizard +msgid "MIS Report Add to Dashboard Wizard" +msgstr "Relatório SIG Add ao Assistente de Dashboard" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "MIS Report Instance" +msgstr "Instância de Relatório SIG" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period +msgid "MIS Report Instance Period" +msgstr "Período da Instância do Relatório SIG" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_instance_period_sum +msgid "MIS Report Instance Period Sum" +msgstr "Soma do Período da Instância do Relatório SIG" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "MIS Report Instances" +msgstr "Instâncias do Relatório SIG" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "MIS Report KPI" +msgstr "Relatório KPI" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_kpi_expression +msgid "MIS Report KPI Expression" +msgstr "Expressão do KPI do Relatório SIG" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_query +msgid "MIS Report Query" +msgstr "Consulta do Relatório SIG" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_result_view_form +msgid "MIS Report Result" +msgstr "Resultado do Relatório SIG" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_style +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "MIS Report Style" +msgstr "Estilo do Relatório SIG" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_style_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_style_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_tree +msgid "MIS Report Styles" +msgstr "Estilos do Relatório SIG" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report_subkpi +msgid "MIS Report Sub-KPI" +msgstr "Sub-KPI do Relatório SIG" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_mis_report +msgid "MIS Report Template" +msgstr "Modelo do Relatório SIG" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_view_menu +msgid "MIS Report Templates" +msgstr "Modelos do Relatório SIG" + +#. module: mis_builder +#: model:ir.ui.menu,name:mis_builder.mis_report_conf_menu +#: model:ir.ui.menu,name:mis_builder.mis_report_finance_menu +msgid "MIS Reporting" +msgstr "Relatórios SIG" + +#. module: mis_builder +#: model:ir.actions.act_window,name:mis_builder.mis_report_instance_view_action +#: model:ir.ui.menu,name:mis_builder.mis_report_instance_view_menu +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_tree +msgid "MIS Reports" +msgstr "Relatórios SIG" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.qweb_pdf_export +msgid "MIS report instance QWEB PDF report" +msgstr "Instância de Relatório QWEB PDF" + +#. module: mis_builder +#: model:ir.actions.report,name:mis_builder.xls_export +msgid "MIS report instance XLS report" +msgstr "Instância de Relatório XLS" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__max +#, python-format +msgid "Max" +msgstr "Max" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__min +#, python-format +msgid "Min" +msgstr "Min" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__mode +msgid "Mode" +msgstr "Modo" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__model_id +msgid "Model" +msgstr "Modelo" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__m +#, python-format +msgid "Month" +msgstr "Mês" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__move_lines_source +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_id +msgid "Move lines source" +msgstr "Mover fonte de linhas" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_aml_model_name +msgid "Move lines source model name" +msgstr "Mover nome do modelo da fonte das linhas" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__multi +msgid "Multi" +msgstr "Multi" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__multi_company +msgid "Multiple companies" +msgstr "Múltiplas empresas" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_add_mis_report_instance_dashboard_wizard__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__name +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__name +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +msgid "Name" +msgstr "Nome" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__none +msgid "No date filter" +msgstr "Sem filtro de data" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "No date filter is allowed for this source in column %s." +msgstr "Nenhum filtro de data é permitido para esta fonte na coluna %s." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__none +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__none +#, python-format +msgid "None" +msgstr "Nada" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_style__normal +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_weight__nornal +msgid "Normal" +msgstr "Normal" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Number" +msgstr "Número" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__duration +msgid "Number of periods" +msgstr "Número de períodos" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__num +#, python-format +msgid "Numeric" +msgstr "Numérico" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__offset +msgid "Offset" +msgstr "Deslocamento" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance_period__offset +msgid "Offset from current period" +msgstr "Deslocamento a partir do período atual" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__period_id +msgid "Parent column" +msgstr "Coluna Pai" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__compare_method__pct +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__pct +#, python-format +msgid "Percentage" +msgstr "Percentagem" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_name_unique +msgid "Period name should be unique by report" +msgstr "Nome do período deve ser único por relatório" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__type +msgid "Period type" +msgstr "Tipo do período" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__period_ids +msgid "Periods" +msgstr "Períodos" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__pivot_date +msgid "Pivot date" +msgstr "Data do Pivot" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "Please provide both columns to compare in %s." +msgstr "Por favor forneça ambas as colunas para comparar em %s." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix +msgid "Prefix" +msgstr "Prefixo" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__prefix_inherit +msgid "Prefix Inherit" +msgstr "Herança de Prefixo" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Preview" +msgstr "Visualizar" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +#, python-format +msgid "Print" +msgstr "Imprimir" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__query_ids +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Queries" +msgstr "Consultas" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__query_company_ids +msgid "Query Company" +msgstr "Empresa de Consulta" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, fuzzy, python-format +msgid "Query name ({}) must be valid python identifier" +msgstr "O nome deve ser um identificador python válido" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Refresh" +msgstr "Atualizar" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__mode__relative +msgid "Relative to report base date" +msgstr "Relativo à data base do relatório" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_query__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__report_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__report_id +msgid "Report" +msgstr "Relatório" + +#. module: mis_builder +#: model:ir.model,name:mis_builder.model_ir_actions_report +msgid "Report Action" +msgstr "Ação do Relatório" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__report_instance_id +msgid "Report Instance" +msgstr "Instância do Relatório" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__date +msgid "Report base date (leave empty to use current date)" +msgstr "Data Base do Relatório (deixar em branco para usar data atual)" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__dp +msgid "Rounding" +msgstr "Arredondamento" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Rounding inherit" +msgstr "Herança de Arredondamento" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "Save" +msgstr "Salvar" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__company_ids +msgid "Select companies for which data will be searched." +msgstr "Selecione empresas para as quais os dados serão pesquisados." + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_instance__currency_id +msgid "" +"Select target currency for the report. Required if companies have different " +"currencies." +msgstr "" +"Selecione a moeda de destino para o relatório. Necessário se as empresas " +"tiverem moedas diferentes." + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__sequence +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subkpi__sequence +msgid "Sequence" +msgstr "Sequência" + +#. module: mis_builder +#. openerp-web +#: code:addons/mis_builder/static/src/xml/mis_report_widget.xml:0 +#, python-format +msgid "Settings" +msgstr "Configurações" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_subreport_unique +msgid "" +"Should not include the same report more than once as sub report of a given " +"report" +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period_sum__sign +msgid "Sign" +msgstr "Assinar" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_period_view_form +msgid "Source" +msgstr "Fonte" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__type__str +#, python-format +msgid "String" +msgstr "Texto" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__style_id +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_id +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Style" +msgstr "Estilo" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__style_expression +msgid "Style expression" +msgstr "Expressão de Estilo" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__auto_expand_accounts_style_id +msgid "Style for account detail rows" +msgstr "Estilo para linhas de detalhes da conta" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__name +msgid "Style name" +msgstr "Nome do estilo" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subkpi_ids +msgid "Sub KPI" +msgstr "Sub KPI" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__subkpi_ids +msgid "Sub KPI Filter" +msgstr "Filtro do Sub KPI" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_kpi_expression_subkpi_kpi_unique +msgid "Sub KPI must be used once and only once for each KPI" +msgstr "O sub KPI deve ser usado uma vez e apenas uma vez para cada KPI" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +msgid "Sub KPI's" +msgstr "Sub KPI's" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_form +#, fuzzy +msgid "Sub Reports" +msgstr "Relatórios SIG" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report__subreport_ids +#, fuzzy +msgid "Sub reports" +msgstr "Relatórios SIG" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__seq2 +msgid "Sub-KPI Sequence" +msgstr "Sequência do Sub-KPI" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#, fuzzy, python-format +msgid "Sub-KPI name ({}) must be a valid python identifier" +msgstr "O nome deve ser um identificador python válido" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi_expression__subkpi_id +msgid "Subkpi" +msgstr "Subkpi" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_subreport__subreport_id +#, fuzzy +msgid "Subreport" +msgstr "Relatório" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, python-format +msgid "Subreport loop detected" +msgstr "" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_subreport.py:0 +#, fuzzy, python-format +msgid "Subreport name ({}) must be a valid python identifier" +msgstr "O nome deve ser um identificador python válido" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_subreport_name_unique +#, fuzzy +msgid "Subreport name should be unique by report" +msgstr "Nome do período deve ser único por relatório" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix +msgid "Suffix" +msgstr "Sufixo" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__suffix_inherit +msgid "Suffix Inherit" +msgstr "Herança do Sufixo" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_kpi__accumulation_method__sum +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_query__aggregate__sum +#, python-format +msgid "Sum" +msgstr "Soma" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_sumcol_accdet +msgid "Sum account details" +msgstr "Somar detalhes da conta" + +#. module: mis_builder +#: code:addons/mis_builder/models/kpimatrix.py:0 +#, python-format +msgid "" +"Sum cannot be computed in column {} because the columns to sum have no " +"common subkpis" +msgstr "" +"A soma não pode ser calculada na coluna {} porque as colunas a serem somadas " +"não têm possuem subkpis comuns" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__source__sumcol +msgid "Sum columns" +msgstr "Somar colunas" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__target_move +msgid "Target Moves" +msgstr "Movimentos Alvo" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_form +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_view_tree +msgid "Template" +msgstr "Modelo" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__temporary +msgid "Temporary" +msgstr "Temporário" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_style__color +msgid "Text color" +msgstr "Cor do texto" + +#. module: mis_builder +#: model:ir.model.fields,help:mis_builder.field_mis_report_style__color +msgid "Text color in valid RGB code (from #000000 to #FFFFFF)" +msgstr "Cor do texto em código RGB válido (de #000000 a #FFFFFF)" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" account selector\n" +" is a like expression on the " +"account code (eg\n" +" 70%, etc)." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The\n" +" journal items domain\n" +" is an Odoo domain filter on " +"journal items." +msgstr "" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_view_kpi_form +msgid "" +"The following special elements are recognized in\n" +" the expressions to compute " +"accounting data:\n" +" \n" +" {bal|crd|deb|pbal|nbal}{pieu}" +"[account\n" +" selector][journal items domain]\n" +" \n" +" ." +msgstr "" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_kpi_data__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance__date_to +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__manual_date_to +msgid "To" +msgstr "Para" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__date_to +msgid "To (computed)" +msgstr "Para (computado)" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_kpi_data.py:0 +#, python-format +msgid "Unexpected accumulation method %s for %s." +msgstr "Método de acumulação %s não esperado para %s." + +#. module: mis_builder +#: code:addons/mis_builder/models/prorata_read_group_mixin.py:0 +#, python-format +msgid "Unsupported operator %s for searching on date" +msgstr "" + +#. module: mis_builder +#: model:ir.actions.server,name:mis_builder.ir_cron_vacuum_temp_reports_ir_actions_server +#: model:ir.cron,cron_name:mis_builder.ir_cron_vacuum_temp_reports +#: model:ir.cron,name:mis_builder.ir_cron_vacuum_temp_reports +msgid "Vacuum temporary reports" +msgstr "Relatórios temporários de vácuo" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__valid +msgid "Valid" +msgstr "Válido" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_kpi__type +msgid "Value type" +msgstr "Tipo de valor" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_style_view_form +msgid "Visibility" +msgstr "Visibilidade" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__w +#, python-format +msgid "Week" +msgstr "Semana" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_duration +msgid "Wrong duration, it must be positive!" +msgstr "Duração incorreta, deve ser positiva!" + +#. module: mis_builder +#: model:ir.model.constraint,message:mis_builder.constraint_mis_report_instance_period_normalize_factor +msgid "Wrong normalize factor, it must be positive!" +msgstr "Fator de normalização incorreto, deve ser positivo!" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_instance_period__type__y +#, python-format +msgid "Year" +msgstr "Ano" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__is_ytd +msgid "Year to date" +msgstr "No acumulado do ano" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "You cannot sum period %s with itself." +msgstr "Você não pode somar o período %s com ele mesmo." + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_instance.py:0 +#, python-format +msgid "from %s to %s" +msgstr "de %s até %s" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__large +msgid "large" +msgstr "grande" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__medium +msgid "medium" +msgstr "médio" + +#. module: mis_builder +#: model_terms:ir.ui.view,arch_db:mis_builder.mis_report_instance_add_to_dashboard_form_view +#: model_terms:ir.ui.view,arch_db:mis_builder.wizard_mis_report_instance_view_form +msgid "or" +msgstr "ou" + +#. module: mis_builder +#: code:addons/mis_builder/models/mis_report_style.py:0 +#, python-format +msgid "pp" +msgstr "pp" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__small +msgid "small" +msgstr "pequeno" + +#. module: mis_builder +#: model:ir.model.fields,field_description:mis_builder.field_mis_report_instance_period__source_cmpcol_from_id +msgid "versus" +msgstr "versus" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-large +msgid "x-large" +msgstr "muito grande" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__x-small +msgid "x-small" +msgstr "muito pequeno" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-large +msgid "xx-large" +msgstr "grandíssimo" + +#. module: mis_builder +#: model:ir.model.fields.selection,name:mis_builder.selection__mis_report_style__font_size__xx-small +msgid "xx-small" +msgstr "Pequeníssimo" + +#~ msgid "" +#~ "AccountingNone: a null value that behaves as 0 in arithmetic " +#~ "operations." +#~ msgstr "" +#~ "AccountingNone: um valor nulo que se comporta como 0 em operações " +#~ "aritméticas." + +#~ msgid "" +#~ "bal, crd, deb, pbal, nbal: balance, debit, credit, positive " +#~ "balance, negative balance." +#~ msgstr "" +#~ "bal, crd, deb, pbal, nbal: saldo, débito, crédito, balanço " +#~ "positivo, balanço negativo." + +#~ msgid "" +#~ "bal[70]: variation of the balance of account 70 over the period " +#~ "(it is the same as balp[70]." +#~ msgstr "" +#~ "bal[70]: variação do balanço da conta 70 ao longo do período (é o " +#~ "mesmo que balp [70]." + +#~ msgid "" +#~ "bale[1%]: balance of accounts starting with 1 at end of period." +#~ msgstr "" +#~ "bale[1%]: balanço de contas iniciando com 1 no final do período." + +#~ msgid "bali[70,60]: initial balance of accounts 70 and 60." +#~ msgstr "bali[70,60]: balanço inicial das contas 70 e 60." + +#~ msgid "" +#~ "balp[('user_type_id', '=', ref('account.data_account_type_receivable')." +#~ "id)][]: variation of the balance of all receivable accounts over the " +#~ "period." +#~ msgstr "" +#~ "balp[('user_type_id', '=', ref('account.data_account_type_receivable')." +#~ "id)][]: variação do balanço de todas as contas a receber durante o " +#~ "período." + +#~ msgid "" +#~ "balp[][('tax_line_id.tag_ids', '=', ref('l10n_be.tax_tag_56').id)]: balance of move lines related to tax grid 56." +#~ msgstr "" +#~ "balp[][('tax_line_id.tag_ids', '=', ref('l10n_be.tax_tag_56').id)]: saldo das linhas de movimento relacionadas ao imposto 56." + +#~ msgid "" +#~ "balu[]: (u for unallocated) is a special expression that shows the " +#~ "unallocated profit/loss of previous\n" +#~ " fiscal years." +#~ msgstr "" +#~ "balu[]: (u para não alocado) é uma expressão especial que exibe o " +#~ "lucro / perda não alocado de\n" +#~ " anos fiscais." + +#~ msgid "" +#~ "crdp[40%]: sum of all credits on accounts starting with 40 during " +#~ "the period." +#~ msgstr "" +#~ "crdp[40%]: soma de todos os créditos em contas iniciando com 40 " +#~ "durante o periodo." + +#~ msgid "date_from, date_to: beginning and end date of the period." +#~ msgstr "date_from, date_to: data inicial e final do período." + +#~ msgid "datetime, datetime, dateutil: the python modules." +#~ msgstr "datetime, datetime, dateutil: os módulos python." + +#~ msgid "" +#~ "debp[55%][('journal_id.code', '=', 'BNK1')]: sum of all debits on " +#~ "accounts 55 and journal BNK1 during the period." +#~ msgstr "" +#~ "debp[55%][('journal_id.code', '=', 'BNK1')]: soma de todos os " +#~ "débitos na conta 55 e diário BNK1 durante o período." + +#~ msgid "" +#~ "p, i, e: respectively variation over the period, initial balance, " +#~ "ending balance" +#~ msgstr "" +#~ "p, i, e: variação respectiva ao longo do período, balanço inicial, " +#~ "balanço final" + +#~ msgid "" +#~ "pbale[55%]: sum of all ending balances of accounts starting with " +#~ "55 whose\n" +#~ " ending balance is positive." +#~ msgstr "" +#~ "pbale[55%]: soma de todos os balanços finais de contas iniciando " +#~ "com 55 as quais\n" +#~ " o balanço final é positivo." + +#~ msgid "" +#~ "sum, min, max, len, avg: behave as expected, very similar to the " +#~ "python builtins." +#~ msgstr "" +#~ "sum, min, max, len, avg: comporta-se como o experado, muito " +#~ "similar aos builtins do python." + +#~ msgid "" +#~ "Additionally following variables are available in the evaluation context:" +#~ msgstr "" +#~ "Adicionalmente as seguintes variáveis estão disponíveis no contexto de " +#~ "avaliação:" + +#~ msgid "" +#~ "Expressions can involve other KPI, sub KPI and query results by name (eg " +#~ "kpi1 + kpi2, kpi2.subkpi1, query1.field1)." +#~ msgstr "" +#~ "Expressões podem envolver outros KPI, sub KPI e resultados de consultas " +#~ "por nome (ex: kpi1 + kpi2, kpi2.subkpi1, query1.field1)." + +#~ msgid "" +#~ "The account selector is a like expression on the account code (eg " +#~ "70%, etc)." +#~ msgstr "" +#~ "O seletor de conta é uma expressão semelhante no código da conta " +#~ "(ex 70%, etc)." + +#~ msgid "" +#~ "The journal items domain is an Odoo domain filter on journal items." +#~ msgstr "" +#~ "O domínio de itens do diário é um filtro de domínio do Odoo em " +#~ "itens de diário." + +#~ msgid "" +#~ "The following special elements are recognized in the expressions to " +#~ "compute accounting data:\n" +#~ " {bal|crd|deb|pbal|nbal}" +#~ "{pieu}[account selector][journal items domain]." +#~ msgstr "" +#~ "Os seguintes elementos especiais são reconhecidos na expressão para " +#~ "cálculo de dados da conta:\n" +#~ " {bal|crd|deb|pbal|nbal}" +#~ "{pieu}[account selector][journal items domain]." + +#~ msgid "MIS Budget" +#~ msgstr "Orçamento SIG" + +#~ msgid "report.mis_builder.mis_report_instance_xlsx" +#~ msgstr "report.mis_builder.mis_report_instance_xlsx" diff --git a/odex25_accounting/mis_builder/migrations/8.0.2.0.0/post-migration.py b/odex25_accounting/mis_builder/migrations/8.0.2.0.0/post-migration.py new file mode 100644 index 000000000..421bb33de --- /dev/null +++ b/odex25_accounting/mis_builder/migrations/8.0.2.0.0/post-migration.py @@ -0,0 +1,29 @@ +# Copyright 2017 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + + +def migrate(cr, version): + cr.execute( + """ + INSERT INTO mis_report_kpi_expression + (create_uid, create_date, write_uid, write_date, + kpi_id, name, sequence) + SELECT create_uid, create_date, write_uid, write_date, + id, old_expression, sequence + FROM mis_report_kpi + """ + ) + cr.execute( + """ + ALTER TABLE mis_report_kpi + DROP COLUMN old_expression + """ + ) + # set default mode to relative for existing periods + # as it was the only mode in previous versions + cr.execute( + """ + UPDATE mis_report_instance_period + SET mode='relative' + """ + ) diff --git a/odex25_accounting/mis_builder/migrations/8.0.2.0.0/pre-migration.py b/odex25_accounting/mis_builder/migrations/8.0.2.0.0/pre-migration.py new file mode 100644 index 000000000..83fc4b5da --- /dev/null +++ b/odex25_accounting/mis_builder/migrations/8.0.2.0.0/pre-migration.py @@ -0,0 +1,20 @@ +# Copyright 2017 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + + +def migrate(cr, version): + cr.execute( + """ + ALTER TABLE mis_report_kpi + RENAME COLUMN expression TO old_expression + """ + ) + # this migration to date_range type is partial, + # actual date ranges needs to be created manually + cr.execute( + """ + UPDATE mis_report_instance_period + SET type='date_range' + WHERE type='fp' + """ + ) diff --git a/odex25_accounting/mis_builder/models/__init__.py b/odex25_accounting/mis_builder/models/__init__.py new file mode 100644 index 000000000..af7bfa7e5 --- /dev/null +++ b/odex25_accounting/mis_builder/models/__init__.py @@ -0,0 +1,10 @@ +# Copyright 2014 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from . import mis_report +from . import mis_report_subreport +from . import mis_report_instance +from . import mis_report_style +from . import aep +from . import mis_kpi_data +from . import prorata_read_group_mixin diff --git a/odex25_accounting/mis_builder/models/accounting_none.py b/odex25_accounting/mis_builder/models/accounting_none.py new file mode 100644 index 000000000..699bad9a9 --- /dev/null +++ b/odex25_accounting/mis_builder/models/accounting_none.py @@ -0,0 +1,215 @@ +# Copyright 2016 Thomas Binsfeld +# Copyright 2016 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +""" +Provides the AccountingNone singleton. + +AccountingNone is a null value that dissolves in basic arithmetic operations, +as illustrated in the examples below. In comparisons, AccountingNone behaves +the same as zero. + +>>> 1 + 1 +2 +>>> 1 + AccountingNone +1 +>>> AccountingNone + 1 +1 +>>> AccountingNone + None +AccountingNone +>>> None + AccountingNone +AccountingNone +>>> +AccountingNone +AccountingNone +>>> -AccountingNone +AccountingNone +>>> -(AccountingNone) +AccountingNone +>>> AccountingNone - 1 +-1 +>>> 1 - AccountingNone +1 +>>> abs(AccountingNone) +AccountingNone +>>> AccountingNone - None +AccountingNone +>>> None - AccountingNone +AccountingNone +>>> AccountingNone / 2 +0.0 +>>> 2 / AccountingNone +Traceback (most recent call last): + ... +ZeroDivisionError +>>> AccountingNone / AccountingNone +AccountingNone +>>> AccountingNone // 2 +0.0 +>>> 2 // AccountingNone +Traceback (most recent call last): + ... +ZeroDivisionError +>>> AccountingNone // AccountingNone +AccountingNone +>>> AccountingNone * 2 +0.0 +>>> 2 * AccountingNone +0.0 +>>> AccountingNone * AccountingNone +AccountingNone +>>> AccountingNone * None +AccountingNone +>>> None * AccountingNone +AccountingNone +>>> str(AccountingNone) +'' +>>> bool(AccountingNone) +False +>>> AccountingNone > 0 +False +>>> AccountingNone < 0 +False +>>> AccountingNone < 1 +True +>>> AccountingNone > 1 +False +>>> 0 < AccountingNone +False +>>> 0 > AccountingNone +False +>>> 1 < AccountingNone +False +>>> 1 > AccountingNone +True +>>> AccountingNone == 0 +True +>>> AccountingNone == 0.0 +True +>>> AccountingNone == None +True +>>> AccountingNone >= AccountingNone +True +>>> AccountingNone <= AccountingNone +True +>>> round(AccountingNone, 2) +0.0 +>>> float(AccountingNone) +0.0 +>>> int(AccountingNone) +0 +""" + +__all__ = ["AccountingNone"] + + +class AccountingNoneType(object): + def __add__(self, other): + if other is None: + return AccountingNone + return other + + __radd__ = __add__ + + def __sub__(self, other): + if other is None: + return AccountingNone + return -other + + def __rsub__(self, other): + if other is None: + return AccountingNone + return other + + def __iadd__(self, other): + if other is None: + return AccountingNone + return other + + def __isub__(self, other): + if other is None: + return AccountingNone + return -other + + def __abs__(self): + return self + + def __pos__(self): + return self + + def __neg__(self): + return self + + def __div__(self, other): + if other is AccountingNone: + return AccountingNone + return 0.0 + + def __rdiv__(self, other): + raise ZeroDivisionError + + def __floordiv__(self, other): + if other is AccountingNone: + return AccountingNone + return 0.0 + + def __rfloordiv__(self, other): + raise ZeroDivisionError + + def __truediv__(self, other): + if other is AccountingNone: + return AccountingNone + return 0.0 + + def __rtruediv__(self, other): + raise ZeroDivisionError + + def __mul__(self, other): + if other is None or other is AccountingNone: + return AccountingNone + return 0.0 + + __rmul__ = __mul__ + + def __repr__(self): + return "AccountingNone" + + def __str__(self): + return "" + + def __nonzero__(self): + return False + + def __bool__(self): + return False + + def __eq__(self, other): + return other == 0 or other is None or other is AccountingNone + + def __lt__(self, other): + return other > 0 + + def __gt__(self, other): + return other < 0 + + def __le__(self, other): + return other >= 0 + + def __ge__(self, other): + return other <= 0 + + def __float__(self): + return 0.0 + + def __int__(self): + return 0 + + def __round__(self, ndigits): + return 0.0 + + +AccountingNone = AccountingNoneType() + + +if __name__ == "__main__": # pragma: no cover + import doctest + + doctest.testmod() diff --git a/odex25_accounting/mis_builder/models/aep.py b/odex25_accounting/mis_builder/models/aep.py new file mode 100644 index 000000000..468cceb26 --- /dev/null +++ b/odex25_accounting/mis_builder/models/aep.py @@ -0,0 +1,549 @@ +# Copyright 2014 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import re +from collections import defaultdict + +from odoo import _, fields +from odoo.exceptions import UserError +from odoo.models import expression +from odoo.tools.float_utils import float_is_zero +from odoo.tools.safe_eval import datetime, dateutil, safe_eval, time + +from .accounting_none import AccountingNone + +try: + import itertools.izip as zip +except ImportError: + pass # python 3 + + +_DOMAIN_START_RE = re.compile(r"\(|(['\"])[!&|]\1") + + +def _is_domain(s): + """ Test if a string looks like an Odoo domain """ + return _DOMAIN_START_RE.match(s) + + +class AccountingExpressionProcessor(object): + """Processor for accounting expressions. + + Expressions of the form [accounts][optional move line domain] + are supported, where: + * field is bal, crd, deb, pbal (positive balances only), + nbal (negative balance only) + * mode is i (initial balance), e (ending balance), + p (moves over period) + * there is also a special u mode (unallocated P&L) which computes + the sum from the beginning until the beginning of the fiscal year + of the period; it is only meaningful for P&L accounts + * accounts is a list of accounts, possibly containing % wildcards, + or a domain expression on account.account + * an optional domain on move lines allowing filters on eg analytic + accounts or journal + + Examples: + * bal[70]: variation of the balance of moves on account 70 + over the period (it is the same as balp[70]); + * bali[70,60]: balance of accounts 70 and 60 at the start of period; + * bale[1%]: balance of accounts starting with 1 at end of period. + + How to use: + * repeatedly invoke parse_expr() for each expression containing + accounting variables as described above; this lets the processor + group domains and modes and accounts; + * when all expressions have been parsed, invoke done_parsing() + to notify the processor that it can prepare to query (mainly + search all accounts - children, consolidation - that will need to + be queried; + * for each period, call do_queries(), then call replace_expr() for each + expression to replace accounting variables with their resulting value + for the given period. + + How it works: + * by accumulating the expressions before hand, it ensures to do the + strict minimum number of queries to the database (for each period, + one query per domain and mode); + * it queries using the orm read_group which reduces to a query with + sum on debit and credit and group by on account_id and company_id, + (note: it seems the orm then does one query per account to fetch + the account name...); + * additionally, one query per view/consolidation account is done to + discover the children accounts. + """ + + MODE_VARIATION = "p" + MODE_INITIAL = "i" + MODE_END = "e" + MODE_UNALLOCATED = "u" + + _ACC_RE = re.compile( + r"(?P\bbal|\bpbal|\bnbal|\bcrd|\bdeb)" + r"(?P[piseu])?" + r"\s*" + r"(?P_[a-zA-Z0-9]+|\[.*?\])" + r"\s*" + r"(?P\[.*?\])?" + ) + + def __init__(self, companies, currency=None, account_model="account.account"): + self.env = companies.env + self.companies = companies + if not currency: + self.currency = companies.mapped("currency_id") + if len(self.currency) > 1: + raise UserError( + _( + "If currency_id is not provided, " + "all companies must have the same currency." + ) + ) + else: + self.currency = currency + self.dp = self.currency.decimal_places + # before done_parsing: {(ml_domain, mode): set(acc_domain)} + # after done_parsing: {(ml_domain, mode): list(account_ids)} + self._map_account_ids = defaultdict(set) + # {account_domain: set(account_ids)} + self._account_ids_by_acc_domain = defaultdict(set) + # smart ending balance (returns AccountingNone if there + # are no moves in period and 0 initial balance), implies + # a first query to get the initial balance and another + # to get the variation, so it's a bit slower + self.smart_end = True + # Account model + self._account_model = self.env[account_model].with_context(active_test=False) + + def _account_codes_to_domain(self, account_codes): + """Convert a comma separated list of account codes + (possibly with wildcards) to a domain on account.account. + """ + elems = [] + for account_code in account_codes.split(","): + account_code = account_code.strip() + if "%" in account_code: + elems.append([("code", "=like", account_code)]) + else: + elems.append([("code", "=", account_code)]) + return tuple(expression.OR(elems)) + + def _parse_match_object(self, mo): + """Split a match object corresponding to an accounting variable + + Returns field, mode, account domain, move line domain. + """ + domain_eval_context = { + "ref": self.env.ref, + "user": self.env.user, + "time": time, + "datetime": datetime, + "dateutil": dateutil, + } + field, mode, account_sel, ml_domain = mo.groups() + # handle some legacy modes + if not mode: + mode = self.MODE_VARIATION + elif mode == "s": + mode = self.MODE_END + # convert account selector to account domain + if account_sel.startswith("_"): + # legacy bal_NNN% + acc_domain = self._account_codes_to_domain(account_sel[1:]) + else: + assert account_sel[0] == "[" and account_sel[-1] == "]" + inner_account_sel = account_sel[1:-1].strip() + if not inner_account_sel: + # empty selector: select all accounts + acc_domain = tuple() + elif _is_domain(inner_account_sel): + # account selector is a domain + acc_domain = tuple(safe_eval(account_sel, domain_eval_context)) + else: + # account selector is a list of account codes + acc_domain = self._account_codes_to_domain(inner_account_sel) + # move line domain + if ml_domain: + assert ml_domain[0] == "[" and ml_domain[-1] == "]" + ml_domain = tuple(safe_eval(ml_domain, domain_eval_context)) + else: + ml_domain = tuple() + return field, mode, acc_domain, ml_domain + + def parse_expr(self, expr): + """Parse an expression, extracting accounting variables. + + Move line domains and account selectors are extracted and + stored in the map so when all expressions have been parsed, + we know which account domains to query for each move line domain + and mode. + """ + for mo in self._ACC_RE.finditer(expr): + _, mode, acc_domain, ml_domain = self._parse_match_object(mo) + if mode == self.MODE_END and self.smart_end: + modes = (self.MODE_INITIAL, self.MODE_VARIATION, self.MODE_END) + else: + modes = (mode,) + for mode in modes: + key = (ml_domain, mode) + self._map_account_ids[key].add(acc_domain) + + def done_parsing(self): + """ Replace account domains by account ids in map """ + for key, acc_domains in self._map_account_ids.items(): + all_account_ids = set() + for acc_domain in acc_domains: + acc_domain_with_company = expression.AND( + [acc_domain, [("company_id", "in", self.companies.ids)]] + ) + account_ids = self._account_model.search(acc_domain_with_company).ids + self._account_ids_by_acc_domain[acc_domain].update(account_ids) + all_account_ids.update(account_ids) + self._map_account_ids[key] = list(all_account_ids) + + @classmethod + def has_account_var(cls, expr): + """Test if an string contains an accounting variable.""" + return bool(cls._ACC_RE.search(expr)) + + def get_account_ids_for_expr(self, expr): + """Get a set of account ids that are involved in an expression. + + Prerequisite: done_parsing() must have been invoked. + """ + account_ids = set() + for mo in self._ACC_RE.finditer(expr): + field, mode, acc_domain, ml_domain = self._parse_match_object(mo) + account_ids.update(self._account_ids_by_acc_domain[acc_domain]) + return account_ids + + def get_aml_domain_for_expr( + self, expr, date_from, date_to, target_move, account_id=None + ): + """Get a domain on account.move.line for an expression. + + Prerequisite: done_parsing() must have been invoked. + + Returns a domain that can be used to search on account.move.line. + """ + aml_domains = [] + date_domain_by_mode = {} + for mo in self._ACC_RE.finditer(expr): + field, mode, acc_domain, ml_domain = self._parse_match_object(mo) + aml_domain = list(ml_domain) + account_ids = set() + account_ids.update(self._account_ids_by_acc_domain[acc_domain]) + if not account_id: + aml_domain.append(("account_id", "in", tuple(account_ids))) + else: + # filter on account_id + if account_id in account_ids: + aml_domain.append(("account_id", "=", account_id)) + else: + continue + if field == "crd": + aml_domain.append(("credit", "<>", 0.0)) + elif field == "deb": + aml_domain.append(("debit", "<>", 0.0)) + aml_domains.append(expression.normalize_domain(aml_domain)) + if mode not in date_domain_by_mode: + date_domain_by_mode[mode] = self.get_aml_domain_for_dates( + date_from, date_to, mode, target_move + ) + assert aml_domains + # TODO we could do this for more precision: + # AND(OR(aml_domains[mode]), date_domain[mode]) for each mode + return expression.OR(aml_domains) + expression.OR(date_domain_by_mode.values()) + + def get_aml_domain_for_dates(self, date_from, date_to, mode, target_move): + if mode == self.MODE_VARIATION: + domain = [("date", ">=", date_from), ("date", "<=", date_to)] + elif mode in (self.MODE_INITIAL, self.MODE_END): + # for income and expense account, sum from the beginning + # of the current fiscal year only, for balance sheet accounts + # sum from the beginning of time + date_from_date = fields.Date.from_string(date_from) + # TODO this takes the fy from the first company + # make that user controllable (nice to have)? + fy_date_from = self.companies[0].compute_fiscalyear_dates(date_from_date)[ + "date_from" + ] + domain = [ + "|", + ("date", ">=", fields.Date.to_string(fy_date_from)), + ("account_id.user_type_id.include_initial_balance", "=", True), + ] + if mode == self.MODE_INITIAL: + domain.append(("date", "<", date_from)) + elif mode == self.MODE_END: + domain.append(("date", "<=", date_to)) + elif mode == self.MODE_UNALLOCATED: + date_from_date = fields.Date.from_string(date_from) + # TODO this takes the fy from the first company + # make that user controllable (nice to have)? + fy_date_from = self.companies[0].compute_fiscalyear_dates(date_from_date)[ + "date_from" + ] + domain = [ + ("date", "<", fields.Date.to_string(fy_date_from)), + ("account_id.user_type_id.include_initial_balance", "=", False), + ] + if target_move == "posted": + domain.append(("move_id.state", "=", "posted")) + return expression.normalize_domain(domain) + + def _get_company_rates(self, date): + # get exchange rates for each company with its rouding + company_rates = {} + target_rate = self.currency.with_context(date=date).rate + for company in self.companies: + if company.currency_id != self.currency: + rate = target_rate / company.currency_id.with_context(date=date).rate + else: + rate = 1.0 + company_rates[company.id] = (rate, company.currency_id.decimal_places) + return company_rates + + def do_queries( + self, + date_from, + date_to, + target_move="posted", + additional_move_line_filter=None, + aml_model=None, + ): + """Query sums of debit and credit for all accounts and domains + used in expressions. + + This method must be executed after done_parsing(). + """ + if not aml_model: + aml_model = self.env["account.move.line"] + else: + aml_model = self.env[aml_model] + aml_model = aml_model.with_context(active_test=False) + company_rates = self._get_company_rates(date_to) + # {(domain, mode): {account_id: (debit, credit)}} + self._data = defaultdict(dict) + domain_by_mode = {} + ends = [] + for key in self._map_account_ids: + domain, mode = key + if mode == self.MODE_END and self.smart_end: + # postpone computation of ending balance + ends.append((domain, mode)) + continue + if mode not in domain_by_mode: + domain_by_mode[mode] = self.get_aml_domain_for_dates( + date_from, date_to, mode, target_move + ) + domain = list(domain) + domain_by_mode[mode] + domain.append(("account_id", "in", self._map_account_ids[key])) + if additional_move_line_filter: + domain.extend(additional_move_line_filter) + # fetch sum of debit/credit, grouped by account_id + accs = aml_model.read_group( + domain, + ["debit", "credit", "account_id", "company_id"], + ["account_id", "company_id"], + lazy=False, + ) + for acc in accs: + rate, dp = company_rates[acc["company_id"][0]] + debit = acc["debit"] or 0.0 + credit = acc["credit"] or 0.0 + if mode in (self.MODE_INITIAL, self.MODE_UNALLOCATED) and float_is_zero( + debit - credit, precision_digits=self.dp + ): + # in initial mode, ignore accounts with 0 balance + continue + self._data[key][acc["account_id"][0]] = (debit * rate, credit * rate) + # compute ending balances by summing initial and variation + for key in ends: + domain, mode = key + initial_data = self._data[(domain, self.MODE_INITIAL)] + variation_data = self._data[(domain, self.MODE_VARIATION)] + account_ids = set(initial_data.keys()) | set(variation_data.keys()) + for account_id in account_ids: + di, ci = initial_data.get(account_id, (AccountingNone, AccountingNone)) + dv, cv = variation_data.get( + account_id, (AccountingNone, AccountingNone) + ) + self._data[key][account_id] = (di + dv, ci + cv) + + def replace_expr(self, expr): + """Replace accounting variables in an expression by their amount. + + Returns a new expression string. + + This method must be executed after do_queries(). + """ + + def f(mo): + field, mode, acc_domain, ml_domain = self._parse_match_object(mo) + key = (ml_domain, mode) + account_ids_data = self._data[key] + v = AccountingNone + account_ids = self._account_ids_by_acc_domain[acc_domain] + for account_id in account_ids: + debit, credit = account_ids_data.get( + account_id, (AccountingNone, AccountingNone) + ) + if field == "bal": + v += debit - credit + elif field == "pbal" and debit >= credit: + v += debit - credit + elif field == "nbal" and debit < credit: + v += debit - credit + elif field == "deb": + v += debit + elif field == "crd": + v += credit + # in initial balance mode, assume 0 is None + # as it does not make sense to distinguish 0 from "no data" + if ( + v is not AccountingNone + and mode in (self.MODE_INITIAL, self.MODE_UNALLOCATED) + and float_is_zero(v, precision_digits=self.dp) + ): + v = AccountingNone + return "(" + repr(v) + ")" + + return self._ACC_RE.sub(f, expr) + + def replace_exprs_by_account_id(self, exprs): + """Replace accounting variables in a list of expression + by their amount, iterating by accounts involved in the expression. + + yields account_id, replaced_expr + + This method must be executed after do_queries(). + """ + + def f(mo): + field, mode, acc_domain, ml_domain = self._parse_match_object(mo) + key = (ml_domain, mode) + # first check if account_id is involved in + # the current expression part + if account_id not in self._account_ids_by_acc_domain[acc_domain]: + return "(AccountingNone)" + # here we know account_id is involved in acc_domain + account_ids_data = self._data[key] + debit, credit = account_ids_data.get( + account_id, (AccountingNone, AccountingNone) + ) + if field == "bal": + v = debit - credit + elif field == "pbal": + if debit >= credit: + v = debit - credit + else: + v = AccountingNone + elif field == "nbal": + if debit < credit: + v = debit - credit + else: + v = AccountingNone + elif field == "deb": + v = debit + elif field == "crd": + v = credit + # in initial balance mode, assume 0 is None + # as it does not make sense to distinguish 0 from "no data" + if ( + v is not AccountingNone + and mode in (self.MODE_INITIAL, self.MODE_UNALLOCATED) + and float_is_zero(v, precision_digits=self.dp) + ): + v = AccountingNone + return "(" + repr(v) + ")" + + account_ids = set() + for expr in exprs: + for mo in self._ACC_RE.finditer(expr): + field, mode, acc_domain, ml_domain = self._parse_match_object(mo) + key = (ml_domain, mode) + account_ids_data = self._data[key] + for account_id in self._account_ids_by_acc_domain[acc_domain]: + if account_id in account_ids_data: + account_ids.add(account_id) + + for account_id in account_ids: + yield account_id, [self._ACC_RE.sub(f, expr) for expr in exprs] + + @classmethod + def _get_balances(cls, mode, companies, date_from, date_to, target_move="posted"): + expr = "deb{mode}[], crd{mode}[]".format(mode=mode) + aep = AccountingExpressionProcessor(companies) + # disable smart_end to have the data at once, instead + # of initial + variation + aep.smart_end = False + aep.parse_expr(expr) + aep.done_parsing() + aep.do_queries(date_from, date_to, target_move) + return aep._data[((), mode)] + + @classmethod + def get_balances_initial(cls, companies, date, target_move="posted"): + """A convenience method to obtain the initial balances of all accounts + at a given date. + + It is the same as get_balances_end(date-1). + + :param companies: + :param date: + :param target_move: if 'posted', consider only posted moves + + Returns a dictionary: {account_id, (debit, credit)} + """ + return cls._get_balances(cls.MODE_INITIAL, companies, date, date, target_move) + + @classmethod + def get_balances_end(cls, companies, date, target_move="posted"): + """A convenience method to obtain the ending balances of all accounts + at a given date. + + It is the same as get_balances_initial(date+1). + + :param companies: + :param date: + :param target_move: if 'posted', consider only posted moves + + Returns a dictionary: {account_id, (debit, credit)} + """ + return cls._get_balances(cls.MODE_END, companies, date, date, target_move) + + @classmethod + def get_balances_variation( + cls, companies, date_from, date_to, target_move="posted" + ): + """A convenience method to obtain the variation of the + balances of all accounts over a period. + + :param companies: + :param date: + :param target_move: if 'posted', consider only posted moves + + Returns a dictionary: {account_id, (debit, credit)} + """ + return cls._get_balances( + cls.MODE_VARIATION, companies, date_from, date_to, target_move + ) + + @classmethod + def get_unallocated_pl(cls, companies, date, target_move="posted"): + """A convenience method to obtain the unallocated profit/loss + of the previous fiscal years at a given date. + + :param companies: + :param date: + :param target_move: if 'posted', consider only posted moves + + Returns a tuple (debit, credit) + """ + # TODO shoud we include here the accounts of type "unaffected" + # or leave that to the caller? + bals = cls._get_balances( + cls.MODE_UNALLOCATED, companies, date, date, target_move + ) + return tuple(map(sum, zip(*bals.values()))) diff --git a/odex25_accounting/mis_builder/models/aggregate.py b/odex25_accounting/mis_builder/models/aggregate.py new file mode 100644 index 000000000..32e34bd95 --- /dev/null +++ b/odex25_accounting/mis_builder/models/aggregate.py @@ -0,0 +1,129 @@ +# Copyright 2014 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + + +def _sum(lst): + """Same as stdlib sum but returns None instead of 0 + in case of empty sequence. + + >>> sum([1]) + 1 + >>> _sum([1]) + 1 + >>> sum([1, 2]) + 3 + >>> _sum([1, 2]) + 3 + >>> sum([]) + 0 + >>> _sum([]) + """ + if not lst: + return None + return sum(lst) + + +def _avg(lst): + """Arithmetic mean of a sequence. Returns None in case of empty sequence. + + >>> _avg([1]) + 1.0 + >>> _avg([1, 2]) + 1.5 + >>> _avg([]) + """ + if not lst: + return None + return sum(lst) / float(len(lst)) + + +def _min(*args): + """Same as stdlib min but returns None instead of exception + in case of empty sequence. + + >>> min(1, 2) + 1 + >>> _min(1, 2) + 1 + >>> min([1, 2]) + 1 + >>> _min([1, 2]) + 1 + >>> min(1) + Traceback (most recent call last): + File "", line 1, in ? + TypeError: 'int' object is not iterable + >>> _min(1) + Traceback (most recent call last): + File "", line 1, in ? + TypeError: 'int' object is not iterable + >>> min([1]) + 1 + >>> _min([1]) + 1 + >>> min() + Traceback (most recent call last): + File "", line 1, in ? + TypeError: min expected 1 arguments, got 0 + >>> _min() + Traceback (most recent call last): + File "", line 1, in ? + TypeError: min expected 1 arguments, got 0 + >>> min([]) + Traceback (most recent call last): + File "", line 1, in ? + ValueError: min() arg is an empty sequence + >>> _min([]) + """ + if len(args) == 1 and not args[0]: + return None + return min(*args) + + +def _max(*args): + """Same as stdlib max but returns None instead of exception + in case of empty sequence. + + >>> max(1, 2) + 2 + >>> _max(1, 2) + 2 + >>> max([1, 2]) + 2 + >>> _max([1, 2]) + 2 + >>> max(1) + Traceback (most recent call last): + File "", line 1, in ? + TypeError: 'int' object is not iterable + >>> _max(1) + Traceback (most recent call last): + File "", line 1, in ? + TypeError: 'int' object is not iterable + >>> max([1]) + 1 + >>> _max([1]) + 1 + >>> max() + Traceback (most recent call last): + File "", line 1, in ? + TypeError: max expected 1 arguments, got 0 + >>> _max() + Traceback (most recent call last): + File "", line 1, in ? + TypeError: max expected 1 arguments, got 0 + >>> max([]) + Traceback (most recent call last): + File "", line 1, in ? + ValueError: max() arg is an empty sequence + >>> _max([]) + """ + if len(args) == 1 and not args[0]: + return None + return max(*args) + + +if __name__ == "__main__": # pragma: no cover + import doctest + + doctest.testmod() diff --git a/odex25_accounting/mis_builder/models/data_error.py b/odex25_accounting/mis_builder/models/data_error.py new file mode 100644 index 000000000..8b53921d2 --- /dev/null +++ b/odex25_accounting/mis_builder/models/data_error.py @@ -0,0 +1,17 @@ +# Copyright 2016 ACSONE SA/NV () +# Copyright 2016 Akretion () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + + +class DataError(Exception): + def __init__(self, name, msg): + super(DataError, self).__init__() + self.name = name + self.msg = msg + + def __repr__(self): + return "{}({})".format(self.__class__.__name__, repr(self.name)) + + +class NameDataError(DataError): + pass diff --git a/odex25_accounting/mis_builder/models/expression_evaluator.py b/odex25_accounting/mis_builder/models/expression_evaluator.py new file mode 100644 index 000000000..a98ac4e37 --- /dev/null +++ b/odex25_accounting/mis_builder/models/expression_evaluator.py @@ -0,0 +1,76 @@ +# Copyright 2020 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from .mis_safe_eval import NameDataError, mis_safe_eval + +try: + import itertools.izip as zip +except ImportError: + pass # python 3 + + +class ExpressionEvaluator(object): + def __init__( + self, + aep, + date_from, + date_to, + target_move=None, + additional_move_line_filter=None, + aml_model=None, + ): + self.aep = aep + self.date_from = date_from + self.date_to = date_to + self.target_move = target_move + self.additional_move_line_filter = additional_move_line_filter + self.aml_model = aml_model + self._aep_queries_done = False + + def aep_do_queries(self): + if self.aep and not self._aep_queries_done: + self.aep.do_queries( + self.date_from, + self.date_to, + self.target_move, + self.additional_move_line_filter, + self.aml_model, + ) + self._aep_queries_done = True + + def eval_expressions(self, expressions, locals_dict): + vals = [] + drilldown_args = [] + name_error = False + for expression in expressions: + expr = expression and expression.name or "AccountingNone" + if self.aep: + replaced_expr = self.aep.replace_expr(expr) + else: + replaced_expr = expr + val = mis_safe_eval(replaced_expr, locals_dict) + vals.append(val) + if isinstance(val, NameDataError): + name_error = True + if replaced_expr != expr: + drilldown_args.append({"expr": expr}) + else: + drilldown_args.append(None) + return vals, drilldown_args, name_error + + def eval_expressions_by_account(self, expressions, locals_dict): + if not self.aep: + return + exprs = [e and e.name or "AccountingNone" for e in expressions] + for account_id, replaced_exprs in self.aep.replace_exprs_by_account_id(exprs): + vals = [] + drilldown_args = [] + name_error = False + for expr, replaced_expr in zip(exprs, replaced_exprs): + val = mis_safe_eval(replaced_expr, locals_dict) + vals.append(val) + if replaced_expr != expr: + drilldown_args.append({"expr": expr, "account_id": account_id}) + else: + drilldown_args.append(None) + yield account_id, vals, drilldown_args, name_error diff --git a/odex25_accounting/mis_builder/models/kpimatrix.py b/odex25_accounting/mis_builder/models/kpimatrix.py new file mode 100644 index 000000000..8b89b28fe --- /dev/null +++ b/odex25_accounting/mis_builder/models/kpimatrix.py @@ -0,0 +1,544 @@ +# Copyright 2014 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import logging +from collections import OrderedDict, defaultdict + +from odoo import _ +from odoo.exceptions import UserError + +from .accounting_none import AccountingNone +from .mis_kpi_data import ACC_SUM +from .mis_safe_eval import DataError, mis_safe_eval +from .simple_array import SimpleArray + +try: + import itertools.izip as zip +except ImportError: + pass # python 3 + + +_logger = logging.getLogger(__name__) + + +class KpiMatrixRow(object): + + # TODO: ultimately, the kpi matrix will become ignorant of KPI's and + # accounts and know about rows, columns, sub columns and styles only. + # It is already ignorant of period and only knowns about columns. + # This will require a correct abstraction for expanding row details. + + def __init__(self, matrix, kpi, account_id=None, parent_row=None): + self._matrix = matrix + self.kpi = kpi + self.account_id = account_id + self.description = "" + self.parent_row = parent_row + if not self.account_id: + self.style_props = self._matrix._style_model.merge( + [self.kpi.report_id.style_id, self.kpi.style_id] + ) + else: + self.style_props = self._matrix._style_model.merge( + [self.kpi.report_id.style_id, self.kpi.auto_expand_accounts_style_id] + ) + + @property + def label(self): + if not self.account_id: + return self.kpi.description + else: + return self._matrix.get_account_name(self.account_id) + + @property + def row_id(self): + if not self.account_id: + return self.kpi.name + else: + return "{}:{}".format(self.kpi.name, self.account_id) + + def iter_cell_tuples(self, cols=None): + if cols is None: + cols = self._matrix.iter_cols() + for col in cols: + yield col.get_cell_tuple_for_row(self) + + def iter_cells(self, subcols=None): + if subcols is None: + subcols = self._matrix.iter_subcols() + for subcol in subcols: + yield subcol.get_cell_for_row(self) + + def is_empty(self): + for cell in self.iter_cells(): + if cell and cell.val not in (AccountingNone, None): + return False + return True + + +class KpiMatrixCol(object): + def __init__(self, key, label, description, locals_dict, subkpis): + self.key = key + self.label = label + self.description = description + self.locals_dict = locals_dict + self.colspan = subkpis and len(subkpis) or 1 + self._subcols = [] + self.subkpis = subkpis + if not subkpis: + subcol = KpiMatrixSubCol(self, "", "", 0) + self._subcols.append(subcol) + else: + for i, subkpi in enumerate(subkpis): + subcol = KpiMatrixSubCol(self, subkpi.description, "", i) + self._subcols.append(subcol) + self._cell_tuples_by_row = {} # {row: (cells tuple)} + + def _set_cell_tuple(self, row, cell_tuple): + self._cell_tuples_by_row[row] = cell_tuple + + def iter_subcols(self): + return self._subcols + + def iter_cell_tuples(self): + return self._cell_tuples_by_row.values() + + def get_cell_tuple_for_row(self, row): + return self._cell_tuples_by_row.get(row) + + +class KpiMatrixSubCol(object): + def __init__(self, col, label, description, index=0): + self.col = col + self.label = label + self.description = description + self.index = index + + @property + def subkpi(self): + if self.col.subkpis: + return self.col.subkpis[self.index] + + def iter_cells(self): + for cell_tuple in self.col.iter_cell_tuples(): + yield cell_tuple[self.index] + + def get_cell_for_row(self, row): + cell_tuple = self.col.get_cell_tuple_for_row(row) + if cell_tuple is None: + return None + return cell_tuple[self.index] + + +class KpiMatrixCell(object): # noqa: B903 (immutable data class) + def __init__( + self, + row, + subcol, + val, + val_rendered, + val_comment, + style_props, + drilldown_arg, + val_type, + ): + self.row = row + self.subcol = subcol + self.val = val + self.val_rendered = val_rendered + self.val_comment = val_comment + self.style_props = style_props + self.drilldown_arg = drilldown_arg + self.val_type = val_type + + +class KpiMatrix(object): + def __init__(self, env, multi_company=False, account_model="account.account"): + # cache language id for faster rendering + lang_model = env["res.lang"] + self.lang = lang_model._lang_get(env.user.lang) + self._style_model = env["mis.report.style"] + self._account_model = env[account_model] + # data structures + # { kpi: KpiMatrixRow } + self._kpi_rows = OrderedDict() + # { kpi: {account_id: KpiMatrixRow} } + self._detail_rows = {} + # { col_key: KpiMatrixCol } + self._cols = OrderedDict() + # { col_key (left of comparison): [(col_key, base_col_key)] } + self._comparison_todo = defaultdict(list) + # { col_key (left of sum): (col_key, [(sign, sum_col_key)]) + self._sum_todo = {} + # { account_id: account_name } + self._account_names = {} + self._multi_company = multi_company + + def declare_kpi(self, kpi): + """Declare a new kpi (row) in the matrix. + + Invoke this first for all kpi, in display order. + """ + self._kpi_rows[kpi] = KpiMatrixRow(self, kpi) + self._detail_rows[kpi] = {} + + def declare_col(self, col_key, label, description, locals_dict, subkpis): + """Declare a new column, giving it an identifier (key). + + Invoke the declare_* methods in display order. + """ + col = KpiMatrixCol(col_key, label, description, locals_dict, subkpis) + self._cols[col_key] = col + return col + + def declare_comparison( + self, cmpcol_key, col_key, base_col_key, label, description=None + ): + """Declare a new comparison column. + + Invoke the declare_* methods in display order. + """ + self._comparison_todo[cmpcol_key] = (col_key, base_col_key, label, description) + self._cols[cmpcol_key] = None # reserve slot in insertion order + + def declare_sum( + self, sumcol_key, col_to_sum_keys, label, description=None, sum_accdet=False + ): + """Declare a new summation column. + + Invoke the declare_* methods in display order. + :param col_to_sum_keys: [(sign, col_key)] + """ + self._sum_todo[sumcol_key] = (col_to_sum_keys, label, description, sum_accdet) + self._cols[sumcol_key] = None # reserve slot in insertion order + + def set_values(self, kpi, col_key, vals, drilldown_args, tooltips=True): + """Set values for a kpi and a colum. + + Invoke this after declaring the kpi and the column. + """ + self.set_values_detail_account( + kpi, col_key, None, vals, drilldown_args, tooltips + ) + + def set_values_detail_account( + self, kpi, col_key, account_id, vals, drilldown_args, tooltips=True + ): + """Set values for a kpi and a column and a detail account. + + Invoke this after declaring the kpi and the column. + """ + if not account_id: + row = self._kpi_rows[kpi] + else: + kpi_row = self._kpi_rows[kpi] + if account_id in self._detail_rows[kpi]: + row = self._detail_rows[kpi][account_id] + else: + row = KpiMatrixRow(self, kpi, account_id, parent_row=kpi_row) + self._detail_rows[kpi][account_id] = row + col = self._cols[col_key] + cell_tuple = [] + assert len(vals) == col.colspan + assert len(drilldown_args) == col.colspan + for val, drilldown_arg, subcol in zip(vals, drilldown_args, col.iter_subcols()): + if isinstance(val, DataError): + val_rendered = val.name + val_comment = val.msg + else: + val_rendered = self._style_model.render( + self.lang, row.style_props, kpi.type, val + ) + if row.kpi.multi and subcol.subkpi: + val_comment = u"{}.{} = {}".format( + row.kpi.name, + subcol.subkpi.name, + row.kpi._get_expression_str_for_subkpi(subcol.subkpi), + ) + else: + val_comment = u"{} = {}".format(row.kpi.name, row.kpi.expression) + cell_style_props = row.style_props + if row.kpi.style_expression: + # evaluate style expression + try: + style_name = mis_safe_eval( + row.kpi.style_expression, col.locals_dict + ) + except Exception: + _logger.error( + "Error evaluating style expression <%s>", + row.kpi.style_expression, + exc_info=True, + ) + if style_name: + style = self._style_model.search([("name", "=", style_name)]) + if style: + cell_style_props = self._style_model.merge( + [row.style_props, style[0]] + ) + else: + _logger.error("Style '%s' not found.", style_name) + cell = KpiMatrixCell( + row, + subcol, + val, + val_rendered, + tooltips and val_comment or None, + cell_style_props, + drilldown_arg, + kpi.type, + ) + cell_tuple.append(cell) + assert len(cell_tuple) == col.colspan + col._set_cell_tuple(row, cell_tuple) + + def _common_subkpis(self, cols): + if not cols: + return set() + common_subkpis = set(cols[0].subkpis) + for col in cols[1:]: + common_subkpis = common_subkpis & set(col.subkpis) + return common_subkpis + + def compute_comparisons(self): + """Compute comparisons. + + Invoke this after setting all values. + """ + for ( + cmpcol_key, + (col_key, base_col_key, label, description), + ) in self._comparison_todo.items(): + col = self._cols[col_key] + base_col = self._cols[base_col_key] + common_subkpis = self._common_subkpis([col, base_col]) + if (col.subkpis or base_col.subkpis) and not common_subkpis: + raise UserError( + _("Columns {} and {} are not comparable").format( + col.description, base_col.description + ) + ) + if not label: + label = u"{} vs {}".format(col.label, base_col.label) + comparison_col = KpiMatrixCol( + cmpcol_key, + label, + description, + {}, + sorted(common_subkpis, key=lambda s: s.sequence), + ) + self._cols[cmpcol_key] = comparison_col + for row in self.iter_rows(): + cell_tuple = col.get_cell_tuple_for_row(row) + base_cell_tuple = base_col.get_cell_tuple_for_row(row) + if cell_tuple is None and base_cell_tuple is None: + continue + if cell_tuple is None: + vals = [AccountingNone] * (len(common_subkpis) or 1) + else: + vals = [ + cell.val + for cell in cell_tuple + if not common_subkpis or cell.subcol.subkpi in common_subkpis + ] + if base_cell_tuple is None: + base_vals = [AccountingNone] * (len(common_subkpis) or 1) + else: + base_vals = [ + cell.val + for cell in base_cell_tuple + if not common_subkpis or cell.subcol.subkpi in common_subkpis + ] + comparison_cell_tuple = [] + for val, base_val, comparison_subcol in zip( + vals, base_vals, comparison_col.iter_subcols() + ): + # TODO FIXME average factors + comparison = self._style_model.compare_and_render( + self.lang, + row.style_props, + row.kpi.type, + row.kpi.compare_method, + val, + base_val, + 1, + 1, + ) + delta, delta_r, delta_style, delta_type = comparison + comparison_cell_tuple.append( + KpiMatrixCell( + row, + comparison_subcol, + delta, + delta_r, + None, + delta_style, + None, + delta_type, + ) + ) + comparison_col._set_cell_tuple(row, comparison_cell_tuple) + + def compute_sums(self): + """Compute comparisons. + + Invoke this after setting all values. + """ + for ( + sumcol_key, + (col_to_sum_keys, label, description, sum_accdet), + ) in self._sum_todo.items(): + sumcols = [self._cols[k] for (sign, k) in col_to_sum_keys] + # TODO check all sumcols are resolved; we need a kind of + # recompute queue here so we don't depend on insertion + # order + common_subkpis = self._common_subkpis(sumcols) + if any(c.subkpis for c in sumcols) and not common_subkpis: + raise UserError( + _( + "Sum cannot be computed in column {} " + "because the columns to sum have no " + "common subkpis" + ).format(label) + ) + sum_col = KpiMatrixCol( + sumcol_key, + label, + description, + {}, + sorted(common_subkpis, key=lambda s: s.sequence), + ) + self._cols[sumcol_key] = sum_col + for row in self.iter_rows(): + acc = SimpleArray([AccountingNone] * (len(common_subkpis) or 1)) + if row.kpi.accumulation_method == ACC_SUM and not ( + row.account_id and not sum_accdet + ): + for sign, col_to_sum in col_to_sum_keys: + cell_tuple = self._cols[col_to_sum].get_cell_tuple_for_row(row) + if cell_tuple is None: + vals = [AccountingNone] * (len(common_subkpis) or 1) + else: + vals = [ + cell.val + for cell in cell_tuple + if not common_subkpis + or cell.subcol.subkpi in common_subkpis + ] + if sign == "+": + acc += SimpleArray(vals) + else: + acc -= SimpleArray(vals) + self.set_values_detail_account( + row.kpi, + sumcol_key, + row.account_id, + acc, + [None] * (len(common_subkpis) or 1), + tooltips=False, + ) + + def iter_rows(self): + """Iterate rows in display order. + + yields KpiMatrixRow. + """ + for kpi_row in self._kpi_rows.values(): + yield kpi_row + detail_rows = self._detail_rows[kpi_row.kpi].values() + detail_rows = sorted(detail_rows, key=lambda r: r.label) + for detail_row in detail_rows: + yield detail_row + + def iter_cols(self): + """Iterate columns in display order. + + yields KpiMatrixCol: one for each column or comparison. + """ + for _col_key, col in self._cols.items(): + yield col + + def iter_subcols(self): + """Iterate sub columns in display order. + + yields KpiMatrixSubCol: one for each subkpi in each column + and comparison. + """ + for col in self.iter_cols(): + for subcol in col.iter_subcols(): + yield subcol + + def _load_account_names(self): + account_ids = set() + for detail_rows in self._detail_rows.values(): + account_ids.update(detail_rows.keys()) + accounts = self._account_model.search([("id", "in", list(account_ids))]) + self._account_names = {a.id: self._get_account_name(a) for a in accounts} + + def _get_account_name(self, account): + result = u"{} {}".format(account.code, account.name) + if self._multi_company: + result = u"{} [{}]".format(result, account.company_id.name) + return result + + def get_account_name(self, account_id): + if account_id not in self._account_names: + self._load_account_names() + return self._account_names[account_id] + + def as_dict(self): + header = [{"cols": []}, {"cols": []}] + for col in self.iter_cols(): + header[0]["cols"].append( + { + "label": col.label, + "description": col.description, + "colspan": col.colspan, + } + ) + for subcol in col.iter_subcols(): + header[1]["cols"].append( + { + "label": subcol.label, + "description": subcol.description, + "colspan": 1, + } + ) + + body = [] + for row in self.iter_rows(): + if ( + row.style_props.hide_empty and row.is_empty() + ) or row.style_props.hide_always: + continue + row_data = { + "row_id": row.row_id, + "parent_row_id": (row.parent_row and row.parent_row.row_id or None), + "label": row.label, + "description": row.description, + "style": self._style_model.to_css_style(row.style_props), + "cells": [], + } + for cell in row.iter_cells(): + if cell is None: + # TODO use subcol style here + row_data["cells"].append({}) + else: + if cell.val is AccountingNone or isinstance(cell.val, DataError): + val = None + else: + val = cell.val + col_data = { + "val": val, + "val_r": cell.val_rendered, + "val_c": cell.val_comment, + "style": self._style_model.to_css_style( + cell.style_props, no_indent=True + ), + } + if cell.drilldown_arg: + col_data["drilldown_arg"] = cell.drilldown_arg + row_data["cells"].append(col_data) + body.append(row_data) + + return {"header": header, "body": body} diff --git a/odex25_accounting/mis_builder/models/mis_kpi_data.py b/odex25_accounting/mis_builder/models/mis_kpi_data.py new file mode 100644 index 000000000..1f9ba18cb --- /dev/null +++ b/odex25_accounting/mis_builder/models/mis_kpi_data.py @@ -0,0 +1,112 @@ +# Copyright 2017 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from collections import defaultdict + +from odoo import _, api, fields, models +from odoo.exceptions import UserError +from odoo.osv import expression + +ACC_SUM = "sum" +ACC_AVG = "avg" +ACC_NONE = "none" + + +def intersect_days(item_dt_from, item_dt_to, dt_from, dt_to): + item_days = (item_dt_to - item_dt_from).days + 1.0 + i_dt_from = max(dt_from, item_dt_from) + i_dt_to = min(dt_to, item_dt_to) + i_days = (i_dt_to - i_dt_from).days + 1.0 + return i_days, item_days + + +class MisKpiData(models.AbstractModel): + """Abstract class for manually entered KPI values.""" + + _name = "mis.kpi.data" + _description = "MIS Kpi Data Abtract class" + + name = fields.Char(compute="_compute_name", required=False, readonly=True) + kpi_expression_id = fields.Many2one( + comodel_name="mis.report.kpi.expression", + required=True, + ondelete="restrict", + string="KPI", + ) + date_from = fields.Date(required=True, string="From") + date_to = fields.Date(required=True, string="To") + amount = fields.Float() + seq1 = fields.Integer( + related="kpi_expression_id.kpi_id.sequence", + store=True, + readonly=True, + string="KPI Sequence", + ) + seq2 = fields.Integer( + related="kpi_expression_id.subkpi_id.sequence", + store=True, + readonly=True, + string="Sub-KPI Sequence", + ) + + @api.depends( + "kpi_expression_id.subkpi_id.name", + "kpi_expression_id.kpi_id.name", + "date_from", + "date_to", + ) + def _compute_name(self): + for rec in self: + subkpi_name = rec.kpi_expression_id.subkpi_id.name + if subkpi_name: + subkpi_name = "." + subkpi_name + else: + subkpi_name = "" + rec.name = u"{}{}: {} - {}".format( + rec.kpi_expression_id.kpi_id.name, + subkpi_name, + rec.date_from, + rec.date_to, + ) + + @api.model + def _intersect_days(self, item_dt_from, item_dt_to, dt_from, dt_to): + return intersect_days(item_dt_from, item_dt_to, dt_from, dt_to) + + @api.model + def _query_kpi_data(self, date_from, date_to, base_domain): + """Query mis.kpi.data over a time period. + + Returns {mis.report.kpi.expression: amount} + """ + dt_from = fields.Date.from_string(date_from) + dt_to = fields.Date.from_string(date_to) + # all data items within or overlapping [date_from, date_to] + date_domain = [("date_from", "<=", date_to), ("date_to", ">=", date_from)] + domain = expression.AND([date_domain, base_domain]) + res = defaultdict(float) + res_avg = defaultdict(list) + for item in self.search(domain): + item_dt_from = fields.Date.from_string(item.date_from) + item_dt_to = fields.Date.from_string(item.date_to) + i_days, item_days = self._intersect_days( + item_dt_from, item_dt_to, dt_from, dt_to + ) + if item.kpi_expression_id.kpi_id.accumulation_method == ACC_SUM: + # accumulate pro-rata overlap between item and reporting period + res[item.kpi_expression_id] += item.amount * i_days / item_days + elif item.kpi_expression_id.kpi_id.accumulation_method == ACC_AVG: + # memorize the amount and number of days overlapping + # the reporting period (used as weight in average) + res_avg[item.kpi_expression_id].append((i_days, item.amount)) + else: + raise UserError( + _("Unexpected accumulation method %s for %s.") + % (item.kpi_expression_id.kpi_id.accumulation_method, item.name) + ) + # compute weighted average for ACC_AVG + for kpi_expression, amounts in res_avg.items(): + res[kpi_expression] = sum(d * a for d, a in amounts) / sum( + d for d, a in amounts + ) + return res diff --git a/odex25_accounting/mis_builder/models/mis_report.py b/odex25_accounting/mis_builder/models/mis_report.py new file mode 100644 index 000000000..75b644652 --- /dev/null +++ b/odex25_accounting/mis_builder/models/mis_report.py @@ -0,0 +1,981 @@ +# Copyright 2014 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import datetime +import logging +import re +import time +from collections import defaultdict + +import dateutil +import pytz + +from odoo import _, api, fields, models +from odoo.exceptions import UserError, ValidationError +from odoo.models import expression as osv_expression +from odoo.tools.safe_eval import safe_eval + +from .accounting_none import AccountingNone +from .aep import AccountingExpressionProcessor as AEP +from .aggregate import _avg, _max, _min, _sum +from .expression_evaluator import ExpressionEvaluator +from .kpimatrix import KpiMatrix +from .mis_kpi_data import ACC_AVG, ACC_NONE, ACC_SUM +from .mis_report_style import CMP_DIFF, CMP_NONE, CMP_PCT, TYPE_NUM, TYPE_PCT, TYPE_STR +from .mis_safe_eval import DataError +from .simple_array import SimpleArray, named_simple_array + +_logger = logging.getLogger(__name__) + + +class SubKPITupleLengthError(UserError): + pass + + +class SubKPIUnknownTypeError(UserError): + pass + + +class AutoStruct(object): + def __init__(self, **kwargs): + for k, v in kwargs.items(): + setattr(self, k, v) + + +def _utc_midnight(d, tz_name, add_day=0): + d = fields.Datetime.from_string(d) + datetime.timedelta(days=add_day) + utc_tz = pytz.timezone("UTC") + context_tz = pytz.timezone(tz_name) + local_timestamp = context_tz.localize(d, is_dst=False) + return fields.Datetime.to_string(local_timestamp.astimezone(utc_tz)) + + +def _python_var(var_str): + return re.sub(r"\W|^(?=\d)", "_", var_str).lower() + + +def _is_valid_python_var(name): + return re.match("[_A-Za-z][_a-zA-Z0-9]*$", name) + + +class MisReportKpi(models.Model): + """A KPI is an element (ie a line) of a MIS report. + + In addition to a name and description, it has an expression + to compute it based on queries defined in the MIS report. + It also has various informations defining how to render it + (numeric or percentage or a string, a prefix, a suffix, divider) and + how to render comparison of two values of the KPI. + KPI's have a sequence and are ordered inside the MIS report. + """ + + _name = "mis.report.kpi" + _description = "MIS Report KPI" + + name = fields.Char(size=32, required=True, string="Name") + description = fields.Char(required=True, string="Description", translate=True) + multi = fields.Boolean() + expression = fields.Char( + compute="_compute_expression", + inverse="_inverse_expression", + string="Expression", + ) + expression_ids = fields.One2many( + comodel_name="mis.report.kpi.expression", + inverse_name="kpi_id", + copy=True, + string="Expressions", + ) + auto_expand_accounts = fields.Boolean(string="Display details by account") + auto_expand_accounts_style_id = fields.Many2one( + string="Style for account detail rows", + comodel_name="mis.report.style", + required=False, + ) + style_id = fields.Many2one( + string="Style", comodel_name="mis.report.style", required=False + ) + style_expression = fields.Char( + string="Style expression", + help="An expression that returns a style depending on the KPI value. " + "Such style is applied on top of the row style.", + ) + type = fields.Selection( + [ + (TYPE_NUM, _("Numeric")), + (TYPE_PCT, _("Percentage")), + (TYPE_STR, _("String")), + ], + required=True, + string="Value type", + default=TYPE_NUM, + ) + compare_method = fields.Selection( + [ + (CMP_DIFF, _("Difference")), + (CMP_PCT, _("Percentage")), + (CMP_NONE, _("None")), + ], + required=True, + string="Comparison Method", + default=CMP_PCT, + ) + accumulation_method = fields.Selection( + [(ACC_SUM, _("Sum")), (ACC_AVG, _("Average")), (ACC_NONE, _("None"))], + required=True, + string="Accumulation Method", + default=ACC_SUM, + help="Determines how values of this kpi spanning over a " + "time period are transformed to match the reporting period. " + "Sum: values of shorter period are added, " + "values of longest or partially overlapping periods are " + "adjusted pro-rata temporis.\n" + "Average: values of included period are averaged " + "with a pro-rata temporis weight.", + ) + sequence = fields.Integer(string="Sequence", default=100) + report_id = fields.Many2one( + "mis.report", string="Report", required=True, ondelete="cascade" + ) + + _order = "sequence, id" + + def name_get(self): + res = [] + for rec in self: + name = u"{} ({})".format(rec.description, rec.name) + res.append((rec.id, name)) + return res + + @api.model + def name_search(self, name="", args=None, operator="ilike", limit=100): + domain = args or [] + domain += ["|", ("name", operator, name), ("description", operator, name)] + return self.search(domain, limit=limit).name_get() + + @api.constrains("name") + def _check_name(self): + for record in self: + if not _is_valid_python_var(record.name): + raise ValidationError( + _("KPI name ({}) must be a valid python identifier").format( + record.name + ) + ) + + @api.depends("expression_ids.subkpi_id.name", "expression_ids.name") + def _compute_expression(self): + for kpi in self: + exprs = [] + for expression in kpi.expression_ids: + if expression.subkpi_id: + exprs.append( + u"{}\xa0=\xa0{}".format( + expression.subkpi_id.name, expression.name + ) + ) + else: + exprs.append(expression.name or "AccountingNone") + kpi.expression = ",\n".join(exprs) + + def _inverse_expression(self): + for kpi in self: + if kpi.multi: + raise UserError(_("Can not update a multi kpi from " "the kpi line")) + if kpi.expression_ids: + kpi.expression_ids[0].write({"name": kpi.expression, "subkpi_id": None}) + for expression in kpi.expression_ids[1:]: + expression.unlink() + else: + expression = self.env["mis.report.kpi.expression"].new( + {"name": kpi.expression} + ) + kpi.expression_ids += expression + + @api.onchange("multi") + def _onchange_multi(self): + for kpi in self: + if not kpi.multi: + if kpi.expression_ids: + kpi.expression = kpi.expression_ids[0].name + else: + kpi.expression = None + else: + expressions = [] + for subkpi in kpi.report_id.subkpi_ids: + expressions.append( + (0, 0, {"name": kpi.expression, "subkpi_id": subkpi.id}) + ) + kpi.expression_ids = expressions + + @api.onchange("description") + def _onchange_description(self): + """ construct name from description """ + if self.description and not self.name: + self.name = _python_var(self.description) + + @api.onchange("type") + def _onchange_type(self): + if self.type == TYPE_NUM: + self.compare_method = CMP_PCT + self.accumulation_method = ACC_SUM + elif self.type == TYPE_PCT: + self.compare_method = CMP_DIFF + self.accumulation_method = ACC_AVG + elif self.type == TYPE_STR: + self.compare_method = CMP_NONE + self.accumulation_method = ACC_NONE + + def _get_expression_str_for_subkpi(self, subkpi): + e = self._get_expression_for_subkpi(subkpi) + return e and e.name or "" + + def _get_expression_for_subkpi(self, subkpi): + for expression in self.expression_ids: + if expression.subkpi_id == subkpi: + return expression + return None + + def _get_expressions(self, subkpis): + if subkpis and self.multi: + return [self._get_expression_for_subkpi(subkpi) for subkpi in subkpis] + else: + if self.expression_ids: + assert len(self.expression_ids) == 1 + assert not self.expression_ids[0].subkpi_id + return self.expression_ids + else: + return [None] + + +class MisReportSubkpi(models.Model): + _name = "mis.report.subkpi" + _description = "MIS Report Sub-KPI" + _order = "sequence, id" + + sequence = fields.Integer(default=1) + report_id = fields.Many2one( + comodel_name="mis.report", required=True, ondelete="cascade" + ) + name = fields.Char(size=32, required=True, string="Name") + description = fields.Char(required=True, string="Description", translate=True) + expression_ids = fields.One2many("mis.report.kpi.expression", "subkpi_id") + + @api.constrains("name") + def _check_name(self): + for record in self: + if not _is_valid_python_var(record.name): + raise ValidationError( + _("Sub-KPI name ({}) must be a valid python identifier").format( + record.name + ) + ) + + @api.onchange("description") + def _onchange_description(self): + """ construct name from description """ + if self.description and not self.name: + self.name = _python_var(self.description) + + +class MisReportKpiExpression(models.Model): + """A KPI Expression is an expression of a line of a MIS report Kpi. + It's used to compute the kpi value. + """ + + _name = "mis.report.kpi.expression" + _description = "MIS Report KPI Expression" + _order = "sequence, name, id" + + sequence = fields.Integer(related="subkpi_id.sequence", store=True, readonly=True) + name = fields.Char(string="Expression") + kpi_id = fields.Many2one("mis.report.kpi", required=True, ondelete="cascade") + # TODO FIXME set readonly=True when onchange('subkpi_ids') below works + subkpi_id = fields.Many2one("mis.report.subkpi", readonly=False, ondelete="cascade") + + _sql_constraints = [ + ( + "subkpi_kpi_unique", + "unique(subkpi_id, kpi_id)", + "Sub KPI must be used once and only once for each KPI", + ) + ] + + def name_get(self): + res = [] + for rec in self: + kpi = rec.kpi_id + subkpi = rec.subkpi_id + if subkpi: + name = u"{} / {} ({}.{})".format( + kpi.description, subkpi.description, kpi.name, subkpi.name + ) + else: + name = rec.kpi_id.display_name + res.append((rec.id, name)) + return res + + @api.model + def name_search(self, name="", args=None, operator="ilike", limit=100): + # TODO maybe implement negative search operators, although + # there is not really a use case for that + domain = args or [] + splitted_name = name.split(".", 2) + name_search_domain = [] + if "." in name: + kpi_name, subkpi_name = splitted_name[0], splitted_name[1] + name_search_domain = osv_expression.AND( + [ + name_search_domain, + [ + "|", + "|", + "&", + ("kpi_id.name", "=", kpi_name), + ("subkpi_id.name", operator, subkpi_name), + ("kpi_id.description", operator, name), + ("subkpi_id.description", operator, name), + ], + ] + ) + name_search_domain = osv_expression.OR( + [ + name_search_domain, + [ + "|", + ("kpi_id.name", operator, name), + ("kpi_id.description", operator, name), + ], + ] + ) + domain = osv_expression.AND([domain, name_search_domain]) + return self.search(domain, limit=limit).name_get() + + +class MisReportQuery(models.Model): + """A query to fetch arbitrary data for a MIS report. + + A query works on a model and has a domain and list of fields to fetch. + At runtime, the domain is expanded with a "and" on the date/datetime field. + """ + + _name = "mis.report.query" + _description = "MIS Report Query" + + @api.depends("field_ids") + def _compute_field_names(self): + for record in self: + field_names = [field.name for field in record.field_ids] + record.field_names = ", ".join(field_names) + + name = fields.Char(size=32, required=True, string="Name") + model_id = fields.Many2one( + "ir.model", required=True, string="Model", ondelete="cascade" + ) + field_ids = fields.Many2many( + "ir.model.fields", required=True, string="Fields to fetch" + ) + field_names = fields.Char( + compute="_compute_field_names", string="Fetched fields name" + ) + aggregate = fields.Selection( + [ + ("sum", _("Sum")), + ("avg", _("Average")), + ("min", _("Min")), + ("max", _("Max")), + ], + string="Aggregate", + ) + date_field = fields.Many2one( + comodel_name="ir.model.fields", + required=True, + domain=[("ttype", "in", ("date", "datetime"))], + ondelete="cascade", + ) + domain = fields.Char(string="Domain") + report_id = fields.Many2one( + comodel_name="mis.report", string="Report", required=True, ondelete="cascade" + ) + + _order = "name" + + @api.constrains("name") + def _check_name(self): + for record in self: + if not _is_valid_python_var(record.name): + raise ValidationError( + _("Query name ({}) must be valid python identifier").format( + record.name + ) + ) + + +class MisReport(models.Model): + """A MIS report template (without period information) + + The MIS report holds: + * a list of explicit queries; the result of each query is + stored in a variable with same name as a query, containing as list + of data structures populated with attributes for each fields to fetch; + when queries have an aggregate method and no fields to group, it returns + a data structure with the aggregated fields + * a list of KPI to be evaluated based on the variables resulting + from the accounting data and queries (KPI expressions can references + queries and accounting expression - see AccoutingExpressionProcessor) + """ + + _name = "mis.report" + _description = "MIS Report Template" + + def _default_move_lines_source(self): + return self.env["ir.model"].search([("model", "=", "account.move.line")]) + + name = fields.Char(required=True, string="Name", translate=True) + description = fields.Char(required=False, string="Description", translate=True) + style_id = fields.Many2one(string="Style", comodel_name="mis.report.style") + query_ids = fields.One2many( + "mis.report.query", "report_id", string="Queries", copy=True + ) + kpi_ids = fields.One2many("mis.report.kpi", "report_id", string="KPI's", copy=True) + subkpi_ids = fields.One2many( + "mis.report.subkpi", "report_id", string="Sub KPI", copy=True + ) + subreport_ids = fields.One2many( + "mis.report.subreport", "report_id", string="Sub reports", copy=True + ) + all_kpi_ids = fields.One2many( + comodel_name="mis.report.kpi", + compute="_compute_all_kpi_ids", + help="KPIs of this report and subreports.", + ) + move_lines_source = fields.Many2one( + comodel_name="ir.model", + string="Move lines source", + domain=[ + ("field_id.name", "=", "debit"), + ("field_id.name", "=", "credit"), + ("field_id.name", "=", "account_id"), + ("field_id.name", "=", "date"), + ("field_id.name", "=", "company_id"), + ], + default=_default_move_lines_source, + required=True, + ondelete="cascade", + help="A 'move line like' model, ie having at least debit, credit, " + "date, account_id and company_id fields. This model is the " + "data source for column Actuals.", + ) + account_model = fields.Char( + compute="_compute_account_model", string="Account model" + ) + + @api.depends("kpi_ids", "subreport_ids") + def _compute_all_kpi_ids(self): + for rec in self: + rec.all_kpi_ids = rec.kpi_ids | rec.subreport_ids.mapped( + "subreport_id.kpi_ids" + ) + + @api.depends("move_lines_source") + def _compute_account_model(self): + for record in self: + record.account_model = record.move_lines_source.field_id.filtered( + lambda r: r.name == "account_id" + ).relation + + @api.onchange("subkpi_ids") + def _on_change_subkpi_ids(self): + """Update kpi expressions when subkpis change on the report, + so the list of kpi expressions is always up-to-date""" + for kpi in self.kpi_ids: + if not kpi.multi: + continue + new_subkpis = {subkpi for subkpi in self.subkpi_ids} + expressions = [] + for expression in kpi.expression_ids: + assert expression.subkpi_id # must be true if kpi is multi + if expression.subkpi_id not in self.subkpi_ids: + expressions.append((2, expression.id, None)) # remove + else: + new_subkpis.remove(expression.subkpi_id) # no change + for subkpi in new_subkpis: + # TODO FIXME this does not work, while the remove above works + expressions.append( + (0, None, {"name": False, "subkpi_id": subkpi.id}) + ) # add empty expressions for new subkpis + if expressions: + kpi.expressions_ids = expressions + + def get_wizard_report_action(self): + action = self.env.ref("mis_builder.mis_report_instance_view_action") + res = action.read()[0] + view = self.env.ref("mis_builder.wizard_mis_report_instance_view_form") + res.update( + { + "view_id": view.id, + "views": [(view.id, "form")], + "target": "new", + "context": { + "default_report_id": self.id, + "default_name": self.name, + "default_temporary": True, + }, + } + ) + return res + + def copy(self, default=None): + self.ensure_one() + default = dict(default or []) + default["name"] = _("%s (copy)") % self.name + new = super(MisReport, self).copy(default) + # after a copy, we have new subkpis, but the expressions + # subkpi_id fields still point to the original one, so + # we patch them after copying + subkpis_by_name = {sk.name: sk for sk in new.subkpi_ids} + for subkpi in self.subkpi_ids: + # search expressions linked to subkpis of the original report + exprs = self.env["mis.report.kpi.expression"].search( + [("kpi_id.report_id", "=", new.id), ("subkpi_id", "=", subkpi.id)] + ) + # and replace them with references to subkpis of the new report + exprs.write({"subkpi_id": subkpis_by_name[subkpi.name].id}) + return new + + # TODO: kpi name cannot be start with query name + + def prepare_kpi_matrix(self, multi_company=False): + self.ensure_one() + kpi_matrix = KpiMatrix(self.env, multi_company, self.account_model) + for kpi in self.kpi_ids: + kpi_matrix.declare_kpi(kpi) + return kpi_matrix + + def _prepare_aep(self, companies, currency=None): + self.ensure_one() + aep = AEP(companies, currency, self.account_model) + for kpi in self.all_kpi_ids: + for expression in kpi.expression_ids: + if expression.name: + aep.parse_expr(expression.name) + aep.done_parsing() + return aep + + def prepare_locals_dict(self): + return { + "sum": _sum, + "min": _min, + "max": _max, + "len": len, + "avg": _avg, + "time": time, + "datetime": datetime, + "dateutil": dateutil, + "AccountingNone": AccountingNone, + "SimpleArray": SimpleArray, + } + + def _fetch_queries(self, date_from, date_to, get_additional_query_filter=None): + self.ensure_one() + res = {} + for query in self.query_ids: + model = self.env[query.model_id.model] + eval_context = { + "env": self.env, + "time": time, + "datetime": datetime, + "dateutil": dateutil, + # deprecated + "uid": self.env.uid, + "context": self.env.context, + } + domain = query.domain and safe_eval(query.domain, eval_context) or [] + if get_additional_query_filter: + domain.extend(get_additional_query_filter(query)) + if query.date_field.ttype == "date": + domain.extend( + [ + (query.date_field.name, ">=", date_from), + (query.date_field.name, "<=", date_to), + ] + ) + else: + datetime_from = _utc_midnight(date_from, self._context.get("tz", "UTC")) + datetime_to = _utc_midnight( + date_to, self._context.get("tz", "UTC"), add_day=1 + ) + domain.extend( + [ + (query.date_field.name, ">=", datetime_from), + (query.date_field.name, "<", datetime_to), + ] + ) + field_names = [f.name for f in query.field_ids] + all_stored = all([model._fields[f].store for f in field_names]) + if not query.aggregate: + data = model.search_read(domain, field_names) + res[query.name] = [AutoStruct(**d) for d in data] + elif query.aggregate == "sum" and all_stored: + # use read_group to sum stored fields + data = model.read_group(domain, field_names, []) + s = AutoStruct(count=data[0]["__count"]) + for field_name in field_names: + try: + v = data[0][field_name] + except KeyError: + _logger.error( + "field %s not found in read_group " "for %s; not summable?", + field_name, + model._name, + ) + v = AccountingNone + setattr(s, field_name, v) + res[query.name] = s + else: + data = model.search_read(domain, field_names) + s = AutoStruct(count=len(data)) + if query.aggregate == "min": + agg = _min + elif query.aggregate == "max": + agg = _max + elif query.aggregate == "avg": + agg = _avg + elif query.aggregate == "sum": + agg = _sum + for field_name in field_names: + setattr(s, field_name, agg([d[field_name] for d in data])) + res[query.name] = s + return res + + def _declare_and_compute_col( # noqa: C901 (TODO simplify this fnction) + self, + expression_evaluator, + kpi_matrix, + col_key, + col_label, + col_description, + subkpis_filter, + locals_dict, + no_auto_expand_accounts=False, + ): + """This is the main computation loop. + + It evaluates the kpis and puts the results in the KpiMatrix. + Evaluation is done through the expression_evaluator so data sources + can provide their own mean of obtaining the data (eg preset + kpi values for budget, or alternative move line sources). + """ + + if subkpis_filter: + # TODO filter by subkpi names + subkpis = [subkpi for subkpi in self.subkpi_ids if subkpi in subkpis_filter] + else: + subkpis = self.subkpi_ids + + SimpleArray_cls = named_simple_array( + "SimpleArray_{}".format(col_key), [subkpi.name for subkpi in subkpis] + ) + locals_dict["SimpleArray"] = SimpleArray_cls + + col = kpi_matrix.declare_col( + col_key, col_label, col_description, locals_dict, subkpis + ) + + compute_queue = self.kpi_ids + recompute_queue = [] + while True: + for kpi in compute_queue: + # build the list of expressions for this kpi + expressions = kpi._get_expressions(subkpis) + + ( + vals, + drilldown_args, + name_error, + ) = expression_evaluator.eval_expressions(expressions, locals_dict) + for drilldown_arg in drilldown_args: + if not drilldown_arg: + continue + drilldown_arg["period_id"] = col_key + drilldown_arg["kpi_id"] = kpi.id + + if name_error: + recompute_queue.append(kpi) + else: + # no error, set it in locals_dict so it can be used + # in computing other kpis + if not subkpis or not kpi.multi: + locals_dict[kpi.name] = vals[0] + else: + locals_dict[kpi.name] = SimpleArray_cls(vals) + + # even in case of name error we set the result in the matrix + # so the name error will be displayed if it cannot be + # resolved by recomputing later + + if subkpis and not kpi.multi: + # here we have one expression for this kpi, but + # multiple subkpis (so this kpi is most probably + # a sum or other operation on multi-valued kpis) + if isinstance(vals[0], tuple): + vals = vals[0] + if len(vals) != col.colspan: + raise SubKPITupleLengthError( + _( + 'KPI "{}" is valued as a tuple of ' + "length {} while a tuple of length {} " + "is expected." + ).format(kpi.description, len(vals), col.colspan) + ) + elif isinstance(vals[0], DataError): + vals = (vals[0],) * col.colspan + else: + raise SubKPIUnknownTypeError( + _( + 'KPI "{}" has type {} while a tuple was ' + "expected.\n\nThis can be fixed by either:\n\t- " + "Changing the KPI value to a tuple of length " + "{}\nor\n\t- Changing the " + "KPI to `multi` mode and giving an explicit " + "value for each sub-KPI." + ).format(kpi.description, type(vals[0]), col.colspan) + ) + if len(drilldown_args) != col.colspan: + drilldown_args = [None] * col.colspan + + kpi_matrix.set_values(kpi, col_key, vals, drilldown_args) + + if ( + name_error + or no_auto_expand_accounts + or not kpi.auto_expand_accounts + ): + continue + + for ( + account_id, + vals, + drilldown_args, + _name_error, + ) in expression_evaluator.eval_expressions_by_account( + expressions, locals_dict + ): + for drilldown_arg in drilldown_args: + if not drilldown_arg: + continue + drilldown_arg["period_id"] = col_key + drilldown_arg["kpi_id"] = kpi.id + kpi_matrix.set_values_detail_account( + kpi, col_key, account_id, vals, drilldown_args + ) + + if len(recompute_queue) == 0: + # nothing to recompute, we are done + break + if len(recompute_queue) == len(compute_queue): + # could not compute anything in this iteration + # (ie real Name errors or cyclic dependency) + # so we stop trying + break + # try again + compute_queue = recompute_queue + recompute_queue = [] + + def declare_and_compute_period( + self, + kpi_matrix, + col_key, + col_label, + col_description, + aep, + date_from, + date_to, + target_move, + subkpis_filter=None, + get_additional_move_line_filter=None, + get_additional_query_filter=None, + locals_dict=None, + aml_model=None, + no_auto_expand_accounts=False, + ): + _logger.warning( + "declare_and_compute_period() is deprecated, " + "use _declare_and_compute_period() instead" + ) + expression_evaluator = ExpressionEvaluator( + aep, + date_from, + date_to, + target_move, + get_additional_move_line_filter() + if get_additional_move_line_filter + else None, + aml_model, + ) + return self._declare_and_compute_period( + expression_evaluator, + kpi_matrix, + col_key, + col_label, + col_description, + subkpis_filter, + get_additional_query_filter, + locals_dict, + no_auto_expand_accounts, + ) + + def _declare_and_compute_period( + self, + expression_evaluator, + kpi_matrix, + col_key, + col_label, + col_description, + subkpis_filter=None, + get_additional_query_filter=None, + locals_dict=None, + no_auto_expand_accounts=False, + ): + """Evaluate a report for a given period, populating a KpiMatrix. + + :param expression_evaluator: an ExpressionEvaluator instance + :param kpi_matrix: the KpiMatrix object to be populated created + with prepare_kpi_matrix() + :param col_key: the period key to use when populating the KpiMatrix + :param subkpis_filter: a list of subkpis to include in the evaluation + (if empty, use all subkpis) + :param get_additional_query_filter: a bound method that takes a single + query argument and returns a + domain compatible with the query + underlying model + :param locals_dict: personalized locals dictionary used as evaluation + context for the KPI expressions + :param no_auto_expand_accounts: disable expansion of account details + """ + self.ensure_one() + + # prepare the localsdict + if locals_dict is None: + locals_dict = {} + + # Evaluate subreports + for subreport in self.subreport_ids: + subreport_locals_dict = subreport.subreport_id._evaluate( + expression_evaluator, subkpis_filter, get_additional_query_filter + ) + locals_dict[subreport.name] = AutoStruct( + **{ + srk.name: subreport_locals_dict.get(srk.name, AccountingNone) + for srk in subreport.subreport_id.kpi_ids + } + ) + + locals_dict.update(self.prepare_locals_dict()) + locals_dict["date_from"] = fields.Date.from_string( + expression_evaluator.date_from + ) + locals_dict["date_to"] = fields.Date.from_string(expression_evaluator.date_to) + + # fetch non-accounting queries + locals_dict.update( + self._fetch_queries( + expression_evaluator.date_from, + expression_evaluator.date_to, + get_additional_query_filter, + ) + ) + + # use AEP to do the accounting queries + expression_evaluator.aep_do_queries() + + self._declare_and_compute_col( + expression_evaluator, + kpi_matrix, + col_key, + col_label, + col_description, + subkpis_filter, + locals_dict, + no_auto_expand_accounts, + ) + + def get_kpis_by_account_id(self, company): + """ Return { account_id: set(kpi) } """ + aep = self._prepare_aep(company) + res = defaultdict(set) + for kpi in self.kpi_ids: + for expression in kpi.expression_ids: + if not expression.name: + continue + account_ids = aep.get_account_ids_for_expr(expression.name) + for account_id in account_ids: + res[account_id].add(kpi) + return res + + def evaluate( + self, + aep, + date_from, + date_to, + target_move="posted", + aml_model=None, + subkpis_filter=None, + get_additional_move_line_filter=None, + get_additional_query_filter=None, + ): + """Simplified method to evaluate a report over a time period. + + :param aep: an AccountingExpressionProcessor instance created + using _prepare_aep() + :param date_from, date_to: the starting and ending date + :param target_move: all|posted + :param aml_model: the name of a model that is compatible with + account.move.line + :param subkpis_filter: a list of subkpis to include in the evaluation + (if empty, use all subkpis) + :param get_additional_move_line_filter: a bound method that takes + no arguments and returns + a domain compatible with + account.move.line + :param get_additional_query_filter: a bound method that takes a single + query argument and returns a + domain compatible with the query + underlying model + :return: a dictionary where keys are KPI names, and values are the + evaluated results; some additional keys might be present: + these should be ignored as they might be removed in + the future. + """ + expression_evaluator = ExpressionEvaluator( + aep, + date_from, + date_to, + target_move, + get_additional_move_line_filter() + if get_additional_move_line_filter + else None, + aml_model, + ) + return self._evaluate(expression_evaluator, subkpis_filter) + + def _evaluate( + self, + expression_evaluator, + subkpis_filter=None, + get_additional_query_filter=None, + ): + locals_dict = {} + kpi_matrix = self.prepare_kpi_matrix() + self._declare_and_compute_period( + expression_evaluator, + kpi_matrix, + col_key=1, + col_label="", + col_description="", + subkpis_filter=subkpis_filter, + get_additional_query_filter=get_additional_query_filter, + locals_dict=locals_dict, + no_auto_expand_accounts=True, + ) + return locals_dict diff --git a/odex25_accounting/mis_builder/models/mis_report_instance.py b/odex25_accounting/mis_builder/models/mis_report_instance.py new file mode 100644 index 000000000..30e238f11 --- /dev/null +++ b/odex25_accounting/mis_builder/models/mis_report_instance.py @@ -0,0 +1,908 @@ +# Copyright 2014 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import datetime +import logging + +from dateutil.relativedelta import relativedelta + +from odoo import _, api, fields, models +from odoo.exceptions import UserError, ValidationError + +from .aep import AccountingExpressionProcessor as AEP +from .expression_evaluator import ExpressionEvaluator + +_logger = logging.getLogger(__name__) + + +SRC_ACTUALS = "actuals" +SRC_ACTUALS_ALT = "actuals_alt" +SRC_CMPCOL = "cmpcol" +SRC_SUMCOL = "sumcol" + +MODE_NONE = "none" +MODE_FIX = "fix" +MODE_REL = "relative" + + +class DateFilterRequired(ValidationError): + pass + + +class DateFilterForbidden(ValidationError): + pass + + +class MisReportInstancePeriodSum(models.Model): + + _name = "mis.report.instance.period.sum" + _description = "MIS Report Instance Period Sum" + + period_id = fields.Many2one( + comodel_name="mis.report.instance.period", + string="Parent column", + ondelete="cascade", + required=True, + ) + period_to_sum_id = fields.Many2one( + comodel_name="mis.report.instance.period", + string="Column", + ondelete="restrict", + required=True, + ) + sign = fields.Selection([("+", "+"), ("-", "-")], required=True, default="+") + + @api.constrains("period_id", "period_to_sum_id") + def _check_period_to_sum(self): + for rec in self: + if rec.period_id == rec.period_to_sum_id: + raise ValidationError( + _("You cannot sum period %s with itself.") % rec.period_id.name + ) + + +class MisReportInstancePeriod(models.Model): + """A MIS report instance has the logic to compute + a report template for a given date period. + + Periods have a duration (day, week, fiscal period) and + are defined as an offset relative to a pivot date. + """ + + @api.depends( + "report_instance_id.pivot_date", + "report_instance_id.comparison_mode", + "date_range_type_id", + "type", + "offset", + "duration", + "mode", + "manual_date_from", + "manual_date_to", + "is_ytd", + ) + def _compute_dates(self): + for record in self: + record.date_from = False + record.date_to = False + record.valid = False + report = record.report_instance_id + d = fields.Date.from_string(report.pivot_date) + if not report.comparison_mode: + record.date_from = report.date_from + record.date_to = report.date_to + record.valid = record.date_from and record.date_to + elif record.mode == MODE_NONE: + record.date_from = False + record.date_to = False + record.valid = True + elif record.mode == MODE_FIX: + record.date_from = record.manual_date_from + record.date_to = record.manual_date_to + record.valid = record.date_from and record.date_to + elif record.mode == MODE_REL and record.type == "d": + date_from = d + datetime.timedelta(days=record.offset) + date_to = date_from + datetime.timedelta(days=record.duration - 1) + record.date_from = fields.Date.to_string(date_from) + record.date_to = fields.Date.to_string(date_to) + record.valid = True + elif record.mode == MODE_REL and record.type == "w": + date_from = d - datetime.timedelta(d.weekday()) + date_from = date_from + datetime.timedelta(days=record.offset * 7) + date_to = date_from + datetime.timedelta(days=(7 * record.duration) - 1) + record.date_from = fields.Date.to_string(date_from) + record.date_to = fields.Date.to_string(date_to) + record.valid = True + elif record.mode == MODE_REL and record.type == "m": + date_from = d.replace(day=1) + date_from = date_from + relativedelta(months=record.offset) + date_to = ( + date_from + + relativedelta(months=record.duration - 1) + + relativedelta(day=31) + ) + record.date_from = fields.Date.to_string(date_from) + record.date_to = fields.Date.to_string(date_to) + record.valid = True + elif record.mode == MODE_REL and record.type == "y": + date_from = d.replace(month=1, day=1) + date_from = date_from + relativedelta(years=record.offset) + date_to = date_from + relativedelta(years=record.duration - 1) + date_to = date_to.replace(month=12, day=31) + record.date_from = fields.Date.to_string(date_from) + record.date_to = fields.Date.to_string(date_to) + record.valid = True + elif record.mode == MODE_REL and record.type == "date_range": + date_range_obj = record.env["date.range"] + current_periods = date_range_obj.search( + [ + ("type_id", "=", record.date_range_type_id.id), + ("date_start", "<=", d), + ("date_end", ">=", d), + "|", + ("company_id", "=", False), + ( + "company_id", + "in", + record.report_instance_id.query_company_ids.ids, + ), + ] + ) + if current_periods: + # TODO we take the first date range we found as current + # this may be surprising if several companies + # have overlapping date ranges with different dates + current_period = current_periods[0] + all_periods = date_range_obj.search( + [ + ("type_id", "=", current_period.type_id.id), + ("company_id", "=", current_period.company_id.id), + ], + order="date_start", + ) + p = all_periods.ids.index(current_period.id) + record.offset + if p >= 0 and p + record.duration <= len(all_periods): + periods = all_periods[p : p + record.duration] + record.date_from = periods[0].date_start + record.date_to = periods[-1].date_end + record.valid = True + if record.mode == MODE_REL and record.valid and record.is_ytd: + record.date_from = fields.Date.from_string(record.date_to).replace( + day=1, month=1 + ) + + _name = "mis.report.instance.period" + _description = "MIS Report Instance Period" + + name = fields.Char(size=32, required=True, string="Label", translate=True) + mode = fields.Selection( + [ + (MODE_FIX, "Fixed dates"), + (MODE_REL, "Relative to report base date"), + (MODE_NONE, "No date filter"), + ], + required=True, + default=MODE_FIX, + ) + type = fields.Selection( + [ + ("d", _("Day")), + ("w", _("Week")), + ("m", _("Month")), + ("y", _("Year")), + ("date_range", _("Date Range")), + ], + string="Period type", + ) + is_ytd = fields.Boolean( + default=False, + string="Year to date", + help="Forces the start date to Jan 1st of the relevant year", + ) + date_range_type_id = fields.Many2one( + comodel_name="date.range.type", + string="Date Range Type", + domain=[("allow_overlap", "=", False)], + ) + offset = fields.Integer( + string="Offset", help="Offset from current period", default=-1 + ) + duration = fields.Integer(string="Duration", help="Number of periods", default=1) + date_from = fields.Date(compute="_compute_dates", string="From (computed)") + date_to = fields.Date(compute="_compute_dates", string="To (computed)") + manual_date_from = fields.Date(string="From") + manual_date_to = fields.Date(string="To") + date_range_id = fields.Many2one(comodel_name="date.range", string="Date Range") + valid = fields.Boolean(compute="_compute_dates", type="boolean", string="Valid") + sequence = fields.Integer(string="Sequence", default=100) + report_instance_id = fields.Many2one( + comodel_name="mis.report.instance", + string="Report Instance", + required=True, + ondelete="cascade", + ) + report_id = fields.Many2one(related="report_instance_id.report_id") + normalize_factor = fields.Integer( + string="Factor", + help="Factor to use to normalize the period (used in comparison", + default=1, + ) + subkpi_ids = fields.Many2many("mis.report.subkpi", string="Sub KPI Filter") + + source = fields.Selection( + [ + (SRC_ACTUALS, "Actuals"), + (SRC_ACTUALS_ALT, "Actuals (alternative)"), + (SRC_SUMCOL, "Sum columns"), + (SRC_CMPCOL, "Compare columns"), + ], + default=SRC_ACTUALS, + required=True, + help="Actuals: current data, from accounting and other queries.\n" + "Actuals (alternative): current data from an " + "alternative source (eg a database view providing look-alike " + "account move lines).\n" + "Sum columns: summation (+/-) of other columns.\n" + "Compare to column: compare to other column.\n", + ) + source_aml_model_id = fields.Many2one( + comodel_name="ir.model", + string="Move lines source", + domain=[ + ("field_id.name", "=", "debit"), + ("field_id.name", "=", "credit"), + ("field_id.name", "=", "account_id"), + ("field_id.name", "=", "date"), + ("field_id.name", "=", "company_id"), + ("field_id.model_id.model", "!=", "account.move.line"), + ], + help="A 'move line like' model, ie having at least debit, credit, " + "date, account_id and company_id fields.", + ) + source_aml_model_name = fields.Char( + string="Move lines source model name", related="source_aml_model_id.model" + ) + source_sumcol_ids = fields.One2many( + comodel_name="mis.report.instance.period.sum", + inverse_name="period_id", + string="Columns to sum", + ) + source_sumcol_accdet = fields.Boolean(string="Sum account details") + source_cmpcol_from_id = fields.Many2one( + comodel_name="mis.report.instance.period", string="versus" + ) + source_cmpcol_to_id = fields.Many2one( + comodel_name="mis.report.instance.period", string="Compare" + ) + allowed_cmpcol_ids = fields.Many2many( + comodel_name="mis.report.instance.period", compute="_compute_allowed_cmpcol_ids" + ) + # filters + analytic_account_id = fields.Many2one( + comodel_name="account.analytic.account", + string="Analytic Account", + help=( + "Filter column on journal entries that match this analytic account." + "This filter is combined with a AND with the report-level filters " + "and cannot be modified in the preview." + ), + ) + analytic_group_id = fields.Many2one( + comodel_name="account.analytic.group", + string="Analytic Account Group", + help=( + "Filter column on journal entries that match this analytic account " + "group. This filter is combined with a AND with the report-level " + "filters and cannot be modified in the preview." + ), + ) + analytic_tag_ids = fields.Many2many( + comodel_name="account.analytic.tag", + string="Analytic Tags", + help=( + "Filter column on journal entries that have all these analytic tags." + "This filter is combined with a AND with the report-level filters " + "and cannot be modified in the preview." + ), + ) + + _order = "sequence, id" + + _sql_constraints = [ + ("duration", "CHECK (duration>0)", "Wrong duration, it must be positive!"), + ( + "normalize_factor", + "CHECK (normalize_factor>0)", + "Wrong normalize factor, it must be positive!", + ), + ( + "name_unique", + "unique(name, report_instance_id)", + "Period name should be unique by report", + ), + ] + + @api.depends("report_instance_id") + def _compute_allowed_cmpcol_ids(self): + """Compute actual records while in NewId context""" + for record in self: + record.allowed_cmpcol_ids = record.report_instance_id.period_ids - record + + @api.constrains("source_aml_model_id") + def _check_source_aml_model_id(self): + for record in self: + if record.source_aml_model_id: + record_model = record.source_aml_model_id.field_id.filtered( + lambda r: r.name == "account_id" + ).relation + report_account_model = record.report_id.account_model + if record_model != report_account_model: + raise ValidationError( + _( + "Actual (alternative) models used in columns must " + "have the same account model in the Account field and must " + "be the same defined in the " + "report template: %s" + ) + % report_account_model + ) + + @api.onchange("date_range_id") + def _onchange_date_range(self): + if self.date_range_id: + self.manual_date_from = self.date_range_id.date_start + self.manual_date_to = self.date_range_id.date_end + + @api.onchange("manual_date_from", "manual_date_to") + def _onchange_dates(self): + if self.date_range_id: + if ( + self.manual_date_from != self.date_range_id.date_start + or self.manual_date_to != self.date_range_id.date_end + ): + self.date_range_id = False + + @api.onchange("source") + def _onchange_source(self): + if self.source in (SRC_SUMCOL, SRC_CMPCOL): + self.mode = MODE_NONE + + def _get_aml_model_name(self): + self.ensure_one() + if self.source == SRC_ACTUALS: + return self.report_id.move_lines_source.model + elif self.source == SRC_ACTUALS_ALT: + return self.source_aml_model_name + return False + + @api.model + def _get_filter_domain_from_context(self): + filters = [] + mis_report_filters = self.env.context.get("mis_report_filters", {}) + for filter_name, domain in mis_report_filters.items(): + if domain: + value = domain.get("value") + operator = domain.get("operator", "=") + # Operator = 'all' when coming from JS widget + if operator == "all": + if not isinstance(value, list): + value = [value] + for m in value: + filters.append((filter_name, "in", [m])) + else: + filters.append((filter_name, operator, value)) + return filters + + def _get_additional_move_line_filter(self): + """Prepare a filter to apply on all move lines + + This filter is applied with a AND operator on all + accounting expression domains. This hook is intended + to be inherited, and is useful to implement filtering + on analytic dimensions or operational units. + + The default filter is built from a ``mis_report_filters`` context + key, which is a list set by the analytic filtering mechanism + of the mis report widget:: + + [(field_name, {'value': value, 'operator': operator})] + + Returns an Odoo domain expression (a python list) + compatible with account.move.line.""" + self.ensure_one() + domain = self._get_filter_domain_from_context() + if ( + self._get_aml_model_name() == "account.move.line" + and self.report_instance_id.target_move == "posted" + ): + domain.extend([("move_id.state", "=", "posted")]) + if self.analytic_account_id: + domain.append(("analytic_account_id", "=", self.analytic_account_id.id)) + if self.analytic_group_id: + domain.append( + ("analytic_account_id.group_id", "=", self.analytic_group_id.id) + ) + for tag in self.analytic_tag_ids: + domain.append(("analytic_tag_ids", "=", tag.id)) + return domain + + def _get_additional_query_filter(self, query): + """Prepare an additional filter to apply on the query + + This filter is combined to the query domain with a AND + operator. This hook is intended + to be inherited, and is useful to implement filtering + on analytic dimensions or operational units. + + Returns an Odoo domain expression (a python list) + compatible with the model of the query.""" + self.ensure_one() + return [] + + @api.constrains("mode", "source") + def _check_mode_source(self): + for rec in self: + if rec.source in (SRC_ACTUALS, SRC_ACTUALS_ALT): + if rec.mode == MODE_NONE: + raise DateFilterRequired( + _("A date filter is mandatory for this source " "in column %s.") + % rec.name + ) + elif rec.source in (SRC_SUMCOL, SRC_CMPCOL): + if rec.mode != MODE_NONE: + raise DateFilterForbidden( + _("No date filter is allowed for this source " "in column %s.") + % rec.name + ) + + @api.constrains("source", "source_cmpcol_from_id", "source_cmpcol_to_id") + def _check_source_cmpcol(self): + for rec in self: + if rec.source == SRC_CMPCOL: + if not rec.source_cmpcol_from_id or not rec.source_cmpcol_to_id: + raise ValidationError( + _("Please provide both columns to compare in %s.") % rec.name + ) + if rec.source_cmpcol_from_id == rec or rec.source_cmpcol_to_id == rec: + raise ValidationError( + _("Column %s cannot be compared to itrec.") % rec.name + ) + if ( + rec.source_cmpcol_from_id.report_instance_id + != rec.report_instance_id + or rec.source_cmpcol_to_id.report_instance_id + != rec.report_instance_id + ): + raise ValidationError( + _("Columns to compare must belong to the same report " "in %s") + % rec.name + ) + + def copy_data(self, default=None): + if self.source == SRC_CMPCOL: + # While duplicating a MIS report instance, comparison columns are + # ignored because they would raise an error, as they keep the old + # `source_cmpcol_from_id` and `source_cmpcol_to_id` from the + # original record. + return [ + False, + ] + return super().copy_data(default=default) + + +class MisReportInstance(models.Model): + """The MIS report instance combines everything to compute + a MIS report template for a set of periods.""" + + @api.depends("date") + def _compute_pivot_date(self): + for record in self: + if record.date: + record.pivot_date = record.date + else: + record.pivot_date = fields.Date.context_today(record) + + _name = "mis.report.instance" + _description = "MIS Report Instance" + + name = fields.Char(required=True, string="Name", translate=True) + description = fields.Char(related="report_id.description", readonly=True) + date = fields.Date( + string="Base date", help="Report base date " "(leave empty to use current date)" + ) + pivot_date = fields.Date(compute="_compute_pivot_date", string="Pivot date") + report_id = fields.Many2one("mis.report", required=True, string="Report") + period_ids = fields.One2many( + comodel_name="mis.report.instance.period", + inverse_name="report_instance_id", + required=True, + string="Periods", + copy=True, + ) + target_move = fields.Selection( + [("posted", "All Posted Entries"), ("all", "All Entries")], + string="Target Moves", + required=True, + default="posted", + ) + company_id = fields.Many2one( + comodel_name="res.company", + string="Company", + default=lambda self: self.env.company, + required=True, + ) + multi_company = fields.Boolean( + string="Multiple companies", + help="Check if you wish to specify " + "children companies to be searched for data.", + default=False, + ) + company_ids = fields.Many2many( + comodel_name="res.company", + string="Companies", + help="Select companies for which data will be searched.", + ) + query_company_ids = fields.Many2many( + comodel_name="res.company", + compute="_compute_query_company_ids", + help="Companies for which data will be searched.", + ) + currency_id = fields.Many2one( + comodel_name="res.currency", + string="Currency", + help="Select target currency for the report. " + "Required if companies have different currencies.", + required=False, + ) + landscape_pdf = fields.Boolean(string="Landscape PDF") + no_auto_expand_accounts = fields.Boolean(string="Disable account details expansion") + display_columns_description = fields.Boolean( + help="Display the date range details in the column headers." + ) + comparison_mode = fields.Boolean( + compute="_compute_comparison_mode", inverse="_inverse_comparison_mode" + ) + date_range_id = fields.Many2one(comodel_name="date.range", string="Date Range") + date_from = fields.Date(string="From") + date_to = fields.Date(string="To") + temporary = fields.Boolean(default=False) + analytic_account_id = fields.Many2one( + comodel_name="account.analytic.account", string="Analytic Account" + ) + analytic_group_id = fields.Many2one( + comodel_name="account.analytic.group", + string="Analytic Account Group", + ) + analytic_tag_ids = fields.Many2many( + comodel_name="account.analytic.tag", string="Analytic Tags" + ) + hide_analytic_filters = fields.Boolean(default=True) + + @api.onchange("company_id", "multi_company") + def _onchange_company(self): + if self.company_id and self.multi_company: + self.company_ids = self.env["res.company"].search( + [("id", "child_of", self.company_id.id)] + ) + else: + self.company_ids = False + + @api.depends("multi_company", "company_id", "company_ids") + def _compute_query_company_ids(self): + for rec in self: + if rec.multi_company: + rec.query_company_ids = rec.company_ids or rec.company_id + else: + rec.query_company_ids = rec.company_id + + @api.model + def get_filter_descriptions_from_context(self): + filters = self.env.context.get("mis_report_filters", {}) + analytic_account_id = filters.get("analytic_account_id", {}).get("value") + filter_descriptions = [] + if analytic_account_id: + analytic_account = self.env["account.analytic.account"].browse( + analytic_account_id + ) + filter_descriptions.append( + _("Analytic Account: %s") % analytic_account.display_name + ) + analytic_group_id = filters.get("analytic_account_id.group_id", {}).get("value") + if analytic_group_id: + analytic_group = self.env["account.analytic.group"].browse( + analytic_group_id + ) + filter_descriptions.append( + _("Analytic Account Group: %s") % analytic_group.display_name + ) + analytic_tag_value = filters.get("analytic_tag_ids", {}).get("value") + if analytic_tag_value: + # TODO 14 we need a test to cover this + analytic_tag_names = self.resolve_2many_commands( + "analytic_tag_ids", analytic_tag_value, ["name"] + ) + filter_descriptions.append( + _("Analytic Tags: %s") + % ", ".join([rec["name"] for rec in analytic_tag_names]) + ) + return filter_descriptions + + def save_report(self): + self.ensure_one() + self.write({"temporary": False}) + action = self.env.ref("mis_builder.mis_report_instance_view_action") + res = action.read()[0] + view = self.env.ref("mis_builder.mis_report_instance_view_form") + res.update({"views": [(view.id, "form")], "res_id": self.id}) + return res + + @api.model + def _vacuum_report(self, hours=24): + clear_date = fields.Datetime.to_string( + datetime.datetime.now() - datetime.timedelta(hours=hours) + ) + reports = self.search( + [("write_date", "<", clear_date), ("temporary", "=", True)] + ) + _logger.debug("Vacuum %s Temporary MIS Builder Report", len(reports)) + return reports.unlink() + + def copy(self, default=None): + self.ensure_one() + default = dict(default or {}) + default["name"] = _("%s (copy)") % self.name + return super(MisReportInstance, self).copy(default) + + def _format_date(self, date): + # format date following user language + lang_model = self.env["res.lang"] + lang = lang_model._lang_get(self.env.user.lang) + date_format = lang.date_format + return datetime.datetime.strftime(fields.Date.from_string(date), date_format) + + @api.depends("date_from") + def _compute_comparison_mode(self): + for instance in self: + instance.comparison_mode = bool(instance.period_ids) and not bool( + instance.date_from + ) + + def _inverse_comparison_mode(self): + for record in self: + if not record.comparison_mode: + if not record.date_from: + record.date_from = fields.Date.context_today(self) + if not record.date_to: + record.date_to = fields.Date.context_today(self) + record.period_ids.unlink() + record.write({"period_ids": [(0, 0, {"name": "Default"})]}) + else: + record.date_from = None + record.date_to = None + + @api.onchange("date_range_id") + def _onchange_date_range(self): + if self.date_range_id: + self.date_from = self.date_range_id.date_start + self.date_to = self.date_range_id.date_end + + @api.onchange("date_from", "date_to") + def _onchange_dates(self): + if self.date_range_id: + if ( + self.date_from != self.date_range_id.date_start + or self.date_to != self.date_range_id.date_end + ): + self.date_range_id = False + + def _add_analytic_filters_to_context(self, context): + self.ensure_one() + if self.analytic_account_id: + context["mis_report_filters"]["analytic_account_id"] = { + "value": self.analytic_account_id.id, + "operator": "=", + } + if self.analytic_group_id: + context["mis_report_filters"]["analytic_account_id.group_id"] = { + "value": self.analytic_group_id.id, + "operator": "=", + } + if self.analytic_tag_ids: + context["mis_report_filters"]["analytic_tag_ids"] = { + "value": self.analytic_tag_ids.ids, + "operator": "all", + } + + def _context_with_filters(self): + self.ensure_one() + if "mis_report_filters" in self.env.context: + # analytic filters are already in context, do nothing + return self.env.context + context = dict(self.env.context, mis_report_filters={}) + self._add_analytic_filters_to_context(context) + return context + + def preview(self): + self.ensure_one() + view_id = self.env.ref("mis_builder." "mis_report_instance_result_view_form") + return { + "type": "ir.actions.act_window", + "res_model": "mis.report.instance", + "res_id": self.id, + "view_mode": "form", + "view_id": view_id.id, + "target": "current", + "context": self._context_with_filters(), + } + + def print_pdf(self): + self.ensure_one() + context = dict(self._context_with_filters(), landscape=self.landscape_pdf) + return ( + self.env.ref("mis_builder.qweb_pdf_export") + .with_context(context) + .report_action(self, data=dict(dummy=True)) # required to propagate context + ) + + def export_xls(self): + self.ensure_one() + context = dict(self._context_with_filters()) + return ( + self.env.ref("mis_builder.xls_export") + .with_context(context) + .report_action(self, data=dict(dummy=True)) # required to propagate context + ) + + def display_settings(self): + assert len(self.ids) <= 1 + view_id = self.env.ref("mis_builder.mis_report_instance_view_form") + return { + "type": "ir.actions.act_window", + "res_model": "mis.report.instance", + "res_id": self.id if self.id else False, + "view_mode": "form", + "views": [(view_id.id, "form")], + "view_id": view_id.id, + "target": "current", + } + + def _add_column_move_lines(self, aep, kpi_matrix, period, label, description): + if not period.date_from or not period.date_to: + raise UserError( + _("Column %s with move lines source must have from/to dates.") + % (period.name,) + ) + expression_evaluator = ExpressionEvaluator( + aep, + period.date_from, + period.date_to, + None, # target_move now part of additional_move_line_filter + period._get_additional_move_line_filter(), + period._get_aml_model_name(), + ) + self.report_id._declare_and_compute_period( + expression_evaluator, + kpi_matrix, + period.id, + label, + description, + period.subkpi_ids, + period._get_additional_query_filter, + no_auto_expand_accounts=self.no_auto_expand_accounts, + ) + + def _add_column_sumcol(self, aep, kpi_matrix, period, label, description): + kpi_matrix.declare_sum( + period.id, + [(c.sign, c.period_to_sum_id.id) for c in period.source_sumcol_ids], + label, + description, + period.source_sumcol_accdet, + ) + + def _add_column_cmpcol(self, aep, kpi_matrix, period, label, description): + kpi_matrix.declare_comparison( + period.id, + period.source_cmpcol_to_id.id, + period.source_cmpcol_from_id.id, + label, + description, + ) + + def _add_column(self, aep, kpi_matrix, period, label, description): + if period.source == SRC_ACTUALS: + return self._add_column_move_lines( + aep, kpi_matrix, period, label, description + ) + elif period.source == SRC_ACTUALS_ALT: + return self._add_column_move_lines( + aep, kpi_matrix, period, label, description + ) + elif period.source == SRC_SUMCOL: + return self._add_column_sumcol(aep, kpi_matrix, period, label, description) + elif period.source == SRC_CMPCOL: + return self._add_column_cmpcol(aep, kpi_matrix, period, label, description) + + def _compute_matrix(self): + """Compute a report and return a KpiMatrix. + + The key attribute of the matrix columns (KpiMatrixCol) + is guaranteed to be the id of the mis.report.instance.period. + """ + self.ensure_one() + aep = self.report_id._prepare_aep(self.query_company_ids, self.currency_id) + kpi_matrix = self.report_id.prepare_kpi_matrix(self.multi_company) + for period in self.period_ids: + description = None + if period.mode == MODE_NONE: + pass + elif not self.display_columns_description: + pass + elif period.date_from == period.date_to and period.date_from: + description = self._format_date(period.date_from) + elif period.date_from and period.date_to: + date_from = self._format_date(period.date_from) + date_to = self._format_date(period.date_to) + description = _("from %s to %s") % (date_from, date_to) + self._add_column(aep, kpi_matrix, period, period.name, description) + kpi_matrix.compute_comparisons() + kpi_matrix.compute_sums() + return kpi_matrix + + def compute(self): + self.ensure_one() + kpi_matrix = self._compute_matrix() + return kpi_matrix.as_dict() + + def drilldown(self, arg): + self.ensure_one() + period_id = arg.get("period_id") + expr = arg.get("expr") + account_id = arg.get("account_id") + if period_id and expr and AEP.has_account_var(expr): + period = self.env["mis.report.instance.period"].browse(period_id) + aep = AEP( + self.query_company_ids, self.currency_id, self.report_id.account_model + ) + aep.parse_expr(expr) + aep.done_parsing() + domain = aep.get_aml_domain_for_expr( + expr, + period.date_from, + period.date_to, + None, # target_move now part of additional_move_line_filter + account_id, + ) + domain.extend(period._get_additional_move_line_filter()) + return { + "name": self._get_drilldown_action_name(arg), + "domain": domain, + "type": "ir.actions.act_window", + "res_model": period._get_aml_model_name(), + "views": [[False, "list"], [False, "form"]], + "view_mode": "list", + "target": "current", + "context": {"active_test": False}, + } + else: + return False + + def _get_drilldown_action_name(self, arg): + kpi_id = arg.get("kpi_id") + kpi = self.env["mis.report.kpi"].browse(kpi_id) + period_id = arg.get("period_id") + period = self.env["mis.report.instance.period"].browse(period_id) + account_id = arg.get("account_id") + + if account_id: + account = self.env[self.report_id.account_model].browse(account_id) + return "{kpi} - {account} - {period}".format( + kpi=kpi.description, + account=account.display_name, + period=period.display_name, + ) + else: + return "{kpi} - {period}".format( + kpi=kpi.description, + period=period.display_name, + ) diff --git a/odex25_accounting/mis_builder/models/mis_report_style.py b/odex25_accounting/mis_builder/models/mis_report_style.py new file mode 100644 index 000000000..c206f2cf8 --- /dev/null +++ b/odex25_accounting/mis_builder/models/mis_report_style.py @@ -0,0 +1,311 @@ +# Copyright 2016 Therp BV () +# Copyright 2016 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import sys + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + +from .accounting_none import AccountingNone +from .data_error import DataError + +if sys.version_info.major >= 3: + unicode = str + + +class PropertyDict(dict): + def __getattr__(self, name): + return self.get(name) + + def copy(self): # pylint: disable=copy-wo-api-one,method-required-super + return PropertyDict(self) + + +PROPS = [ + "color", + "background_color", + "font_style", + "font_weight", + "font_size", + "indent_level", + "prefix", + "suffix", + "dp", + "divider", + "hide_empty", + "hide_always", +] + +TYPE_NUM = "num" +TYPE_PCT = "pct" +TYPE_STR = "str" + +CMP_DIFF = "diff" +CMP_PCT = "pct" +CMP_NONE = "none" + + +class MisReportKpiStyle(models.Model): + + _name = "mis.report.style" + _description = "MIS Report Style" + + @api.constrains("indent_level") + def check_positive_val(self): + for record in self: + if record.indent_level < 0: + raise ValidationError( + _("Indent level must be greater than " "or equal to 0") + ) + + _font_style_selection = [("normal", "Normal"), ("italic", "Italic")] + + _font_weight_selection = [("nornal", "Normal"), ("bold", "Bold")] + + _font_size_selection = [ + ("medium", "medium"), + ("xx-small", "xx-small"), + ("x-small", "x-small"), + ("small", "small"), + ("large", "large"), + ("x-large", "x-large"), + ("xx-large", "xx-large"), + ] + + _font_size_to_xlsx_size = { + "medium": 11, + "xx-small": 5, + "x-small": 7, + "small": 9, + "large": 13, + "x-large": 15, + "xx-large": 17, + } + + # style name + # TODO enforce uniqueness + name = fields.Char(string="Style name", required=True) + + # color + color_inherit = fields.Boolean(default=True) + color = fields.Char( + string="Text color", + help="Text color in valid RGB code (from #000000 to #FFFFFF)", + default="#000000", + ) + background_color_inherit = fields.Boolean(default=True) + background_color = fields.Char( + help="Background color in valid RGB code (from #000000 to #FFFFFF)", + default="#FFFFFF", + ) + # font + font_style_inherit = fields.Boolean(default=True) + font_style = fields.Selection(selection=_font_style_selection) + font_weight_inherit = fields.Boolean(default=True) + font_weight = fields.Selection(selection=_font_weight_selection) + font_size_inherit = fields.Boolean(default=True) + font_size = fields.Selection(selection=_font_size_selection) + # indent + indent_level_inherit = fields.Boolean(default=True) + indent_level = fields.Integer() + # number format + prefix_inherit = fields.Boolean(default=True) + prefix = fields.Char(size=16, string="Prefix") + suffix_inherit = fields.Boolean(default=True) + suffix = fields.Char(size=16, string="Suffix") + dp_inherit = fields.Boolean(default=True) + dp = fields.Integer(string="Rounding", default=0) + divider_inherit = fields.Boolean(default=True) + divider = fields.Selection( + [ + ("1e-6", _("µ")), + ("1e-3", _("m")), + ("1", _("1")), + ("1e3", _("k")), + ("1e6", _("M")), + ], + string="Factor", + default="1", + ) + hide_empty_inherit = fields.Boolean(default=True) + hide_empty = fields.Boolean(default=False) + hide_always_inherit = fields.Boolean(default=True) + hide_always = fields.Boolean(default=False) + + @api.model + def merge(self, styles): + """Merge several styles, giving priority to the last. + + Returns a PropertyDict of style properties. + """ + r = PropertyDict() + for style in styles: + if not style: + continue + if isinstance(style, dict): + r.update(style) + else: + for prop in PROPS: + inherit = getattr(style, prop + "_inherit", None) + if not inherit: + value = getattr(style, prop) + r[prop] = value + return r + + @api.model + def render(self, lang, style_props, type, value, sign="-"): + if type == TYPE_NUM: + return self.render_num( + lang, + value, + style_props.divider, + style_props.dp, + style_props.prefix, + style_props.suffix, + sign=sign, + ) + elif type == TYPE_PCT: + return self.render_pct(lang, value, style_props.dp, sign=sign) + else: + return self.render_str(lang, value) + + @api.model + def render_num( + self, lang, value, divider=1.0, dp=0, prefix=None, suffix=None, sign="-" + ): + # format number following user language + if value is None or value is AccountingNone: + return u"" + value = round(value / float(divider or 1), dp or 0) or 0 + r = lang.format("%%%s.%df" % (sign, dp or 0), value, grouping=True) + r = r.replace("-", u"\N{NON-BREAKING HYPHEN}") + if prefix: + r = prefix + u"\N{NO-BREAK SPACE}" + r + if suffix: + r = r + u"\N{NO-BREAK SPACE}" + suffix + return r + + @api.model + def render_pct(self, lang, value, dp=1, sign="-"): + return self.render_num(lang, value, divider=0.01, dp=dp, suffix="%", sign=sign) + + @api.model + def render_str(self, lang, value): + if value is None or value is AccountingNone: + return u"" + return unicode(value) + + @api.model + def compare_and_render( + self, + lang, + style_props, + type, + compare_method, + value, + base_value, + average_value=1, + average_base_value=1, + ): + """ + :param lang: res.lang record + :param style_props: PropertyDict with style properties + :param type: num, pct or str + :param compare_method: diff, pct, none + :param value: value to compare (value - base_value) + :param base_value: value compared with (value - base_value) + :param average_value: value = value / average_value + :param average_base_value: base_value = base_value / average_base_value + :return: tuple with 4 elements + - delta = comparison result (Float or AccountingNone) + - delta_r = delta rendered in formatted string (String) + - delta_style = PropertyDict with style properties + - delta_type = Type of the comparison result (num or pct) + """ + delta = AccountingNone + delta_r = "" + delta_style = style_props.copy() + delta_type = TYPE_NUM + if isinstance(value, DataError) or isinstance(base_value, DataError): + return AccountingNone, "", delta_style, delta_type + if value is None: + value = AccountingNone + if base_value is None: + base_value = AccountingNone + if type == TYPE_PCT: + delta = value - base_value + if delta and round(delta, (style_props.dp or 0) + 2) != 0: + delta_style.update(divider=0.01, prefix="", suffix=_("pp")) + else: + delta = AccountingNone + elif type == TYPE_NUM: + if value and average_value: + # pylint: disable=redefined-variable-type + value = value / float(average_value) + if base_value and average_base_value: + # pylint: disable=redefined-variable-type + base_value = base_value / float(average_base_value) + if compare_method == CMP_DIFF: + delta = value - base_value + if delta and round(delta, style_props.dp or 0) != 0: + pass + else: + delta = AccountingNone + elif compare_method == CMP_PCT: + if base_value and round(base_value, style_props.dp or 0) != 0: + delta = (value - base_value) / abs(base_value) + if delta and round(delta, 3) != 0: + delta_style.update(dp=1) + delta_type = TYPE_PCT + else: + delta = AccountingNone + if delta is not AccountingNone: + delta_r = self.render(lang, delta_style, delta_type, delta, sign="+") + return delta, delta_r, delta_style, delta_type + + @api.model + def to_xlsx_style(self, type, props, no_indent=False): + xlsx_attributes = [ + ("italic", props.font_style == "italic"), + ("bold", props.font_weight == "bold"), + ("size", self._font_size_to_xlsx_size.get(props.font_size, 11)), + ("font_color", props.color), + ("bg_color", props.background_color), + ] + if type == TYPE_NUM: + num_format = u"#,##0" + if props.dp: + num_format += u"." + num_format += u"0" * props.dp + if props.prefix: + num_format = u'"{} "{}'.format(props.prefix, num_format) + if props.suffix: + num_format = u'{}" {}"'.format(num_format, props.suffix) + xlsx_attributes.append(("num_format", num_format)) + elif type == TYPE_PCT: + num_format = u"0" + if props.dp: + num_format += u"." + num_format += u"0" * props.dp + num_format += "%" + xlsx_attributes.append(("num_format", num_format)) + if props.indent_level is not None and not no_indent: + xlsx_attributes.append(("indent", props.indent_level)) + return dict([a for a in xlsx_attributes if a[1] is not None]) + + @api.model + def to_css_style(self, props, no_indent=False): + css_attributes = [ + ("font-style", props.font_style), + ("font-weight", props.font_weight), + ("font-size", props.font_size), + ("color", props.color), + ("background-color", props.background_color), + ] + if props.indent_level is not None and not no_indent: + css_attributes.append(("text-indent", "{}em".format(props.indent_level))) + return ( + "; ".join(["%s: %s" % a for a in css_attributes if a[1] is not None]) + or None + ) diff --git a/odex25_accounting/mis_builder/models/mis_report_subreport.py b/odex25_accounting/mis_builder/models/mis_report_subreport.py new file mode 100644 index 000000000..3f3cdbe2c --- /dev/null +++ b/odex25_accounting/mis_builder/models/mis_report_subreport.py @@ -0,0 +1,66 @@ +# Copyright 2020 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + +from odoo.addons.mis_builder.models.mis_report import _is_valid_python_var + + +class ParentLoopError(ValidationError): + pass + + +class InvalidNameError(ValidationError): + pass + + +class MisReportSubReport(models.Model): + _name = "mis.report.subreport" + _description = "MIS Report - Sub Reports Relation" + + name = fields.Char(required=True) + report_id = fields.Many2one(comodel_name="mis.report", required=True) + subreport_id = fields.Many2one(comodel_name="mis.report", required=True) + + _sql_constraints = [ + ( + "name_unique", + "unique(name, report_id)", + "Subreport name should be unique by report", + ), + ( + "subreport_unique", + "unique(subreport_id, report_id)", + "Should not include the same report more than once as sub report " + "of a given report", + ), + ] + + @api.constrains("name") + def _check_name(self): + for rec in self: + if not _is_valid_python_var(rec.name): + raise InvalidNameError( + _("Subreport name ({}) must be a valid python identifier").format( + rec.name + ) + ) + + @api.constrains("report_id", "subreport_id") + def _check_loop(self): + def _has_subreport(reports, report): + if not reports: + return False + if report in reports: + return True + return any( + _has_subreport(r.subreport_ids.mapped("subreport_id"), report) + for r in reports + ) + + for rec in self: + if _has_subreport(rec.subreport_id, rec.report_id): + raise ParentLoopError(_("Subreport loop detected")) + + # TODO check subkpi compatibility in subreports diff --git a/odex25_accounting/mis_builder/models/mis_safe_eval.py b/odex25_accounting/mis_builder/models/mis_safe_eval.py new file mode 100644 index 000000000..42fa31834 --- /dev/null +++ b/odex25_accounting/mis_builder/models/mis_safe_eval.py @@ -0,0 +1,33 @@ +# Copyright 2016 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import traceback + +from odoo.tools.safe_eval import _BUILTINS, _SAFE_OPCODES, test_expr + +from .data_error import DataError, NameDataError + +__all__ = ["mis_safe_eval"] + + +def mis_safe_eval(expr, locals_dict): + """Evaluate an expression using safe_eval + + Returns the evaluated value or DataError. + + Raises NameError if the evaluation depends on a variable that is not + present in local_dict. + """ + try: + c = test_expr(expr, _SAFE_OPCODES, mode="eval") + globals_dict = {"__builtins__": _BUILTINS} + # pylint: disable=eval-used,eval-referenced + val = eval(c, globals_dict, locals_dict) + except NameError: + val = NameDataError("#NAME", traceback.format_exc()) + except ZeroDivisionError: + # pylint: disable=redefined-variable-type + val = DataError("#DIV/0", traceback.format_exc()) + except Exception: + val = DataError("#ERR", traceback.format_exc()) + return val diff --git a/odex25_accounting/mis_builder/models/prorata_read_group_mixin.py b/odex25_accounting/mis_builder/models/prorata_read_group_mixin.py new file mode 100644 index 000000000..ba3ab08db --- /dev/null +++ b/odex25_accounting/mis_builder/models/prorata_read_group_mixin.py @@ -0,0 +1,96 @@ +# Copyright 2020 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models +from odoo.exceptions import UserError +from odoo.fields import Date + +from .mis_kpi_data import intersect_days + + +class ProRataReadGroupMixin(models.AbstractModel): + _name = "prorata.read_group.mixin" + _description = "Adapt model with date_from/date_to for pro-rata temporis read_group" + + date_from = fields.Date(required=True) + date_to = fields.Date(required=True) + date = fields.Date( + compute=lambda self: None, + search="_search_date", + help=( + "Dummy field that adapts searches on date " + "to searches on date_from/date_to." + ), + ) + + def _search_date(self, operator, value): + if operator in (">=", ">"): + return [("date_to", operator, value)] + elif operator in ("<=", "<"): + return [("date_from", operator, value)] + raise UserError( + _("Unsupported operator %s for searching on date") % (operator,) + ) + + @api.model + def _intersect_days(self, item_dt_from, item_dt_to, dt_from, dt_to): + return intersect_days(item_dt_from, item_dt_to, dt_from, dt_to) + + @api.model + def read_group( + self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True + ): + """Override read_group to perform pro-rata temporis adjustments. + + When read_group is invoked with a domain that filters on + a time period (date >= from and date <= to, or + date_from <= to and date_to >= from), adjust the accumulated + values pro-rata temporis. + """ + date_from = None + date_to = None + assert isinstance(domain, list) + for domain_item in domain: + if isinstance(domain_item, (list, tuple)): + field, op, value = domain_item + if field == "date" and op == ">=": + date_from = value + elif field == "date_to" and op == ">=": + date_from = value + elif field == "date" and op == "<=": + date_to = value + elif field == "date_from" and op == "<=": + date_to = value + if ( + date_from is not None + and date_to is not None + and not any(":" in f for f in fields) + ): + dt_from = Date.from_string(date_from) + dt_to = Date.from_string(date_to) + res = {} + sum_fields = set(fields) - set(groupby) + read_fields = set(fields + ["date_from", "date_to"]) + for item in self.search(domain).read(read_fields): + key = tuple(item[k] for k in groupby) + if key not in res: + res[key] = {k: item[k] for k in groupby} + res[key].update({k: 0.0 for k in sum_fields}) + res_item = res[key] + for sum_field in sum_fields: + item_dt_from = Date.from_string(item["date_from"]) + item_dt_to = Date.from_string(item["date_to"]) + i_days, item_days = self._intersect_days( + item_dt_from, item_dt_to, dt_from, dt_to + ) + res_item[sum_field] += item[sum_field] * i_days / item_days + return res.values() + return super(ProRataReadGroupMixin, self).read_group( + domain, + fields, + groupby, + offset=offset, + limit=limit, + orderby=orderby, + lazy=lazy, + ) diff --git a/odex25_accounting/mis_builder/models/simple_array.py b/odex25_accounting/mis_builder/models/simple_array.py new file mode 100644 index 000000000..507d5a6e0 --- /dev/null +++ b/odex25_accounting/mis_builder/models/simple_array.py @@ -0,0 +1,184 @@ +# Copyright 2014 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +""" A trivial immutable array that supports basic arithmetic operations. + +>>> a = SimpleArray((1.0, 2.0, 3.0)) +>>> b = SimpleArray((4.0, 5.0, 6.0)) +>>> t = (4.0, 5.0, 6.0) +>>> +a +SimpleArray((1.0, 2.0, 3.0)) +>>> -a +SimpleArray((-1.0, -2.0, -3.0)) +>>> a + b +SimpleArray((5.0, 7.0, 9.0)) +>>> b + a +SimpleArray((5.0, 7.0, 9.0)) +>>> a + t +SimpleArray((5.0, 7.0, 9.0)) +>>> t + a +SimpleArray((5.0, 7.0, 9.0)) +>>> a - b +SimpleArray((-3.0, -3.0, -3.0)) +>>> a - t +SimpleArray((-3.0, -3.0, -3.0)) +>>> t - a +SimpleArray((3.0, 3.0, 3.0)) +>>> a * b +SimpleArray((4.0, 10.0, 18.0)) +>>> b * a +SimpleArray((4.0, 10.0, 18.0)) +>>> a * t +SimpleArray((4.0, 10.0, 18.0)) +>>> t * a +SimpleArray((4.0, 10.0, 18.0)) +>>> a / b +SimpleArray((0.25, 0.4, 0.5)) +>>> b / a +SimpleArray((4.0, 2.5, 2.0)) +>>> a / t +SimpleArray((0.25, 0.4, 0.5)) +>>> t / a +SimpleArray((4.0, 2.5, 2.0)) +>>> b / 2 +SimpleArray((2.0, 2.5, 3.0)) +>>> 2 * b +SimpleArray((8.0, 10.0, 12.0)) +>>> 1 - b +SimpleArray((-3.0, -4.0, -5.0)) +>>> b += 2 ; b +SimpleArray((6.0, 7.0, 8.0)) +>>> a / ((1.0, 0.0, 1.0)) +SimpleArray((1.0, DataError('#DIV/0'), 3.0)) +>>> a / 0.0 +SimpleArray((DataError('#DIV/0'), DataError('#DIV/0'), DataError('#DIV/0'))) +>>> a * ((1.0, 'a', 1.0)) +SimpleArray((1.0, DataError('#ERR'), 3.0)) +>>> 6.0 / a +SimpleArray((6.0, 3.0, 2.0)) +>>> Vector = named_simple_array('Vector', ('x', 'y')) +>>> p1 = Vector((1, 2)) +>>> print(p1.x, p1.y, p1) +1 2 Vector((1, 2)) +>>> p2 = Vector((2, 3)) +>>> print(p2.x, p2.y, p2) +2 3 Vector((2, 3)) +>>> p3 = p1 + p2 +>>> print(p3.x, p3.y, p3) +3 5 Vector((3, 5)) +>>> p4 = (4, 5) + p2 +>>> print(p4.x, p4.y, p4) +6 8 Vector((6, 8)) +>>> p1 * 2 +Vector((2, 4)) +>>> 2 * p1 +Vector((2, 4)) +>>> p1 - 1 +Vector((0, 1)) +>>> 1 - p1 +Vector((0, -1)) +>>> p1 / 2.0 +Vector((0.5, 1.0)) +>>> v = 2.0 / p1 +>>> print(v.x, v.y, v) +2.0 1.0 Vector((2.0, 1.0)) +""" + +import itertools +import operator +import traceback + +from .data_error import DataError + +__all__ = ["SimpleArray", "named_simple_array"] + + +class SimpleArray(tuple): + def _op(self, op, other): + def _o2(x, y): + try: + return op(x, y) + except ZeroDivisionError: + return DataError("#DIV/0", traceback.format_exc()) + except Exception: + return DataError("#ERR", traceback.format_exc()) + + if isinstance(other, tuple): + if len(other) != len(self): + raise TypeError("tuples must have same length for %s" % op) + return self.__class__(map(_o2, self, other)) + else: + return self.__class__(_o2(z, other) for z in self) + + def _cast(self, other): + if isinstance(other, self.__class__): + return other + elif isinstance(other, tuple): + return self.__class__(other) + else: + # other is a scalar + return self.__class__(itertools.repeat(other, len(self))) + + def __add__(self, other): + return self._op(operator.add, other) + + __radd__ = __add__ + + def __pos__(self): + return self.__class__(map(operator.pos, self)) + + def __neg__(self): + return self.__class__(map(operator.neg, self)) + + def __sub__(self, other): + return self._op(operator.sub, other) + + def __rsub__(self, other): + return self._cast(other)._op(operator.sub, self) + + def __mul__(self, other): + return self._op(operator.mul, other) + + __rmul__ = __mul__ + + def __div__(self, other): + return self._op(operator.div, other) + + def __floordiv__(self, other): + return self._op(operator.floordiv, other) + + def __truediv__(self, other): + return self._op(operator.truediv, other) + + def __rdiv__(self, other): + return self._cast(other)._op(operator.div, self) + + def __rfloordiv__(self, other): + return self._cast(other)._op(operator.floordiv, self) + + def __rtruediv__(self, other): + return self._cast(other)._op(operator.truediv, self) + + def __repr__(self): + return "{}({})".format(self.__class__.__name__, tuple.__repr__(self)) + + +def named_simple_array(typename, field_names): + """Return a subclass of SimpleArray, with named properties. + + This method is to SimpleArray what namedtuple is to tuple. + It's less sophisticated than namedtuple so some namedtuple + advanced use cases may not work, but it's good enough for + our needs in mis_builder, ie referring to subkpi values + by name. + """ + props = { + field_name: property(operator.itemgetter(i)) + for i, field_name in enumerate(field_names) + } + return type(typename, (SimpleArray,), props) + + +if __name__ == "__main__": # pragma: no cover + import doctest + + doctest.testmod() diff --git a/odex25_accounting/mis_builder/readme/CONTRIBUTORS.rst b/odex25_accounting/mis_builder/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..0bd722a3f --- /dev/null +++ b/odex25_accounting/mis_builder/readme/CONTRIBUTORS.rst @@ -0,0 +1,23 @@ +* Stéphane Bidoul +* Laetitia Gangloff +* Adrien Peiffer +* Alexis de Lattre +* Alexandre Fayolle +* Jordi Ballester +* Thomas Binsfeld +* Giovanni Capalbo +* Marco Calcagni +* Sébastien Beau +* Laurent Mignon +* Luc De Meyer +* Benjamin Willig +* Martronic SA +* nicomacr +* Juan Jose Scarafia +* Richard deMeester +* Eric Caudal +* Andrea Stirpe +* Maxence Groine +* Arnaud Pineux +* Ernesto Tejeda +* Pedro M. Baeza diff --git a/odex25_accounting/mis_builder/readme/DESCRIPTION.rst b/odex25_accounting/mis_builder/readme/DESCRIPTION.rst new file mode 100644 index 000000000..44542643d --- /dev/null +++ b/odex25_accounting/mis_builder/readme/DESCRIPTION.rst @@ -0,0 +1,5 @@ +This module allows you to build Management Information Systems dashboards. +Such style of reports presents KPI in rows and time periods in columns. +Reports mainly fetch data from account moves, but can also combine data coming +from arbitrary Odoo models. Reports can be exported to PDF, Excel and they +can be added to Odoo dashboards. diff --git a/odex25_accounting/mis_builder/readme/DEVELOP.rst b/odex25_accounting/mis_builder/readme/DEVELOP.rst new file mode 100644 index 000000000..6595dbe2b --- /dev/null +++ b/odex25_accounting/mis_builder/readme/DEVELOP.rst @@ -0,0 +1,6 @@ +A typical extension is to provide a mechanism to filter reports on analytic dimensions +or operational units. To implement this, you can override _get_additional_move_line_filter +and _get_additional_filter to further filter move lines or queries based on a user +selection. A typical use case could be to add an analytic account field on mis.report.instance, +or even on mis.report.instance.period if you want different columns to show different +analytic accounts. diff --git a/odex25_accounting/mis_builder/readme/HISTORY.rst b/odex25_accounting/mis_builder/readme/HISTORY.rst new file mode 100644 index 000000000..4e320ba68 --- /dev/null +++ b/odex25_accounting/mis_builder/readme/HISTORY.rst @@ -0,0 +1,428 @@ +14.0.3.6.7 (2021-06-02) +**Bugfixes** + +- When on a MIS Report Instance, if you wanted to generate a new line of type comparison, you couldn't currently select any existing period to compare. + This happened because the field domain was searching in a NewId context, thus not finding a correct period. + Changing the domain and making it use a computed field with a search for the _origin record solves the problem. (`#361 `_) + + +14.0.3.6.6 (2021-04-23) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Bugfixes** + +- Fix drilldown action name when the account model has been customized. (`#350 `_) + + +14.0.3.6.5 (2021-04-23) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Bugfixes** + +- While duplicating a MIS report instance, comparison columns are ignored because + they would raise an error otherwise, as they keep the old source_cmpcol_from_id + and source_cmpcol_to_id from the original record. (`#343 `_) + + +14.0.3.6.4 (2021-04-06) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Features** + +- The drilldown action name displayed on the breadcrumb has been revised. + The kpi description and the account ``display_name`` are shown instead + of the kpi's technical definition. (`#304 `_) +- Add analytic group filters on report instance, periods and in the interactive + view. (`#320 `_) + + +13.0.3.6.3 (2020-08-28) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Bugfixes** + +- Having a "Compare columns" added on a KPI with an associated style using a + Factor/Divider did lead to the said factor being applied on the percentages + when exporting to XLSX. (`#300 `_) + + +**Misc** + +- `#280 `_, `#296 `_ + + +13.0.3.6.2 (2020-04-22) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Bugfixes** + +- The "Settings" button is now displayed for users with the "Show full accounting features" right when previewing a report. (`#281 `_) + + +13.0.3.6.1 (2020-04-22) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Bugfixes** + +- Fix ``TypeError: 'module' object is not iterable`` when using + budgets by account. (`#276 `_) + + +13.0.3.6.0 (2020-03-28) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Features** + +- Add column-level filters on analytic account and analytic tags. + These filters are combined with a AND with the report-level filters + and cannot be modified in the preview. (`#138 `_) +- Access to KPI from other reports in KPI expressions, aka subreports. In a + report template, one can list named "subreports" (other report templates). When + evaluating expressions, you can access KPI's of subreports with a dot-prefix + notation. Example: you can define a MIS Report for a "Balance Sheet", and then + have another MIS Report "Balance Sheet Ratios" that fetches KPI's from "Balance + Sheet" to create new KPI's for the ratios (e.g. balance_sheet.current_assets / + balance_sheet.total_assets). (`#155 `_) + + +13.0.3.5.0 (2020-01-??) +~~~~~~~~~~~~~~~~~~~~~~~ + +Migration to odoo 13.0. + +12.0.3.5.0 (2019-10-26) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Features** + +- The ``account_id`` field of the model selected in 'Move lines source' + in the Period form can now be a Many2one + relationship with any model that has a ``code`` field (not only with + ``account.account`` model). To this end, the model to be used for Actuals + move lines can be configured on the report template. It can be something else + than move lines and the only constraint is that its ``account_id`` field + has a ``code`` field. (`#149 `_) +- Add ``source_aml_model_name`` field so extension modules providing + alternative data sources can more easily customize their data source. (`#214 `_) +- Support analytic tag filters in the backend view and preview widget. + Selecting several tags in the filter means filtering on move lines which + have *all* these tags set. This is to support the most common use case of + using tags for different dimensions. The filter also makes a AND with the + analytic account filter. (`#228 `_) +- Display company in account details rows in multi-company mode. (`#242 `_) + + +**Bugfixes** + +- Propagate context to xlsx report, so the analytic account filter + works when exporting to xslx too. This also requires a fix to + ``report_xlsx`` (see https://github.com/OCA/reporting-engine/pull/259). (`#178 `_) +- In columns of type Sum, preserve styles for KPIs that are not summable + (eg percentage values). Before this fix, such cells were displayed without + style. (`#219 `_) +- In Excel export, keep the percentage point suffix (pp) instead of replacing it with %. (`#220 `_) + + +12.0.3.4.0 (2019-07-09) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Features** + +- New year-to-date mode for defining periods. (`#165 `_) +- Add support for move lines with negative debit or credit. + Used by some for storno accounting. Not officially supported. (`#175 `_) +- In Excel export, use a number format with thousands separator. The + specific separator used depends on the Excel configuration (eg regional + settings). (`#190 `_) +- Add generation date/time at the end of the XLS export. (`#191 `_) +- In presence of Sub KPIs, report more informative user errors when + non-multi expressions yield tuples of incorrect lenght. (`#196 `_) + + +**Bugfixes** + +- Fix rendering of percentage types in Excel export. (`#192 `_) + + +12.0.3.3.0 (2019-01-26) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Features** + +*Dynamic analytic filters in report preview are not yet available in 11, +this requires an update to the JS widget that proved difficult to implement +so far. Help welcome.* + +- Analytic account filters. On a report, an analytic + account can be selected for filtering. The filter will + be applied to move lines queries. A filter box is also + available in the widget to let the user select the analytic + account during report preview. (`#15 `_) +- Control visibility of analytic filter combo box in widget. + This is useful to hide the analytic filters on reports where + they do not make sense, such as balance sheet reports. (`#42 `_) +- Display analytic filters in the header of exported pdf and xls. (`#44 `_) +- Replace the last old gtk icons with fontawesome icons. (`#104 `_) +- Use active_test=False in AEP queries. + This is important for reports involving inactive taxes. + This should not negatively effect existing reports, because + an accounting report must take into account all existing move lines + even if they reference objects such as taxes, journals, accounts types + that have been deactivated since their creation. (`#107 `_) +- int(), float() and round() support for AccountingNone. (`#108 `_) +- Allow referencing subkpis by name by writing `kpi_x.subkpi_y` in expressions. (`#114 `_) +- Add an option to control the display of the start/end dates in the + column headers. It is disabled by default (this is a change compared + to previous behaviour). (`#118 `_) +- Add evaluate method to mis.report. This is a simplified + method to evaluate kpis of a report over a time period, + without creating a mis.report.instance. (`#123 `_) + +**Bugs** + +- In the style form, hide the "Hide always" checkbox when "Hide always inherit" + is checked, as for all other syle elements. (`#121 _`) + +**Upgrading from 3.2 (breaking changes)** + +If you use ``Actuals (alternative)`` data source in combination with analytic +filters, the underlying model must now have an ``analytic_account_id`` field. + + +11.0.3.2.2 (2018-06-30) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [FIX] Fix bug in company_default_get call returning + id instead of recordset + (`#103 `_) +* [IMP] add "hide always" style property to make hidden KPI's + (for KPI that serve as basis for other formulas, but do not + need to be displayed). + (`#46 `_) + +11.0.3.2.1 (2018-05-29) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [FIX] Missing comparison operator for AccountingNone + leading to errors in pbal computations + (`#93 `_) + +10.0.3.2.0 (2018-05-02) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [FIX] make subkpi ordering deterministic + (`#71 `_) +* [ADD] report instance level option to disable account expansion, + enabling the creation of detailed templates while deferring the decision + of rendering the details or not to the report instance + (`#74 `_) +* [ADD] pbal and nbal accounting expressions, to sum positive + and negative balances respectively (ie ignoring accounts with negative, + resp positive balances) + (`#86 `_) + +11.0.3.1.2 (2018-02-04) +~~~~~~~~~~~~~~~~~~~~~~~ + +Migration to Odoo 11. No new feature. +(`#67 `_) + +10.0.3.1.1 (2017-11-14) +~~~~~~~~~~~~~~~~~~~~~~~ + +New features: + +* [ADD] month and year relative periods, easier to use than + date ranges for the most common case. + (`#2 `_) +* [ADD] multi-company consolidation support, with currency conversion + (the conversion rate date is the end of the reporting period) + (`#7 `_, + `#3 `_) +* [ADD] provide ref, datetime, dateutil, time, user in the evaluation + context of move line domains; among other things, this allows using + references to xml ids (such as account types or tax tags) when + querying move lines + (`#26 `_). +* [ADD] extended account selectors: you can now select accounts using + any domain on account.account, not only account codes + ``balp[('user_type_id', '=', ref('account.data_account_type_receivable').id)]`` + (`#4 `_). +* [IMP] in the report instance configuration form, the filters are + now grouped in a notebook page, this improves readability and + extensibility + (`#39 `_). + +Bug fixes: + +* [FIX] fix error when saving periods in comparison mode on newly + created (not yet saved) report instances. + `#50 `_ +* [FIX] improve display of Base Date report instance view. + `#51 `_ + +Upgrading from 3.0 (breaking changes): + +* Alternative move line data sources must have a company_id field. + +10.0.3.0.4 (2017-10-14) +~~~~~~~~~~~~~~~~~~~~~~~ + +Bug fix: + +* [FIX] issue with initial balance rounding. + `#30 `_ + +10.0.3.0.3 (2017-10-03) +~~~~~~~~~~~~~~~~~~~~~~~ + +Bug fix: + +* [FIX] fix error saving KPI on newly created reports. + `#18 `_ + +10.0.3.0.2 (2017-10-01) +~~~~~~~~~~~~~~~~~~~~~~~ + +New features: + +* [ADD] Alternative move line source per report column. + This makes mis buidler accounting expressions work on any model + that has debit, credit, account_id and date fields. Provided you can + expose, say, committed purchases, or your budget as a view with + debit, credit and account_id, this opens up a lot of possibilities +* [ADD] Comparison column source (more flexible than the previous, + now deprecated, comparison mechanism). + CAVEAT: there is no automated migration to the new mechanism. +* [ADD] Sum column source, to create columns that add/subtract + other columns. +* [ADD] mis.kpi.data abstract model as a basis for manual KPI values + supporting automatic ajustment to the reporting time period (the basis + for budget item, but could also server other purposes, such as manually + entering some KPI values, such as number of employee) +* [ADD] mis_builder_budget module providing a new budget data source +* [ADD] new "hide empty" style property +* [IMP] new AEP method to get accounts involved in an expression + (this is useful to find which KPI relate to a given P&L + acount, to implement budget control) +* [IMP] many UI improvements +* [IMP] many code style improvements and some refactoring +* [IMP] add the column date_from, date_to in expression evaluation context, + as well as time, datetime and dateutil modules + +Main bug fixes: + +* [FIX] deletion of templates and reports (cascade and retricts) + (https://github.com/OCA/account-financial-reporting/issues/281) +* [FIX] copy of reports + (https://github.com/OCA/account-financial-reporting/issues/282) +* [FIX] better error message when periods have wrong/missing dates + (https://github.com/OCA/account-financial-reporting/issues/283) +* [FIX] xlsx export of string types KPI + (https://github.com/OCA/account-financial-reporting/issues/285) +* [FIX] sorting of detail by account +* [FIX] computation bug in detail by account when multiple accounting + expressions were used in a KPI +* [FIX] permission issue when adding report to dashboard with non admin user + +10.0.2.0.3 (unreleased) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [IMP] more robust behaviour in presence of missing expressions +* [FIX] indent style +* [FIX] local variable 'ctx' referenced before assignment when generating + reports with no objects +* [IMP] use fontawesome icons +* [MIG] migrate to 10.0 +* [FIX] unicode error when exporting to Excel +* [IMP] provide full access to mis builder style for group Adviser. + +9.0.2.0.2 (2016-09-27) +~~~~~~~~~~~~~~~~~~~~~~ + +* [IMP] Add refresh button in mis report preview. +* [IMP] Widget code changes to allow to add fields in the widget more easily. + +9.0.2.0.1 (2016-05-26) +~~~~~~~~~~~~~~~~~~~~~~ + +* [IMP] remove unused argument in declare_and_compute_period() + for a cleaner API. This is a breaking API changing merged in + urgency before it is used by other modules. + +9.0.2.0.0 (2016-05-24) +~~~~~~~~~~~~~~~~~~~~~~ + +Part of the work for this release has been done at the Sorrento sprint +April 26-29, 2016. The rest (ie a major refactoring) has been done in +the weeks after. + +* [IMP] hide button box in edit mode on the report instance settings form +* [FIX] Fix sum aggregation of non-stored fields + (https://github.com/OCA/account-financial-reporting/issues/178) +* [IMP] There is now a default style at the report level +* [CHG] Number display properties (rounding, prefix, suffix, factor) are + now defined in styles +* [CHG] Percentage difference are rounded to 1 digit instead of the kpi's + rounding, as the KPI rounding does not make sense in this case +* [CHG] The divider suffix (k, M, etc) is not inserted automatically anymore + because it is inconsistent when working with prefixes; you need to add it + manually in the suffix +* [IMP] AccountingExpressionProcessor now supports 'balu' expressions + to obtain the unallocated profit/loss of previous fiscal years; + get_unallocated_pl is the corresponding convenience method +* [IMP] AccountingExpressionProcessor now has easy methods to obtain + balances by account: get_balances_initial, get_balances_end, + get_balances_variation +* [IMP] there is now an auto-expand feature to automatically display + a detail by account for selected kpis +* [IMP] the kpi and period lists are now manipulated through forms instead + of directly in the tree views +* [IMP] it is now possible to create a report through a wizard, such + reports are deemed temporary and available through a "Last Reports Generated" + menu, they are garbaged collected automatically, unless saved permanently, + which can be done using a Save button +* [IMP] there is now a beginner mode to configure simple reports with + only one period +* [IMP] it is now easier to configure periods with fixed start/end dates +* [IMP] the new sub-kpi mechanism allows the creation of columns + with multiple values, or columns with different values +* [IMP] thanks to the new style model, the Excel export is now styled +* [IMP] a new style model is now used to centralize style configuration +* [FIX] use =like instead of like to search for accounts, because + the % are added by the user in the expressions +* [FIX] Correctly compute the initial balance of income and expense account + based on the start of the fiscal year +* [IMP] Support date ranges (from OCA/server-tools/date_range) as a more + flexible alternative to fiscal periods +* v9 migration: fiscal periods are removed, account charts are removed, + consolidation accounts have been removed + +8.0.1.0.0 (2016-04-27) +~~~~~~~~~~~~~~~~~~~~~~ + +* The copy of a MIS Report Instance now copies period. + https://github.com/OCA/account-financial-reporting/pull/181 +* The copy of a MIS Report Template now copies KPIs and queries. + https://github.com/OCA/account-financial-reporting/pull/177 +* Usability: the default view for MIS Report instances is now the rendered preview, + and the settings are accessible through a gear icon in the list view and + a button in the preview. + https://github.com/OCA/account-financial-reporting/pull/170 +* Display blank cells instead of 0.0 when there is no data. + https://github.com/OCA/account-financial-reporting/pull/169 +* Usability: better layout of the MIS Report periods settings on small screens. + https://github.com/OCA/account-financial-reporting/pull/167 +* Include the download buttons inside the MIS Builder widget, and refactor + the widget to open the door to analytic filtering in the previews. + https://github.com/OCA/account-financial-reporting/pull/151 +* Add KPI rendering prefixes (so you can print $ in front of the value). + https://github.com/OCA/account-financial-reporting/pull/158 +* Add hooks for analytic filtering. + https://github.com/OCA/account-financial-reporting/pull/128 + https://github.com/OCA/account-financial-reporting/pull/131 + +8.0.0.2.0 +~~~~~~~~~ + +Pre-history. Or rather, you need to look at the git log. diff --git a/odex25_accounting/mis_builder/readme/INSTALL.rst b/odex25_accounting/mis_builder/readme/INSTALL.rst new file mode 100644 index 000000000..7b0f57714 --- /dev/null +++ b/odex25_accounting/mis_builder/readme/INSTALL.rst @@ -0,0 +1,7 @@ +Your preferred way to install addons will work with MIS Builder. + +An easy way to install it with all its dependencies is using pip: + +* ``pip install --pre odoo12-addon-mis_builder`` +* then restart Odoo, update the addons list in your database, and install + the MIS Builder application. diff --git a/odex25_accounting/mis_builder/readme/ROADMAP.rst b/odex25_accounting/mis_builder/readme/ROADMAP.rst new file mode 100644 index 000000000..085352cdb --- /dev/null +++ b/odex25_accounting/mis_builder/readme/ROADMAP.rst @@ -0,0 +1,3 @@ +The mis_builder `roadmap `_ +and `known issues `_ can +be found on GitHub. diff --git a/odex25_accounting/mis_builder/readme/USAGE.rst b/odex25_accounting/mis_builder/readme/USAGE.rst new file mode 100644 index 000000000..19383ac2b --- /dev/null +++ b/odex25_accounting/mis_builder/readme/USAGE.rst @@ -0,0 +1,26 @@ +To configure this module, you need to: + +* Go to Accounting > Configuration > MIS Reporting > MIS Report Templates where + you can create report templates by defining KPI's. KPI's constitute the rows of your + reports. Such report templates are time independent. + +.. figure:: https://raw.githubusercontent.com/OCA/mis-builder/10.0/mis_builder/static/description/ex_report_template.png + :alt: Sample report template + :width: 80 % + :align: center + +* Then in Accounting > Reports > MIS Reporting > MIS Reports you can create report instance by + binding the templates to time periods, hence defining the columns of your reports. + +.. figure:: https://raw.githubusercontent.com/OCA/mis-builder/10.0/mis_builder/static/description/ex_report_settings.png + :alt: Sample report configuration + :width: 80 % + :align: center + +* From the MIS Reports view, you can preview the report, add it to and Odoo dashboard, + and export it to PDF or Excel. + +.. figure:: https://raw.githubusercontent.com/OCA/mis-builder/10.0/mis_builder/static/description/ex_report_preview.png + :alt: Sample preview + :width: 80 % + :align: center diff --git a/odex25_accounting/mis_builder/readme/newsfragments/.gitignore b/odex25_accounting/mis_builder/readme/newsfragments/.gitignore new file mode 100644 index 000000000..e69de29bb diff --git a/odex25_accounting/mis_builder/report/__init__.py b/odex25_accounting/mis_builder/report/__init__.py new file mode 100644 index 000000000..6f814d60b --- /dev/null +++ b/odex25_accounting/mis_builder/report/__init__.py @@ -0,0 +1,5 @@ +# Copyright 2014 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from . import mis_report_instance_qweb +from . import mis_report_instance_xlsx diff --git a/odex25_accounting/mis_builder/report/mis_report_instance_qweb.py b/odex25_accounting/mis_builder/report/mis_report_instance_qweb.py new file mode 100644 index 000000000..bf7d07e3b --- /dev/null +++ b/odex25_accounting/mis_builder/report/mis_report_instance_qweb.py @@ -0,0 +1,28 @@ +# Copyright 2014 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import logging + +from odoo import models + +_logger = logging.getLogger(__name__) + + +class Report(models.Model): + _inherit = "ir.actions.report" + + def _render_qweb_pdf(self, res_ids=None, data=None): + if self.report_name == "mis_builder.report_mis_report_instance": + if not res_ids: + res_ids = self.env.context.get("active_ids") + mis_report_instance = self.env["mis.report.instance"].browse(res_ids)[0] + context = dict( + mis_report_instance._context_with_filters(), + landscape=mis_report_instance.landscape_pdf, + ) + # data=None, because it was there only to force Odoo + # to propagate context + return super(Report, self.with_context(context))._render_qweb_pdf( + res_ids, data=None + ) + return super(Report, self)._render_qweb_pdf(res_ids, data) diff --git a/odex25_accounting/mis_builder/report/mis_report_instance_qweb.xml b/odex25_accounting/mis_builder/report/mis_report_instance_qweb.xml new file mode 100644 index 000000000..c1146f809 --- /dev/null +++ b/odex25_accounting/mis_builder/report/mis_report_instance_qweb.xml @@ -0,0 +1,116 @@ + + + + MIS report instance QWEB PDF report + mis.report.instance + ir.actions.report + mis_builder.report_mis_report_instance + qweb-pdf + + + + + diff --git a/odex25_accounting/mis_builder/report/mis_report_instance_xlsx.py b/odex25_accounting/mis_builder/report/mis_report_instance_xlsx.py new file mode 100644 index 000000000..a35ff42fe --- /dev/null +++ b/odex25_accounting/mis_builder/report/mis_report_instance_xlsx.py @@ -0,0 +1,174 @@ +# Copyright 2014 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import logging +import numbers +from collections import defaultdict +from datetime import datetime + +from odoo import _, fields, models + +from ..models.accounting_none import AccountingNone +from ..models.data_error import DataError +from ..models.mis_report_style import TYPE_STR + +_logger = logging.getLogger(__name__) + + +ROW_HEIGHT = 15 # xlsxwriter units +COL_WIDTH = 0.9 # xlsxwriter units +MIN_COL_WIDTH = 10 # characters +MAX_COL_WIDTH = 50 # characters + + +class MisBuilderXlsx(models.AbstractModel): + _name = "report.mis_builder.mis_report_instance_xlsx" + _description = "MIS Builder XLSX report" + _inherit = "report.report_xlsx.abstract" + + def generate_xlsx_report(self, workbook, data, objects): + + # get the computed result of the report + matrix = objects._compute_matrix() + style_obj = self.env["mis.report.style"] + + # create worksheet + report_name = u"{} - {}".format( + objects[0].name, u", ".join([a.name for a in objects[0].query_company_ids]) + ) + sheet = workbook.add_worksheet(report_name[:31]) + row_pos = 0 + col_pos = 0 + # width of the labels column + label_col_width = MIN_COL_WIDTH + # {col_pos: max width in characters} + col_width = defaultdict(lambda: MIN_COL_WIDTH) + + # document title + bold = workbook.add_format({"bold": True}) + header_format = workbook.add_format( + {"bold": True, "align": "center", "bg_color": "#F0EEEE"} + ) + sheet.write(row_pos, 0, report_name, bold) + row_pos += 2 + + # filters + if not objects.hide_analytic_filters: + for filter_description in objects.get_filter_descriptions_from_context(): + sheet.write(row_pos, 0, filter_description) + row_pos += 1 + row_pos += 1 + + # column headers + sheet.write(row_pos, 0, "", header_format) + col_pos = 1 + for col in matrix.iter_cols(): + label = col.label + if col.description: + label += "\n" + col.description + sheet.set_row(row_pos, ROW_HEIGHT * 2) + if col.colspan > 1: + sheet.merge_range( + row_pos, + col_pos, + row_pos, + col_pos + col.colspan - 1, + label, + header_format, + ) + else: + sheet.write(row_pos, col_pos, label, header_format) + col_width[col_pos] = max( + col_width[col_pos], len(col.label or ""), len(col.description or "") + ) + col_pos += col.colspan + row_pos += 1 + + # sub column headers + sheet.write(row_pos, 0, "", header_format) + col_pos = 1 + for subcol in matrix.iter_subcols(): + label = subcol.label + if subcol.description: + label += "\n" + subcol.description + sheet.set_row(row_pos, ROW_HEIGHT * 2) + sheet.write(row_pos, col_pos, label, header_format) + col_width[col_pos] = max( + col_width[col_pos], + len(subcol.label or ""), + len(subcol.description or ""), + ) + col_pos += 1 + row_pos += 1 + + # rows + for row in matrix.iter_rows(): + if ( + row.style_props.hide_empty and row.is_empty() + ) or row.style_props.hide_always: + continue + row_xlsx_style = style_obj.to_xlsx_style(TYPE_STR, row.style_props) + row_format = workbook.add_format(row_xlsx_style) + col_pos = 0 + label = row.label + if row.description: + label += "\n" + row.description + sheet.set_row(row_pos, ROW_HEIGHT * 2) + sheet.write(row_pos, col_pos, label, row_format) + label_col_width = max( + label_col_width, len(row.label or ""), len(row.description or "") + ) + for cell in row.iter_cells(): + col_pos += 1 + if not cell or cell.val is AccountingNone: + # TODO col/subcol format + sheet.write(row_pos, col_pos, "", row_format) + continue + cell_xlsx_style = style_obj.to_xlsx_style( + cell.val_type, cell.style_props, no_indent=True + ) + cell_xlsx_style["align"] = "right" + cell_format = workbook.add_format(cell_xlsx_style) + if isinstance(cell.val, DataError): + val = cell.val.name + # TODO display cell.val.msg as Excel comment? + elif cell.val is None or cell.val is AccountingNone: + val = "" + else: + divider = float(cell.style_props.get("divider", 1)) + if ( + divider != 1 + and isinstance(cell.val, numbers.Number) + and not cell.val_type == "pct" + ): + val = cell.val / divider + else: + val = cell.val + sheet.write(row_pos, col_pos, val, cell_format) + col_width[col_pos] = max( + col_width[col_pos], len(cell.val_rendered or "") + ) + row_pos += 1 + + # Add date/time footer + row_pos += 1 + footer_format = workbook.add_format( + {"italic": True, "font_color": "#202020", "size": 9} + ) + lang_model = self.env["res.lang"] + lang = lang_model._lang_get(self.env.user.lang) + + now_tz = fields.Datetime.context_timestamp( + self.env["res.users"], datetime.now() + ) + create_date = _("Generated on {} at {}").format( + now_tz.strftime(lang.date_format), now_tz.strftime(lang.time_format) + ) + sheet.write(row_pos, 0, create_date, footer_format) + + # adjust col widths + sheet.set_column(0, 0, min(label_col_width, MAX_COL_WIDTH) * COL_WIDTH) + data_col_width = min(MAX_COL_WIDTH, max(col_width.values())) + min_col_pos = min(col_width.keys()) + max_col_pos = max(col_width.keys()) + sheet.set_column(min_col_pos, max_col_pos, data_col_width * COL_WIDTH) diff --git a/odex25_accounting/mis_builder/report/mis_report_instance_xlsx.xml b/odex25_accounting/mis_builder/report/mis_report_instance_xlsx.xml new file mode 100644 index 000000000..6059075b3 --- /dev/null +++ b/odex25_accounting/mis_builder/report/mis_report_instance_xlsx.xml @@ -0,0 +1,11 @@ + + + + MIS report instance XLS report + mis.report.instance + ir.actions.report + mis_builder.mis_report_instance_xlsx + xlsx + mis_report_instance + + diff --git a/odex25_accounting/mis_builder/security/ir.model.access.csv b/odex25_accounting/mis_builder/security/ir.model.access.csv new file mode 100644 index 000000000..5a61ee7cf --- /dev/null +++ b/odex25_accounting/mis_builder/security/ir.model.access.csv @@ -0,0 +1,22 @@ +"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" +manage_mis_report_kpi,manage_mis_report_kpi,model_mis_report_kpi,account.group_account_manager,1,1,1,1 +access_mis_report_kpi,access_mis_report_kpi,model_mis_report_kpi,base.group_user,1,0,0,0 +manage_mis_report_query,manage_mis_report_query,model_mis_report_query,account.group_account_manager,1,1,1,1 +access_mis_report_query,access_mis_report_query,model_mis_report_query,base.group_user,1,0,0,0 +manage_mis_report,manage_mis_report,model_mis_report,account.group_account_manager,1,1,1,1 +access_mis_report,access_mis_report,model_mis_report,base.group_user,1,0,0,0 +manage_mis_report_instance_period,manage_mis_report_instance_period,model_mis_report_instance_period,account.group_account_manager,1,1,1,1 +access_mis_report_instance_period,access_mis_report_instance_period,model_mis_report_instance_period,base.group_user,1,0,0,0 +manage_mis_report_instance_period_sum,manage_mis_report_instance_period_sum,model_mis_report_instance_period_sum,account.group_account_manager,1,1,1,1 +access_mis_report_instance_period_sum,access_mis_report_instance_period_sum,model_mis_report_instance_period_sum,base.group_user,1,0,0,0 +manage_mis_report_instance,manage_mis_report_instance,model_mis_report_instance,account.group_account_manager,1,1,1,1 +access_mis_report_instance,access_mis_report_instance,model_mis_report_instance,base.group_user,1,0,0,0 +manage_mis_report_subkpi,access_mis_report_subkpi,model_mis_report_subkpi,account.group_account_manager,1,1,1,1 +access_mis_report_subkpi,access_mis_report_subkpi,model_mis_report_subkpi,base.group_user,1,0,0,0 +manage_mis_report_kpi_expression,access_mis_report_kpi_expression,model_mis_report_kpi_expression,account.group_account_manager,1,1,1,1 +access_mis_report_kpi_expression,access_mis_report_kpi_expression,model_mis_report_kpi_expression,base.group_user,1,0,0,0 +manage_mis_report_subreport,access_mis_report_subreport,model_mis_report_subreport,account.group_account_manager,1,1,1,1 +access_mis_report_subreport,access_mis_report_subreport,model_mis_report_subreport,base.group_user,1,0,0,0 +manage_mis_report_style,access_mis_report_style,model_mis_report_style,account.group_account_manager,1,1,1,1 +access_mis_report_style,access_mis_report_style,model_mis_report_style,base.group_user,1,0,0,0 +access_add_to_dashboard_wizard,access_add_to_dashboard_wizard,model_add_mis_report_instance_dashboard_wizard,base.group_user,1,1,1,0 diff --git a/odex25_accounting/mis_builder/security/mis_builder_security.xml b/odex25_accounting/mis_builder/security/mis_builder_security.xml new file mode 100644 index 000000000..6c37f2513 --- /dev/null +++ b/odex25_accounting/mis_builder/security/mis_builder_security.xml @@ -0,0 +1,10 @@ + + + + Mis Report Instance multi company + + + ['|',('company_id','=',False),('company_id','in',company_ids)] + + + diff --git a/odex25_accounting/mis_builder/static/description/ex_report_preview.png b/odex25_accounting/mis_builder/static/description/ex_report_preview.png new file mode 100644 index 000000000..e818c5244 Binary files /dev/null and b/odex25_accounting/mis_builder/static/description/ex_report_preview.png differ diff --git a/odex25_accounting/mis_builder/static/description/ex_report_settings.png b/odex25_accounting/mis_builder/static/description/ex_report_settings.png new file mode 100644 index 000000000..f2633b99e Binary files /dev/null and b/odex25_accounting/mis_builder/static/description/ex_report_settings.png differ diff --git a/odex25_accounting/mis_builder/static/description/ex_report_template.png b/odex25_accounting/mis_builder/static/description/ex_report_template.png new file mode 100644 index 000000000..33950ae6a Binary files /dev/null and b/odex25_accounting/mis_builder/static/description/ex_report_template.png differ diff --git a/odex25_accounting/mis_builder/static/description/icon.png b/odex25_accounting/mis_builder/static/description/icon.png new file mode 100644 index 000000000..1afa781fa Binary files /dev/null and b/odex25_accounting/mis_builder/static/description/icon.png differ diff --git a/odex25_accounting/mis_builder/static/description/index.html b/odex25_accounting/mis_builder/static/description/index.html new file mode 100644 index 000000000..9d39660cf --- /dev/null +++ b/odex25_accounting/mis_builder/static/description/index.html @@ -0,0 +1,949 @@ + + + + + + +MIS Builder + + + +
    +

    MIS Builder

    + + +

    Production/Stable License: AGPL-3 OCA/mis-builder Translate me on Weblate Try me on Runbot

    +

    This module allows you to build Management Information Systems dashboards. +Such style of reports presents KPI in rows and time periods in columns. +Reports mainly fetch data from account moves, but can also combine data coming +from arbitrary Odoo models. Reports can be exported to PDF, Excel and they +can be added to Odoo dashboards.

    +

    Table of contents

    + +
    +

    Installation

    +

    Your preferred way to install addons will work with MIS Builder.

    +

    An easy way to install it with all its dependencies is using pip:

    +
      +
    • pip install --pre odoo12-addon-mis_builder
    • +
    • then restart Odoo, update the addons list in your database, and install +the MIS Builder application.
    • +
    +
    +
    +

    Usage

    +

    To configure this module, you need to:

    +
      +
    • Go to Accounting > Configuration > MIS Reporting > MIS Report Templates where +you can create report templates by defining KPI’s. KPI’s constitute the rows of your +reports. Such report templates are time independent.
    • +
    +
    +Sample report template +
    +
      +
    • Then in Accounting > Reports > MIS Reporting > MIS Reports you can create report instance by +binding the templates to time periods, hence defining the columns of your reports.
    • +
    +
    +Sample report configuration +
    +
      +
    • From the MIS Reports view, you can preview the report, add it to and Odoo dashboard, +and export it to PDF or Excel.
    • +
    +
    +Sample preview +
    +
    +
    +

    Development

    +

    A typical extension is to provide a mechanism to filter reports on analytic dimensions +or operational units. To implement this, you can override _get_additional_move_line_filter +and _get_additional_filter to further filter move lines or queries based on a user +selection. A typical use case could be to add an analytic account field on mis.report.instance, +or even on mis.report.instance.period if you want different columns to show different +analytic accounts.

    +
    +
    +

    Known issues / Roadmap

    +

    The mis_builder roadmap +and known issues can +be found on GitHub.

    +
    +
    +

    Changelog

    +

    14.0.3.6.7 (2021-06-02) +Bugfixes

    +
      +
    • When on a MIS Report Instance, if you wanted to generate a new line of type comparison, you couldn’t currently select any existing period to compare. +This happened because the field domain was searching in a NewId context, thus not finding a correct period. +Changing the domain and making it use a computed field with a search for the _origin record solves the problem. (#361)
    • +
    +
    +

    14.0.3.6.6 (2021-04-23)

    +

    Bugfixes

    +
      +
    • Fix drilldown action name when the account model has been customized. (#350)
    • +
    +
    +
    +

    14.0.3.6.5 (2021-04-23)

    +

    Bugfixes

    +
      +
    • While duplicating a MIS report instance, comparison columns are ignored because +they would raise an error otherwise, as they keep the old source_cmpcol_from_id +and source_cmpcol_to_id from the original record. (#343)
    • +
    +
    +
    +

    14.0.3.6.4 (2021-04-06)

    +

    Features

    +
      +
    • The drilldown action name displayed on the breadcrumb has been revised. +The kpi description and the account display_name are shown instead +of the kpi’s technical definition. (#304)
    • +
    • Add analytic group filters on report instance, periods and in the interactive +view. (#320)
    • +
    +
    +
    +

    13.0.3.6.3 (2020-08-28)

    +

    Bugfixes

    +
      +
    • Having a “Compare columns” added on a KPI with an associated style using a +Factor/Divider did lead to the said factor being applied on the percentages +when exporting to XLSX. (#300)
    • +
    +

    Misc

    + +
    +
    +

    13.0.3.6.2 (2020-04-22)

    +

    Bugfixes

    +
      +
    • The “Settings” button is now displayed for users with the “Show full accounting features” right when previewing a report. (#281)
    • +
    +
    +
    +

    13.0.3.6.1 (2020-04-22)

    +

    Bugfixes

    +
      +
    • Fix TypeError: 'module' object is not iterable when using +budgets by account. (#276)
    • +
    +
    +
    +

    13.0.3.6.0 (2020-03-28)

    +

    Features

    +
      +
    • Add column-level filters on analytic account and analytic tags. +These filters are combined with a AND with the report-level filters +and cannot be modified in the preview. (#138)
    • +
    • Access to KPI from other reports in KPI expressions, aka subreports. In a +report template, one can list named “subreports” (other report templates). When +evaluating expressions, you can access KPI’s of subreports with a dot-prefix +notation. Example: you can define a MIS Report for a “Balance Sheet”, and then +have another MIS Report “Balance Sheet Ratios” that fetches KPI’s from “Balance +Sheet” to create new KPI’s for the ratios (e.g. balance_sheet.current_assets / +balance_sheet.total_assets). (#155)
    • +
    +
    +
    +

    13.0.3.5.0 (2020-01-??)

    +

    Migration to odoo 13.0.

    +
    +
    +

    12.0.3.5.0 (2019-10-26)

    +

    Features

    +
      +
    • The account_id field of the model selected in ‘Move lines source’ +in the Period form can now be a Many2one +relationship with any model that has a code field (not only with +account.account model). To this end, the model to be used for Actuals +move lines can be configured on the report template. It can be something else +than move lines and the only constraint is that its account_id field +has a code field. (#149)
    • +
    • Add source_aml_model_name field so extension modules providing +alternative data sources can more easily customize their data source. (#214)
    • +
    • Support analytic tag filters in the backend view and preview widget. +Selecting several tags in the filter means filtering on move lines which +have all these tags set. This is to support the most common use case of +using tags for different dimensions. The filter also makes a AND with the +analytic account filter. (#228)
    • +
    • Display company in account details rows in multi-company mode. (#242)
    • +
    +

    Bugfixes

    +
      +
    • Propagate context to xlsx report, so the analytic account filter +works when exporting to xslx too. This also requires a fix to +report_xlsx (see https://github.com/OCA/reporting-engine/pull/259). (#178)
    • +
    • In columns of type Sum, preserve styles for KPIs that are not summable +(eg percentage values). Before this fix, such cells were displayed without +style. (#219)
    • +
    • In Excel export, keep the percentage point suffix (pp) instead of replacing it with %. (#220)
    • +
    +
    +
    +

    12.0.3.4.0 (2019-07-09)

    +

    Features

    +
      +
    • New year-to-date mode for defining periods. (#165)
    • +
    • Add support for move lines with negative debit or credit. +Used by some for storno accounting. Not officially supported. (#175)
    • +
    • In Excel export, use a number format with thousands separator. The +specific separator used depends on the Excel configuration (eg regional +settings). (#190)
    • +
    • Add generation date/time at the end of the XLS export. (#191)
    • +
    • In presence of Sub KPIs, report more informative user errors when +non-multi expressions yield tuples of incorrect lenght. (#196)
    • +
    +

    Bugfixes

    +
      +
    • Fix rendering of percentage types in Excel export. (#192)
    • +
    +
    +
    +

    12.0.3.3.0 (2019-01-26)

    +

    Features

    +

    Dynamic analytic filters in report preview are not yet available in 11, +this requires an update to the JS widget that proved difficult to implement +so far. Help welcome.

    +
      +
    • Analytic account filters. On a report, an analytic +account can be selected for filtering. The filter will +be applied to move lines queries. A filter box is also +available in the widget to let the user select the analytic +account during report preview. (#15)
    • +
    • Control visibility of analytic filter combo box in widget. +This is useful to hide the analytic filters on reports where +they do not make sense, such as balance sheet reports. (#42)
    • +
    • Display analytic filters in the header of exported pdf and xls. (#44)
    • +
    • Replace the last old gtk icons with fontawesome icons. (#104)
    • +
    • Use active_test=False in AEP queries. +This is important for reports involving inactive taxes. +This should not negatively effect existing reports, because +an accounting report must take into account all existing move lines +even if they reference objects such as taxes, journals, accounts types +that have been deactivated since their creation. (#107)
    • +
    • int(), float() and round() support for AccountingNone. (#108)
    • +
    • Allow referencing subkpis by name by writing kpi_x.subkpi_y in expressions. (#114)
    • +
    • Add an option to control the display of the start/end dates in the +column headers. It is disabled by default (this is a change compared +to previous behaviour). (#118)
    • +
    • Add evaluate method to mis.report. This is a simplified +method to evaluate kpis of a report over a time period, +without creating a mis.report.instance. (#123)
    • +
    +

    Bugs

    +
      +
    • In the style form, hide the “Hide always” checkbox when “Hide always inherit” +is checked, as for all other syle elements. (#121 <https://github.com/OCA/mis-builder/pull/121>_)
    • +
    +

    Upgrading from 3.2 (breaking changes)

    +

    If you use Actuals (alternative) data source in combination with analytic +filters, the underlying model must now have an analytic_account_id field.

    +
    +
    +

    11.0.3.2.2 (2018-06-30)

    +
      +
    • [FIX] Fix bug in company_default_get call returning +id instead of recordset +(#103)
    • +
    • [IMP] add “hide always” style property to make hidden KPI’s +(for KPI that serve as basis for other formulas, but do not +need to be displayed). +(#46)
    • +
    +
    +
    +

    11.0.3.2.1 (2018-05-29)

    +
      +
    • [FIX] Missing comparison operator for AccountingNone +leading to errors in pbal computations +(#93)
    • +
    +
    +
    +

    10.0.3.2.0 (2018-05-02)

    +
      +
    • [FIX] make subkpi ordering deterministic +(#71)
    • +
    • [ADD] report instance level option to disable account expansion, +enabling the creation of detailed templates while deferring the decision +of rendering the details or not to the report instance +(#74)
    • +
    • [ADD] pbal and nbal accounting expressions, to sum positive +and negative balances respectively (ie ignoring accounts with negative, +resp positive balances) +(#86)
    • +
    +
    +
    +

    11.0.3.1.2 (2018-02-04)

    +

    Migration to Odoo 11. No new feature. +(#67)

    +
    +
    +

    10.0.3.1.1 (2017-11-14)

    +

    New features:

    +
      +
    • [ADD] month and year relative periods, easier to use than +date ranges for the most common case. +(#2)
    • +
    • [ADD] multi-company consolidation support, with currency conversion +(the conversion rate date is the end of the reporting period) +(#7, +#3)
    • +
    • [ADD] provide ref, datetime, dateutil, time, user in the evaluation +context of move line domains; among other things, this allows using +references to xml ids (such as account types or tax tags) when +querying move lines +(#26).
    • +
    • [ADD] extended account selectors: you can now select accounts using +any domain on account.account, not only account codes +balp[('user_type_id', '=', ref('account.data_account_type_receivable').id)] +(#4).
    • +
    • [IMP] in the report instance configuration form, the filters are +now grouped in a notebook page, this improves readability and +extensibility +(#39).
    • +
    +

    Bug fixes:

    +
      +
    • [FIX] fix error when saving periods in comparison mode on newly +created (not yet saved) report instances. +#50
    • +
    • [FIX] improve display of Base Date report instance view. +#51
    • +
    +

    Upgrading from 3.0 (breaking changes):

    +
      +
    • Alternative move line data sources must have a company_id field.
    • +
    +
    +
    +

    10.0.3.0.4 (2017-10-14)

    +

    Bug fix:

    +
      +
    • [FIX] issue with initial balance rounding. +#30
    • +
    +
    +
    +

    10.0.3.0.3 (2017-10-03)

    +

    Bug fix:

    +
      +
    • [FIX] fix error saving KPI on newly created reports. +#18
    • +
    +
    +
    +

    10.0.3.0.2 (2017-10-01)

    +

    New features:

    +
      +
    • [ADD] Alternative move line source per report column. +This makes mis buidler accounting expressions work on any model +that has debit, credit, account_id and date fields. Provided you can +expose, say, committed purchases, or your budget as a view with +debit, credit and account_id, this opens up a lot of possibilities
    • +
    • [ADD] Comparison column source (more flexible than the previous, +now deprecated, comparison mechanism). +CAVEAT: there is no automated migration to the new mechanism.
    • +
    • [ADD] Sum column source, to create columns that add/subtract +other columns.
    • +
    • [ADD] mis.kpi.data abstract model as a basis for manual KPI values +supporting automatic ajustment to the reporting time period (the basis +for budget item, but could also server other purposes, such as manually +entering some KPI values, such as number of employee)
    • +
    • [ADD] mis_builder_budget module providing a new budget data source
    • +
    • [ADD] new “hide empty” style property
    • +
    • [IMP] new AEP method to get accounts involved in an expression +(this is useful to find which KPI relate to a given P&L +acount, to implement budget control)
    • +
    • [IMP] many UI improvements
    • +
    • [IMP] many code style improvements and some refactoring
    • +
    • [IMP] add the column date_from, date_to in expression evaluation context, +as well as time, datetime and dateutil modules
    • +
    +

    Main bug fixes:

    + +
    +
    +

    10.0.2.0.3 (unreleased)

    +
      +
    • [IMP] more robust behaviour in presence of missing expressions
    • +
    • [FIX] indent style
    • +
    • [FIX] local variable ‘ctx’ referenced before assignment when generating +reports with no objects
    • +
    • [IMP] use fontawesome icons
    • +
    • [MIG] migrate to 10.0
    • +
    • [FIX] unicode error when exporting to Excel
    • +
    • [IMP] provide full access to mis builder style for group Adviser.
    • +
    +
    +
    +

    9.0.2.0.2 (2016-09-27)

    +
      +
    • [IMP] Add refresh button in mis report preview.
    • +
    • [IMP] Widget code changes to allow to add fields in the widget more easily.
    • +
    +
    +
    +

    9.0.2.0.1 (2016-05-26)

    +
      +
    • [IMP] remove unused argument in declare_and_compute_period() +for a cleaner API. This is a breaking API changing merged in +urgency before it is used by other modules.
    • +
    +
    +
    +

    9.0.2.0.0 (2016-05-24)

    +

    Part of the work for this release has been done at the Sorrento sprint +April 26-29, 2016. The rest (ie a major refactoring) has been done in +the weeks after.

    +
      +
    • [IMP] hide button box in edit mode on the report instance settings form
    • +
    • [FIX] Fix sum aggregation of non-stored fields +(https://github.com/OCA/account-financial-reporting/issues/178)
    • +
    • [IMP] There is now a default style at the report level
    • +
    • [CHG] Number display properties (rounding, prefix, suffix, factor) are +now defined in styles
    • +
    • [CHG] Percentage difference are rounded to 1 digit instead of the kpi’s +rounding, as the KPI rounding does not make sense in this case
    • +
    • [CHG] The divider suffix (k, M, etc) is not inserted automatically anymore +because it is inconsistent when working with prefixes; you need to add it +manually in the suffix
    • +
    • [IMP] AccountingExpressionProcessor now supports ‘balu’ expressions +to obtain the unallocated profit/loss of previous fiscal years; +get_unallocated_pl is the corresponding convenience method
    • +
    • [IMP] AccountingExpressionProcessor now has easy methods to obtain +balances by account: get_balances_initial, get_balances_end, +get_balances_variation
    • +
    • [IMP] there is now an auto-expand feature to automatically display +a detail by account for selected kpis
    • +
    • [IMP] the kpi and period lists are now manipulated through forms instead +of directly in the tree views
    • +
    • [IMP] it is now possible to create a report through a wizard, such +reports are deemed temporary and available through a “Last Reports Generated” +menu, they are garbaged collected automatically, unless saved permanently, +which can be done using a Save button
    • +
    • [IMP] there is now a beginner mode to configure simple reports with +only one period
    • +
    • [IMP] it is now easier to configure periods with fixed start/end dates
    • +
    • [IMP] the new sub-kpi mechanism allows the creation of columns +with multiple values, or columns with different values
    • +
    • [IMP] thanks to the new style model, the Excel export is now styled
    • +
    • [IMP] a new style model is now used to centralize style configuration
    • +
    • [FIX] use =like instead of like to search for accounts, because +the % are added by the user in the expressions
    • +
    • [FIX] Correctly compute the initial balance of income and expense account +based on the start of the fiscal year
    • +
    • [IMP] Support date ranges (from OCA/server-tools/date_range) as a more +flexible alternative to fiscal periods
    • +
    • v9 migration: fiscal periods are removed, account charts are removed, +consolidation accounts have been removed
    • +
    +
    +
    +

    8.0.1.0.0 (2016-04-27)

    + +
    +
    +

    8.0.0.2.0

    +

    Pre-history. Or rather, you need to look at the git log.

    +
    +
    +
    +

    Bug Tracker

    +

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

    +

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

    +
    +
    +

    Credits

    +
    +

    Authors

    +
      +
    • ACSONE SA/NV
    • +
    +
    +
    +

    Contributors

    + +
    +
    +

    Maintainers

    +

    This module is maintained by the OCA.

    +Odoo Community Association +

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

    +

    Current maintainer:

    +

    sbidoul

    +

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

    +

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

    +
    +
    +
    + + diff --git a/odex25_accounting/mis_builder/static/src/css/custom.css b/odex25_accounting/mis_builder/static/src/css/custom.css new file mode 100644 index 000000000..3ea36d7a6 --- /dev/null +++ b/odex25_accounting/mis_builder/static/src/css/custom.css @@ -0,0 +1,29 @@ +.o_web_client .mis_builder_amount { + text-align: right; +} + +.o_web_client .mis_builder_collabel { + text-align: center; +} + +.o_web_client .mis_builder_rowlabel { + text-align: left; +} + +.o_web_client .mis_builder a { + /* we don't want the link color, to respect user styles */ + color: inherit; +} + +.o_web_client .mis_builder a:hover { + /* underline links on hover to give a visual cue */ + text-decoration: underline; +} + +.oe_mis_builder_content { + padding: 10px; +} + +.oe_mis_builder_analytic_filter_box { + padding-bottom: 10px; +} diff --git a/odex25_accounting/mis_builder/static/src/css/report.css b/odex25_accounting/mis_builder/static/src/css/report.css new file mode 100644 index 000000000..0d58939ca --- /dev/null +++ b/odex25_accounting/mis_builder/static/src/css/report.css @@ -0,0 +1,46 @@ +.mis_table { + display: table; + width: 100%; + table-layout: fixed; +} +.mis_row { + display: table-row; + page-break-inside: avoid; +} +.mis_cell { + display: table-cell; + page-break-inside: avoid; +} +.mis_thead { + display: table-header-group; +} +.mis_tbody { + display: table-row-group; +} +.mis_table, +.mis_table .mis_row { + border-left: 0px; + border-right: 0px; + text-align: left; + padding-right: 3px; + padding-left: 3px; + padding-top: 2px; + padding-bottom: 2px; + border-collapse: collapse; +} +.mis_table .mis_row { + border-color: grey; + border-bottom: 1px solid lightGrey; +} +.mis_table .mis_cell.mis_collabel { + font-weight: bold; + background-color: #f0f0f0; + text-align: center; +} +.mis_table .mis_cell.mis_rowlabel { + text-align: left; + /*white-space: nowrap;*/ +} +.mis_table .mis_cell.mis_amount { + text-align: right; +} diff --git a/odex25_accounting/mis_builder/static/src/js/mis_report_widget.js b/odex25_accounting/mis_builder/static/src/js/mis_report_widget.js new file mode 100644 index 000000000..fedfe9032 --- /dev/null +++ b/odex25_accounting/mis_builder/static/src/js/mis_report_widget.js @@ -0,0 +1,450 @@ +/* Copyright 2014-2019 ACSONE SA/NV () + License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). */ + +odoo.define("mis_builder.widget", function (require) { + "use strict"; + + var AbstractField = require("web.AbstractField"); + var StandaloneFieldManagerMixin = require("web.StandaloneFieldManagerMixin"); + var field_registry = require("web.field_registry"); + var relational_fields = require("web.relational_fields"); + var BasicModel = require("web.BasicModel"); + + var core = require("web.core"); + var session = require("web.session"); + + var _t = core._t; + + var MisReportWidget = AbstractField.extend(StandaloneFieldManagerMixin, { + template: "MisReportWidgetTemplate", + + events: _.extend({}, AbstractField.prototype.events, { + "click .mis_builder_drilldown": "drilldown", + "click .oe_mis_builder_print": "printPdf", + "click .oe_mis_builder_export": "exportXls", + "click .oe_mis_builder_settings": "displaySettings", + "click .oe_mis_builder_refresh": "refresh", + }), + + init: function () { + var self = this; + self._super.apply(self, arguments); + StandaloneFieldManagerMixin.init.call(self); + self.model = new BasicModel(self); // For FieldManagerMixin + self.analytic_account_id_domain = []; // TODO unused for now + self.analytic_account_id_label = _t("Analytic Account Filter"); + self.analytic_account_id_m2o = undefined; // Field widget + self.analytic_group_id_domain = []; // TODO unused for now + self.analytic_group_filter_name = "analytic_account_id.group_id"; + self.analytic_group_id_label = _t("Analytic Account Group"); + self.analytic_group_id_m2o = undefined; // Field widget + self.analytic_tag_ids_domain = []; // TODO unused for now + self.analytic_tag_ids_label = _t("Analytic Tags Filter"); + self.analytic_tag_ids_m2m = undefined; // Field widget + self.mis_report_data = undefined; + self.show_settings = false; + self.has_group_analytic_accounting = false; + self.has_group_analytic_tags = false; + self.hide_analytic_filters = false; + }, + + _getFilterValue: function (name) { + var filters = this.getParent().state.context.mis_report_filters || {}; + var filter = filters[name] || {}; + return filter.value; + }, + + _setFilterValue: function (name, value, operator) { + var context = this.getParent().state.context; + var filters = undefined; + if (context.mis_report_filters === undefined) { + filters = {}; + context.mis_report_filters = filters; + } else { + filters = context.mis_report_filters; + } + if (value === undefined) { + filters[name] = {}; + return; + } + filters[name] = { + value: value, + operator: operator, + }; + }, + + /** + * Return the id of the mis.report.instance to which the widget is + * bound. + * + * @returns int + */ + _instanceId: function () { + if (this.value) { + return this.value; + } + + /* + * This trick is needed because in a dashboard the view does + * not seem to be bound to an instance: it seems to be a limitation + * of Odoo dashboards that are not designed to contain forms but + * rather tree views or charts. + */ + var context = this.getParent().state.context; + if (context.active_model === "mis.report.instance") { + return context.active_id; + } + }, + + /** + * Method called between @see init and @see start. Performs asynchronous + * calls required by the rendering and the start method. + * + * @returns Promise + */ + willStart: function () { + var self = this; + var context = self.getParent().state.context; + + var def1 = self + ._rpc({ + model: "mis.report.instance", + method: "compute", + args: [self._instanceId()], + context: context, + }) + .then(function (result) { + self.mis_report_data = result; + }); + + var def2 = session + .user_has_group("account.group_account_user") + .then(function (result) { + self.show_settings = result; + }); + + var def3 = session + .user_has_group("analytic.group_analytic_accounting") + .then(function (result) { + self.has_group_analytic_accounting = result; + }); + + var def4 = session + .user_has_group("analytic.group_analytic_tags") + .then(function (result) { + self.has_group_analytic_tags = result; + }); + + var def5 = self + ._rpc({ + model: "mis.report.instance", + method: "read", + args: [self._instanceId(), ["hide_analytic_filters"]], + context: context, + }) + .then(function (result) { + self.hide_analytic_filters = result[0].hide_analytic_filters; + }); + + return $.when( + this._super.apply(this, arguments), + def1, + def2, + def3, + def4, + def5 + ); + }, + + start: function () { + var self = this; + self._super.apply(self, arguments); + self._addAnalyticFilters(); + }, + + /** + * Create list of field descriptors to be provided + * to BasicModel.makeRecord. + * + * @returns list of objects + */ + _getFilterFields: function () { + var self = this; + var fields = []; + if (self.has_group_analytic_accounting) { + fields.push({ + relation: "account.analytic.account", + type: "many2one", + name: "filter_analytic_account_id", + value: self._getFilterValue("analytic_account_id"), + }); + fields.push({ + relation: "account.analytic.group", + type: "many2one", + name: "filter_analytic_account_id.group_id", + value: self._getFilterValue("analytic_account_id.group_id"), + }); + } + if (self.has_group_analytic_tags) { + fields.push({ + relation: "account.analytic.tag", + type: "many2many", + name: "filter_analytic_tag_ids", + value: self._getFilterValue("analytic_tag_ids"), + }); + } + return fields; + }, + + /** + * Create fieldInfo structure to be provided + * to BasicModel.makeRecord. + * + * @returns object + */ + _getFilterFieldInfo: function () { + return {}; + }, + + /** + * Create analytic filter widgets and add them in the filter box. + * + * @param {Object} record @see BasicModel.makeRecord + */ + _makeFilterFieldWidgets: function (record) { + var self = this; + + if (self.has_group_analytic_accounting) { + self.analytic_account_id_m2o = new relational_fields.FieldMany2One( + self, + "filter_analytic_account_id", + record, + { + mode: "edit", + attrs: { + placeholder: self.analytic_account_id_label, + options: { + no_create: "True", + no_open: "True", + }, + }, + } + ); + self._registerWidget( + record.id, + self.analytic_account_id_m2o.name, + self.analytic_account_id_m2o + ); + self.analytic_account_id_m2o.appendTo(self.getMisBuilderFilterBox()); + + self.analytic_group_id_m2o = new relational_fields.FieldMany2One( + self, + "filter_analytic_account_id.group_id", + record, + { + mode: "edit", + attrs: { + placeholder: self.analytic_group_id_label, + options: { + no_create: "True", + no_open: "True", + }, + }, + } + ); + self._registerWidget( + record.id, + self.analytic_group_id_m2o.name, + self.analytic_group_id_m2o + ); + self.analytic_group_id_m2o.appendTo(self.getMisBuilderFilterBox()); + } + + if (self.has_group_analytic_tags) { + self.analytic_tag_ids_m2m = new relational_fields.FieldMany2ManyTags( + self, + "filter_analytic_tag_ids", + record, + { + mode: "edit", + attrs: { + placeholder: self.analytic_tag_ids_label, + options: { + no_create: "True", + no_open: "True", + }, + }, + } + ); + self._registerWidget( + record.id, + self.analytic_tag_ids_m2m.name, + self.analytic_tag_ids_m2m + ); + self.analytic_tag_ids_m2m.appendTo(self.getMisBuilderFilterBox()); + } + }, + + /** + * Hack to work around Odoo not fetching display name for + * x2many used with makeRecord. + * + * @returns a list of deferred + * to be awaited before creating the widgets. + * + * @param {Object} record @see BasicModel.makeRecord + */ + _beforeCreateWidgets: function (record) { + var self = this; + var defs = []; + + if (self.has_group_analytic_tags) { + var dataPoint = record.data.filter_analytic_tag_ids; + dataPoint.fieldsInfo.default.display_name = {}; + defs.push(self.model.reload(dataPoint.id)); + } + + return defs; + }, + + /** + * Populate the analytic filters box. + * This method is not meant to be overridden. + */ + _addAnalyticFilters: function () { + var self = this; + if (self.hide_analytic_filters) { + return; + } + self.model + .makeRecord( + "dummy.model", + self._getFilterFields(), + self._getFilterFieldInfo() + ) + .then(function (recordId) { + var record = self.model.get(recordId); + var defs = self._beforeCreateWidgets(record); + $.when.apply($, defs).then(function () { + record = self.model.get(record.id); + self._makeFilterFieldWidgets(record); + }); + }); + }, + + _confirmChange: function () { + var self = this; + var result = StandaloneFieldManagerMixin._confirmChange.apply( + self, + arguments + ); + + if (self.analytic_account_id_m2o !== undefined) { + if (self.analytic_account_id_m2o.value) { + self._setFilterValue( + "analytic_account_id", + self.analytic_account_id_m2o.value.res_id, + "=" + ); + } else { + self._setFilterValue("analytic_account_id", undefined); + } + } + + if (self.analytic_group_id_m2o !== undefined) { + if (self.analytic_group_id_m2o.value) { + self._setFilterValue( + self.analytic_group_filter_name, + self.analytic_group_id_m2o.value.res_id, + "=" + ); + } else { + self._setFilterValue(self.analytic_group_filter_name, undefined); + } + } + + if (self.analytic_tag_ids_m2m !== undefined) { + if ( + self.analytic_tag_ids_m2m.value && + self.analytic_tag_ids_m2m.value.res_ids.length > 0 + ) { + self._setFilterValue( + "analytic_tag_ids", + self.analytic_tag_ids_m2m.value.res_ids, + "all" + ); + } else { + self._setFilterValue("analytic_tag_ids", undefined); + } + } + + return result; + }, + + refresh: function () { + this.replace(); + }, + + printPdf: function () { + var self = this; + var context = self.getParent().state.context; + this._rpc({ + model: "mis.report.instance", + method: "print_pdf", + args: [this._instanceId()], + context: context, + }).then(function (result) { + self.do_action(result); + }); + }, + + exportXls: function () { + var self = this; + var context = self.getParent().state.context; + this._rpc({ + model: "mis.report.instance", + method: "export_xls", + args: [this._instanceId()], + context: context, + }).then(function (result) { + self.do_action(result); + }); + }, + + displaySettings: function () { + var self = this; + var context = self.getParent().state.context; + this._rpc({ + model: "mis.report.instance", + method: "display_settings", + args: [this._instanceId()], + context: context, + }).then(function (result) { + self.do_action(result); + }); + }, + + drilldown: function (event) { + var self = this; + var context = self.getParent().state.context; + var drilldown = $(event.target).data("drilldown"); + this._rpc({ + model: "mis.report.instance", + method: "drilldown", + args: [this._instanceId(), drilldown], + context: context, + }).then(function (result) { + self.do_action(result); + }); + }, + + getMisBuilderFilterBox: function () { + var self = this; + return self.$(".oe_mis_builder_analytic_filter_box"); + }, + }); + + field_registry.add("mis_report_widget", MisReportWidget); + + return MisReportWidget; +}); diff --git a/odex25_accounting/mis_builder/static/src/xml/mis_report_widget.xml b/odex25_accounting/mis_builder/static/src/xml/mis_report_widget.xml new file mode 100644 index 000000000..274c4f8c6 --- /dev/null +++ b/odex25_accounting/mis_builder/static/src/xml/mis_report_widget.xml @@ -0,0 +1,98 @@ + diff --git a/odex25_accounting/mis_builder/tests/__init__.py b/odex25_accounting/mis_builder/tests/__init__.py new file mode 100644 index 000000000..1174376d6 --- /dev/null +++ b/odex25_accounting/mis_builder/tests/__init__.py @@ -0,0 +1,16 @@ +# Copyright 2014 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from . import test_accounting_none +from . import test_analytic_filters +from . import test_aep +from . import test_multi_company_aep +from . import test_aggregate +from . import test_data_sources +from . import test_kpi_data +from . import test_mis_report_instance +from . import test_mis_safe_eval +from . import test_period_dates +from . import test_render +from . import test_simple_array +from . import test_utc_midnight diff --git a/odex25_accounting/mis_builder/tests/common.py b/odex25_accounting/mis_builder/tests/common.py new file mode 100644 index 000000000..3f9bc5c29 --- /dev/null +++ b/odex25_accounting/mis_builder/tests/common.py @@ -0,0 +1,80 @@ +# Copyright 2017 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import doctest + +from odoo.tests import BaseCase, tagged + + +def setup_test_model(env, model_cls): + model_cls._build_model(env.registry, env.cr) + env.registry.setup_models(env.cr) + env.registry.init_models( + env.cr, [model_cls._name], dict(env.context, update_custom_fields=True) + ) + + +def teardown_test_model(env, model_cls): + del env.registry.models[model_cls._name] + env.registry.setup_models(env.cr) + + +def _zip(iter1, iter2): + i = 0 + iter1 = iter(iter1) + iter2 = iter(iter2) + while True: + i1 = next(iter1, None) + i2 = next(iter2, None) + if i1 is None and i2 is None: + return + yield i, i1, i2 + i += 1 + + +def assert_matrix(matrix, expected): + for i, row, expected_row in _zip(matrix.iter_rows(), expected): + if row is None and expected_row is not None: + raise AssertionError("not enough rows") + if row is not None and expected_row is None: + raise AssertionError("too many rows") + for j, cell, expected_val in _zip(row.iter_cells(), expected_row): + assert ( + cell and cell.val + ) == expected_val, "{} != {} in row {} col {}".format( + cell and cell.val, expected_val, i, j + ) + + +@tagged("doctest") +class OdooDocTestCase(BaseCase): + """ + We need a custom DocTestCase class in order to: + - define test_tags to run as part of standard tests + - output a more meaningful test name than default "DocTestCase.runTest" + """ + + __qualname__ = "doctests for " + + def __init__(self, test): + self.__test = test + self.__name = test._dt_test.name + super().__init__(self.__name) + + def __getattr__(self, item): + if item == self.__name: + return self.__test + + +def load_doctests(module): + """ + Generates a tests loading method for the doctests of the given module + https://docs.python.org/3/library/unittest.html#load-tests-protocol + """ + + def load_tests(loader, tests, ignore): + for test in doctest.DocTestSuite(module): + tests.addTest(OdooDocTestCase(test)) + return tests + + return load_tests diff --git a/odex25_accounting/mis_builder/tests/test_accounting_none.py b/odex25_accounting/mis_builder/tests/test_accounting_none.py new file mode 100644 index 000000000..ced8c3ef9 --- /dev/null +++ b/odex25_accounting/mis_builder/tests/test_accounting_none.py @@ -0,0 +1,8 @@ +# Copyright 2014 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + + +from ..models import accounting_none +from .common import load_doctests + +load_tests = load_doctests(accounting_none) diff --git a/odex25_accounting/mis_builder/tests/test_aep.py b/odex25_accounting/mis_builder/tests/test_aep.py new file mode 100644 index 000000000..8d9bf433d --- /dev/null +++ b/odex25_accounting/mis_builder/tests/test_aep.py @@ -0,0 +1,412 @@ +# Copyright 2014 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import datetime +import time + +import odoo.tests.common as common +from odoo import fields +from odoo.tools.safe_eval import safe_eval + +from ..models.accounting_none import AccountingNone +from ..models.aep import AccountingExpressionProcessor as AEP, _is_domain + + +class TestAEP(common.TransactionCase): + def setUp(self): + super(TestAEP, self).setUp() + self.res_company = self.env["res.company"] + self.account_model = self.env["account.account"] + self.move_model = self.env["account.move"] + self.journal_model = self.env["account.journal"] + self.curr_year = datetime.date.today().year + self.prev_year = self.curr_year - 1 + # create company + self.company = self.res_company.create({"name": "AEP Company"}) + # create receivable bs account + type_ar = self.browse_ref("account.data_account_type_receivable") + self.account_ar = self.account_model.create( + { + "company_id": self.company.id, + "code": "400AR", + "name": "Receivable", + "user_type_id": type_ar.id, + "reconcile": True, + } + ) + # create income pl account + type_in = self.browse_ref("account.data_account_type_revenue") + self.account_in = self.account_model.create( + { + "company_id": self.company.id, + "code": "700IN", + "name": "Income", + "user_type_id": type_in.id, + } + ) + # create journal + self.journal = self.journal_model.create( + { + "company_id": self.company.id, + "name": "Sale journal", + "code": "VEN", + "type": "sale", + } + ) + # create move in December last year + self._create_move( + date=datetime.date(self.prev_year, 12, 1), + amount=100, + debit_acc=self.account_ar, + credit_acc=self.account_in, + ) + # create move in January this year + self._create_move( + date=datetime.date(self.curr_year, 1, 1), + amount=300, + debit_acc=self.account_ar, + credit_acc=self.account_in, + ) + # create move in March this year + self._create_move( + date=datetime.date(self.curr_year, 3, 1), + amount=500, + debit_acc=self.account_ar, + credit_acc=self.account_in, + ) + # create the AEP, and prepare the expressions we'll need + self.aep = AEP(self.company) + self.aep.parse_expr("bali[]") + self.aep.parse_expr("bale[]") + self.aep.parse_expr("balp[]") + self.aep.parse_expr("balu[]") + self.aep.parse_expr("bali[700IN]") + self.aep.parse_expr("bale[700IN]") + self.aep.parse_expr("balp[700IN]") + self.aep.parse_expr("bali[400AR]") + self.aep.parse_expr("bale[400AR]") + self.aep.parse_expr("balp[400AR]") + self.aep.parse_expr("debp[400A%]") + self.aep.parse_expr("crdp[700I%]") + self.aep.parse_expr("bali[400%]") + self.aep.parse_expr("bale[700%]") + self.aep.parse_expr("balp[]" "[('account_id.code', '=', '400AR')]") + self.aep.parse_expr( + "balp[]" + "[('account_id.user_type_id', '=', " + " ref('account.data_account_type_receivable').id)]" + ) + self.aep.parse_expr( + "balp[('user_type_id', '=', " + " ref('account.data_account_type_receivable').id)]" + ) + self.aep.parse_expr( + "balp['&', " + " ('user_type_id', '=', " + " ref('account.data_account_type_receivable').id), " + " ('code', '=', '400AR')]" + ) + self.aep.parse_expr("bal_700IN") # deprecated + self.aep.parse_expr("bals[700IN]") # deprecated + + def _create_move(self, date, amount, debit_acc, credit_acc, post=True): + move = self.move_model.create( + { + "journal_id": self.journal.id, + "date": fields.Date.to_string(date), + "line_ids": [ + (0, 0, {"name": "/", "debit": amount, "account_id": debit_acc.id}), + ( + 0, + 0, + {"name": "/", "credit": amount, "account_id": credit_acc.id}, + ), + ], + } + ) + if post: + move._post() + return move + + def _do_queries(self, date_from, date_to): + self.aep.do_queries( + date_from=fields.Date.to_string(date_from), + date_to=fields.Date.to_string(date_to), + target_move="posted", + ) + + def _eval(self, expr): + eval_dict = {"AccountingNone": AccountingNone} + return safe_eval(self.aep.replace_expr(expr), eval_dict) + + def _eval_by_account_id(self, expr): + res = {} + eval_dict = {"AccountingNone": AccountingNone} + for account_id, replaced_exprs in self.aep.replace_exprs_by_account_id([expr]): + res[account_id] = safe_eval(replaced_exprs[0], eval_dict) + return res + + def test_sanity_check(self): + self.assertEqual(self.company.fiscalyear_last_day, 31) + self.assertEqual(self.company.fiscalyear_last_month, "12") + + def test_aep_basic(self): + self.aep.done_parsing() + # let's query for december + self._do_queries( + datetime.date(self.prev_year, 12, 1), datetime.date(self.prev_year, 12, 31) + ) + # initial balance must be None + self.assertIs(self._eval("bali[400AR]"), AccountingNone) + self.assertIs(self._eval("bali[700IN]"), AccountingNone) + # check variation + self.assertEqual(self._eval("balp[400AR]"), 100) + self.assertEqual(self._eval("balp[][('account_id.code', '=', '400AR')]"), 100) + self.assertEqual( + self._eval( + "balp[]" + "[('account_id.user_type_id', '=', " + " ref('account.data_account_type_receivable').id)]" + ), + 100, + ) + self.assertEqual( + self._eval( + "balp[('user_type_id', '=', " + " ref('account.data_account_type_receivable').id)]" + ), + 100, + ) + self.assertEqual( + self._eval( + "balp['&', " + " ('user_type_id', '=', " + " ref('account.data_account_type_receivable').id), " + " ('code', '=', '400AR')]" + ), + 100, + ) + self.assertEqual(self._eval("balp[700IN]"), -100) + # check ending balance + self.assertEqual(self._eval("bale[400AR]"), 100) + self.assertEqual(self._eval("bale[700IN]"), -100) + + # let's query for January + self._do_queries( + datetime.date(self.curr_year, 1, 1), datetime.date(self.curr_year, 1, 31) + ) + # initial balance is None for income account (it's not carried over) + self.assertEqual(self._eval("bali[400AR]"), 100) + self.assertIs(self._eval("bali[700IN]"), AccountingNone) + # check variation + self.assertEqual(self._eval("balp[400AR]"), 300) + self.assertEqual(self._eval("balp[700IN]"), -300) + # check ending balance + self.assertEqual(self._eval("bale[400AR]"), 400) + self.assertEqual(self._eval("bale[700IN]"), -300) + + # let's query for March + self._do_queries( + datetime.date(self.curr_year, 3, 1), datetime.date(self.curr_year, 3, 31) + ) + # initial balance is the ending balance fo January + self.assertEqual(self._eval("bali[400AR]"), 400) + self.assertEqual(self._eval("bali[700IN]"), -300) + self.assertEqual(self._eval("pbali[400AR]"), 400) + self.assertEqual(self._eval("nbali[400AR]"), 0) + self.assertEqual(self._eval("nbali[700IN]"), -300) + self.assertEqual(self._eval("pbali[700IN]"), 0) + # check variation + self.assertEqual(self._eval("balp[400AR]"), 500) + self.assertEqual(self._eval("balp[700IN]"), -500) + self.assertEqual(self._eval("nbalp[400AR]"), 0) + self.assertEqual(self._eval("pbalp[400AR]"), 500) + self.assertEqual(self._eval("nbalp[700IN]"), -500) + self.assertEqual(self._eval("pbalp[700IN]"), 0) + # check ending balance + self.assertEqual(self._eval("bale[400AR]"), 900) + self.assertEqual(self._eval("nbale[400AR]"), 0) + self.assertEqual(self._eval("pbale[400AR]"), 900) + self.assertEqual(self._eval("bale[700IN]"), -800) + self.assertEqual(self._eval("nbale[700IN]"), -800) + self.assertEqual(self._eval("pbale[700IN]"), 0) + # check some variant expressions, for coverage + self.assertEqual(self._eval("crdp[700I%]"), 500) + self.assertEqual(self._eval("debp[400A%]"), 500) + self.assertEqual(self._eval("bal_700IN"), -500) + self.assertEqual(self._eval("bals[700IN]"), -800) + + # unallocated p&l from previous year + self.assertEqual(self._eval("balu[]"), -100) + + # TODO allocate profits, and then... + + def test_aep_by_account(self): + self.aep.done_parsing() + self._do_queries( + datetime.date(self.curr_year, 3, 1), datetime.date(self.curr_year, 3, 31) + ) + variation = self._eval_by_account_id("balp[]") + self.assertEqual(variation, {self.account_ar.id: 500, self.account_in.id: -500}) + variation = self._eval_by_account_id("pbalp[]") + self.assertEqual( + variation, {self.account_ar.id: 500, self.account_in.id: AccountingNone} + ) + variation = self._eval_by_account_id("nbalp[]") + self.assertEqual( + variation, {self.account_ar.id: AccountingNone, self.account_in.id: -500} + ) + variation = self._eval_by_account_id("balp[700IN]") + self.assertEqual(variation, {self.account_in.id: -500}) + variation = self._eval_by_account_id("crdp[700IN] - debp[400AR]") + self.assertEqual(variation, {self.account_ar.id: -500, self.account_in.id: 500}) + end = self._eval_by_account_id("bale[]") + self.assertEqual(end, {self.account_ar.id: 900, self.account_in.id: -800}) + + def test_aep_convenience_methods(self): + initial = AEP.get_balances_initial( + self.company, time.strftime("%Y") + "-03-01", "posted" + ) + self.assertEqual( + initial, {self.account_ar.id: (400, 0), self.account_in.id: (0, 300)} + ) + variation = AEP.get_balances_variation( + self.company, + time.strftime("%Y") + "-03-01", + time.strftime("%Y") + "-03-31", + "posted", + ) + self.assertEqual( + variation, {self.account_ar.id: (500, 0), self.account_in.id: (0, 500)} + ) + end = AEP.get_balances_end( + self.company, time.strftime("%Y") + "-03-31", "posted" + ) + self.assertEqual( + end, {self.account_ar.id: (900, 0), self.account_in.id: (0, 800)} + ) + unallocated = AEP.get_unallocated_pl( + self.company, time.strftime("%Y") + "-03-15", "posted" + ) + self.assertEqual(unallocated, (0, 100)) + + def test_float_is_zero(self): + dp = self.company.currency_id.decimal_places + self.assertEqual(dp, 2) + # make initial balance at Jan 1st equal to 0.01 + self._create_move( + date=datetime.date(self.prev_year, 12, 1), + amount=100.01, + debit_acc=self.account_in, + credit_acc=self.account_ar, + ) + initial = AEP.get_balances_initial( + self.company, time.strftime("%Y") + "-01-01", "posted" + ) + self.assertEqual(initial, {self.account_ar.id: (100.00, 100.01)}) + # make initial balance at Jan 1st equal to 0.001 + self._create_move( + date=datetime.date(self.prev_year, 12, 1), + amount=0.009, + debit_acc=self.account_ar, + credit_acc=self.account_in, + ) + initial = AEP.get_balances_initial( + self.company, time.strftime("%Y") + "-01-01", "posted" + ) + # epsilon initial balances is reported as empty + self.assertEqual(initial, {}) + + def test_get_account_ids_for_expr(self): + self.aep.done_parsing() + expr = "balp[700IN]" + account_ids = self.aep.get_account_ids_for_expr(expr) + self.assertEqual(account_ids, {self.account_in.id}) + expr = "balp[700%]" + account_ids = self.aep.get_account_ids_for_expr(expr) + self.assertEqual(account_ids, {self.account_in.id}) + expr = "bali[400%], bale[700%]" # subkpis combined expression + account_ids = self.aep.get_account_ids_for_expr(expr) + self.assertEqual(account_ids, {self.account_in.id, self.account_ar.id}) + + def test_get_aml_domain_for_expr(self): + self.aep.done_parsing() + expr = "balp[700IN]" + domain = self.aep.get_aml_domain_for_expr( + expr, "2017-01-01", "2017-03-31", target_move="posted" + ) + self.assertEqual( + domain, + [ + ("account_id", "in", (self.account_in.id,)), + "&", + "&", + ("date", ">=", "2017-01-01"), + ("date", "<=", "2017-03-31"), + ("move_id.state", "=", "posted"), + ], + ) + expr = "debi[700IN] - crdi[400AR]" + domain = self.aep.get_aml_domain_for_expr( + expr, "2017-02-01", "2017-03-31", target_move="draft" + ) + self.assertEqual( + domain, + [ + "|", + # debi[700IN] + "&", + ("account_id", "in", (self.account_in.id,)), + ("debit", "<>", 0.0), + # crdi[400AR] + "&", + ("account_id", "in", (self.account_ar.id,)), + ("credit", "<>", 0.0), + "&", + # for P&L accounts, only after fy start + "|", + ("date", ">=", "2017-01-01"), + ("account_id.user_type_id.include_initial_balance", "=", True), + # everything must be before from_date for initial balance + ("date", "<", "2017-02-01"), + ], + ) + + def test_is_domain(self): + self.assertTrue(_is_domain("('a', '=' 1)")) + self.assertTrue(_is_domain("'&', ('a', '=' 1), ('b', '=', 1)")) + self.assertTrue(_is_domain("'|', ('a', '=' 1), ('b', '=', 1)")) + self.assertTrue(_is_domain("'!', ('a', '=' 1), ('b', '=', 1)")) + self.assertTrue(_is_domain("\"&\", ('a', '=' 1), ('b', '=', 1)")) + self.assertTrue(_is_domain("\"|\", ('a', '=' 1), ('b', '=', 1)")) + self.assertTrue(_is_domain("\"!\", ('a', '=' 1), ('b', '=', 1)")) + self.assertFalse(_is_domain("123%")) + self.assertFalse(_is_domain("123%,456")) + self.assertFalse(_is_domain("")) + + def test_inactive_tax(self): + expr = 'balp[][("tax_ids.name", "=", "test tax")]' + self.aep.parse_expr(expr) + self.aep.done_parsing() + + tax = self.env["account.tax"].create( + dict(name="test tax", active=True, amount=0, company_id=self.company.id) + ) + move = self._create_move( + date=datetime.date(self.prev_year, 12, 1), + amount=100, + debit_acc=self.account_ar, + credit_acc=self.account_in, + post=False, + ) + for ml in move.line_ids: + if ml.credit: + ml.write(dict(tax_ids=[(6, 0, [tax.id])])) + tax.active = False + move._post() + # let's query for december 1st + self._do_queries( + datetime.date(self.prev_year, 12, 1), datetime.date(self.prev_year, 12, 1) + ) + # let's see if there was a match + self.assertEqual(self._eval(expr), -100) diff --git a/odex25_accounting/mis_builder/tests/test_aggregate.py b/odex25_accounting/mis_builder/tests/test_aggregate.py new file mode 100644 index 000000000..f1650f1e2 --- /dev/null +++ b/odex25_accounting/mis_builder/tests/test_aggregate.py @@ -0,0 +1,7 @@ +# Copyright 2014 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from ..models import aggregate +from .common import load_doctests + +load_tests = load_doctests(aggregate) diff --git a/odex25_accounting/mis_builder/tests/test_analytic_filters.py b/odex25_accounting/mis_builder/tests/test_analytic_filters.py new file mode 100644 index 000000000..7c03caf51 --- /dev/null +++ b/odex25_accounting/mis_builder/tests/test_analytic_filters.py @@ -0,0 +1,115 @@ +# Copyright 2019 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo.tests.common import TransactionCase + + +class TestAnalyticFilters(TransactionCase): + def setUp(self): + super(TestAnalyticFilters, self).setUp() + self.aag = self.env["account.analytic.group"].search([], limit=1) + + def test_context_with_filters(self): + aaa = self.env["account.analytic.account"].search([], limit=1) + mri = self.env["mis.report.instance"].new() + mri.analytic_account_id = False + mri.analytic_group_id = False + assert mri._context_with_filters().get("mis_report_filters") == {} + mri.analytic_account_id = aaa + mri.analytic_group_id = self.aag + assert mri._context_with_filters().get("mis_report_filters") == { + "analytic_account_id": {"value": aaa.id, "operator": "="}, + "analytic_account_id.group_id": {"value": self.aag.id, "operator": "="}, + } + # test _context_with_filters does nothing is a filter is already + # in the context + mri.with_context(mis_report_filters={"f": 1})._context_with_filters().get( + "mis_report_filters" + ) == {"f": 1} + + def _check_get_filter_domain_from_context( + self, mis_report_filters, expected_domain + ): + domain = ( + self.env["mis.report.instance.period"] + .with_context(mis_report_filters=mis_report_filters) + ._get_filter_domain_from_context() + ) + assert domain == expected_domain + + def _check_get_filter_descriptions_from_context( + self, mis_report_filters, expected_domain + ): + filter_descriptions = ( + self.env["mis.report.instance"] + .with_context(mis_report_filters=mis_report_filters) + .get_filter_descriptions_from_context() + ) + assert filter_descriptions == expected_domain + + def test_get_filter_domain_from_context_1(self): + # no filter, no domain + self._check_get_filter_domain_from_context({}, []) + # the most basic analytic account filter (default operator is =) + self._check_get_filter_domain_from_context( + {"analytic_account_id": {"value": 1}}, [("analytic_account_id", "=", 1)] + ) + self._check_get_filter_domain_from_context( + {"analytic_group_id": {"value": 1}}, [("analytic_group_id", "=", 1)] + ) + # custom operator + self._check_get_filter_domain_from_context( + {"analytic_account_id": {"value": 1, "operator": "!="}}, + [("analytic_account_id", "!=", 1)], + ) + self._check_get_filter_domain_from_context( + {"analytic_group_id": {"value": 1, "operator": "!="}}, + [("analytic_group_id", "!=", 1)], + ) + # any field name works + self._check_get_filter_domain_from_context( + {"some_field": {"value": "x"}}, [("some_field", "=", "x")] + ) + # filter name without value => no domain + self._check_get_filter_domain_from_context({"some_field": None}, []) + # "is not set" filter must work + self._check_get_filter_domain_from_context( + {"analytic_account_id": {"value": False}}, + [("analytic_account_id", "=", False)], + ) + self._check_get_filter_domain_from_context( + {"analytic_group_id": {"value": False}}, + [("analytic_group_id", "=", False)], + ) + # Filter from analytic account filter widget + self._check_get_filter_domain_from_context( + {"analytic_account_id": {"value": 1, "operator": "all"}}, + [("analytic_account_id", "in", [1])], + ) + + # Filter from analytic group filter widget + self._check_get_filter_domain_from_context( + {"analytic_group_id": {"value": 1, "operator": "all"}}, + [("analytic_group_id", "in", [1])], + ) + + # Filter from analytic tags filter widget + self._check_get_filter_domain_from_context( + {"analytic_tag_ids": {"value": [1, 2], "operator": "all"}}, + [("analytic_tag_ids", "in", [1]), ("analytic_tag_ids", "in", [2])], + ) + + def test_get_filter_descriptions_from_context_1(self): + self._check_get_filter_descriptions_from_context( + {"analytic_account_id.group_id": {"value": self.aag.id}}, + ["Analytic Account Group: %s" % self.aag.display_name], + ) + + def test_get_additional_move_line_filter_with_analytic_group(self): + instance_period = self.env["mis.report.instance.period"].new( + { + "analytic_group_id": self.aag.id, + } + ) + domain = instance_period._get_additional_move_line_filter() + assert domain == [("analytic_account_id.group_id", "=", self.aag.id)] diff --git a/odex25_accounting/mis_builder/tests/test_data_sources.py b/odex25_accounting/mis_builder/tests/test_data_sources.py new file mode 100644 index 000000000..c29ca967f --- /dev/null +++ b/odex25_accounting/mis_builder/tests/test_data_sources.py @@ -0,0 +1,221 @@ +# Copyright 2016 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import odoo.tests.common as common + +from ..models.accounting_none import AccountingNone +from ..models.mis_report import CMP_DIFF +from ..models.mis_report_instance import ( + MODE_NONE, + SRC_ACTUALS_ALT, + SRC_CMPCOL, + SRC_SUMCOL, +) +from .common import assert_matrix + + +class TestMisReportInstanceDataSources(common.TransactionCase): + """Test sum and comparison data source.""" + + def _create_move(self, date, amount, debit_acc, credit_acc): + move = self.move_model.create( + { + "journal_id": self.journal.id, + "date": date, + "line_ids": [ + (0, 0, {"name": "/", "debit": amount, "account_id": debit_acc.id}), + ( + 0, + 0, + {"name": "/", "credit": amount, "account_id": credit_acc.id}, + ), + ], + } + ) + move._post() + return move + + def setUp(self): + super(TestMisReportInstanceDataSources, self).setUp() + self.account_model = self.env["account.account"] + self.move_model = self.env["account.move"] + self.journal_model = self.env["account.journal"] + # create receivable bs account + type_ar = self.browse_ref("account.data_account_type_receivable") + self.account_ar = self.account_model.create( + { + "company_id": self.env.user.company_id.id, + "code": "400AR", + "name": "Receivable", + "user_type_id": type_ar.id, + "reconcile": True, + } + ) + # create income account + type_in = self.browse_ref("account.data_account_type_revenue") + self.account_in = self.account_model.create( + { + "company_id": self.env.user.company_id.id, + "code": "700IN", + "name": "Income", + "user_type_id": type_in.id, + } + ) + self.account_in2 = self.account_model.create( + { + "company_id": self.env.user.company_id.id, + "code": "700IN2", + "name": "Income", + "user_type_id": type_in.id, + } + ) + # create journal + self.journal = self.journal_model.create( + { + "company_id": self.env.user.company_id.id, + "name": "Sale journal", + "code": "VEN", + "type": "sale", + } + ) + # create move + self._create_move( + date="2017-01-01", + amount=11, + debit_acc=self.account_ar, + credit_acc=self.account_in, + ) + # create move + self._create_move( + date="2017-02-01", + amount=13, + debit_acc=self.account_ar, + credit_acc=self.account_in, + ) + self._create_move( + date="2017-02-01", + amount=17, + debit_acc=self.account_ar, + credit_acc=self.account_in2, + ) + # create report + self.report = self.env["mis.report"].create(dict(name="test report")) + self.kpi1 = self.env["mis.report.kpi"].create( + dict( + report_id=self.report.id, + name="k1", + description="kpi 1", + expression="-balp[700IN]", + compare_method=CMP_DIFF, + ) + ) + self.expr1 = self.kpi1.expression_ids[0] + self.kpi2 = self.env["mis.report.kpi"].create( + dict( + report_id=self.report.id, + name="k2", + description="kpi 2", + expression="-balp[700%]", + compare_method=CMP_DIFF, + auto_expand_accounts=True, + ) + ) + self.instance = self.env["mis.report.instance"].create( + dict(name="test instance", report_id=self.report.id, comparison_mode=True) + ) + self.p1 = self.env["mis.report.instance.period"].create( + dict( + name="p1", + report_instance_id=self.instance.id, + manual_date_from="2017-01-01", + manual_date_to="2017-01-31", + ) + ) + self.p2 = self.env["mis.report.instance.period"].create( + dict( + name="p2", + report_instance_id=self.instance.id, + manual_date_from="2017-02-01", + manual_date_to="2017-02-28", + ) + ) + + def test_sum(self): + self.psum = self.env["mis.report.instance.period"].create( + dict( + name="psum", + report_instance_id=self.instance.id, + mode=MODE_NONE, + source=SRC_SUMCOL, + source_sumcol_ids=[ + (0, 0, dict(period_to_sum_id=self.p1.id, sign="+")), + (0, 0, dict(period_to_sum_id=self.p2.id, sign="+")), + ], + ) + ) + matrix = self.instance._compute_matrix() + # None in last col because account details are not summed by default + assert_matrix( + matrix, + [ + [11, 13, 24], + [11, 30, 41], + [11, 13, AccountingNone], + [AccountingNone, 17, AccountingNone], + ], + ) + + def test_sum_diff(self): + self.psum = self.env["mis.report.instance.period"].create( + dict( + name="psum", + report_instance_id=self.instance.id, + mode=MODE_NONE, + source=SRC_SUMCOL, + source_sumcol_ids=[ + (0, 0, dict(period_to_sum_id=self.p1.id, sign="+")), + (0, 0, dict(period_to_sum_id=self.p2.id, sign="-")), + ], + source_sumcol_accdet=True, + ) + ) + matrix = self.instance._compute_matrix() + assert_matrix( + matrix, + [[11, 13, -2], [11, 30, -19], [11, 13, -2], [AccountingNone, 17, -17]], + ) + + def test_cmp(self): + self.pcmp = self.env["mis.report.instance.period"].create( + dict( + name="pcmp", + report_instance_id=self.instance.id, + mode=MODE_NONE, + source=SRC_CMPCOL, + source_cmpcol_from_id=self.p1.id, + source_cmpcol_to_id=self.p2.id, + ) + ) + matrix = self.instance._compute_matrix() + assert_matrix( + matrix, [[11, 13, 2], [11, 30, 19], [11, 13, 2], [AccountingNone, 17, 17]] + ) + + def test_actuals(self): + matrix = self.instance._compute_matrix() + assert_matrix(matrix, [[11, 13], [11, 30], [11, 13], [AccountingNone, 17]]) + + def test_actuals_disable_auto_expand_accounts(self): + self.instance.no_auto_expand_accounts = True + matrix = self.instance._compute_matrix() + assert_matrix(matrix, [[11, 13], [11, 30]]) + + def test_actuals_alt(self): + aml_model = self.env["ir.model"].search([("name", "=", "account.move.line")]) + self.kpi2.auto_expand_accounts = False + self.p1.source = SRC_ACTUALS_ALT + self.p1.source_aml_model_id = aml_model.id + self.p2.source = SRC_ACTUALS_ALT + self.p1.source_aml_model_id = aml_model.id + matrix = self.instance._compute_matrix() + assert_matrix(matrix, [[11, 13], [11, 30]]) diff --git a/odex25_accounting/mis_builder/tests/test_kpi_data.py b/odex25_accounting/mis_builder/tests/test_kpi_data.py new file mode 100644 index 000000000..5461a36df --- /dev/null +++ b/odex25_accounting/mis_builder/tests/test_kpi_data.py @@ -0,0 +1,143 @@ +# Copyright 2017 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo import models +from odoo.tests.common import SavepointCase + +from ..models.mis_kpi_data import ACC_AVG, ACC_SUM +from .common import setup_test_model, teardown_test_model + + +class TestKpiData(SavepointCase): + class MisKpiDataTestItem(models.Model): + + _name = "mis.kpi.data.test.item" + _inherit = "mis.kpi.data" + _description = "MIS Kpi Data test item" + + @classmethod + def setUpClass(cls): + super(TestKpiData, cls).setUpClass() + setup_test_model(cls.env, cls.MisKpiDataTestItem) + + report = cls.env["mis.report"].create(dict(name="test report")) + cls.kpi1 = cls.env["mis.report.kpi"].create( + dict( + report_id=report.id, + name="k1", + description="kpi 1", + expression="AccountingNone", + ) + ) + cls.expr1 = cls.kpi1.expression_ids[0] + cls.kpi2 = cls.env["mis.report.kpi"].create( + dict( + report_id=report.id, + name="k2", + description="kpi 2", + expression="AccountingNone", + ) + ) + cls.expr2 = cls.kpi2.expression_ids[0] + cls.kd11 = cls.env["mis.kpi.data.test.item"].create( + dict( + kpi_expression_id=cls.expr1.id, + date_from="2017-05-01", + date_to="2017-05-10", + amount=10, + ) + ) + cls.kd12 = cls.env["mis.kpi.data.test.item"].create( + dict( + kpi_expression_id=cls.expr1.id, + date_from="2017-05-11", + date_to="2017-05-20", + amount=20, + ) + ) + cls.kd13 = cls.env["mis.kpi.data.test.item"].create( + dict( + kpi_expression_id=cls.expr1.id, + date_from="2017-05-21", + date_to="2017-05-25", + amount=30, + ) + ) + cls.kd21 = cls.env["mis.kpi.data.test.item"].create( + dict( + kpi_expression_id=cls.expr2.id, + date_from="2017-06-01", + date_to="2017-06-30", + amount=3, + ) + ) + + @classmethod + def tearDownClass(cls): + teardown_test_model(cls.env, cls.MisKpiDataTestItem) + super(TestKpiData, cls).tearDownClass() + + def test_kpi_data_name(self): + self.assertEqual(self.kd11.name, "k1: 2017-05-01 - 2017-05-10") + self.assertEqual(self.kd12.name, "k1: 2017-05-11 - 2017-05-20") + + def test_kpi_data_sum(self): + self.assertEqual(self.kpi1.accumulation_method, ACC_SUM) + # one full + r = self.env["mis.kpi.data.test.item"]._query_kpi_data( + "2017-05-01", "2017-05-10", [] + ) + self.assertEqual(r, {self.expr1: 10}) + # one half + r = self.env["mis.kpi.data.test.item"]._query_kpi_data( + "2017-05-01", "2017-05-05", [] + ) + self.assertEqual(r, {self.expr1: 5}) + # two full + r = self.env["mis.kpi.data.test.item"]._query_kpi_data( + "2017-05-01", "2017-05-20", [] + ) + self.assertEqual(r, {self.expr1: 30}) + # two half + r = self.env["mis.kpi.data.test.item"]._query_kpi_data( + "2017-05-06", "2017-05-15", [] + ) + self.assertEqual(r, {self.expr1: 15}) + # more than covered range + r = self.env["mis.kpi.data.test.item"]._query_kpi_data( + "2017-01-01", "2017-05-31", [] + ) + self.assertEqual(r, {self.expr1: 60}) + # two kpis + r = self.env["mis.kpi.data.test.item"]._query_kpi_data( + "2017-05-21", "2017-06-30", [] + ) + self.assertEqual(r, {self.expr1: 30, self.expr2: 3}) + + def test_kpi_data_avg(self): + self.kpi1.accumulation_method = ACC_AVG + # one full + r = self.env["mis.kpi.data.test.item"]._query_kpi_data( + "2017-05-01", "2017-05-10", [] + ) + self.assertEqual(r, {self.expr1: 10}) + # one half + r = self.env["mis.kpi.data.test.item"]._query_kpi_data( + "2017-05-01", "2017-05-05", [] + ) + self.assertEqual(r, {self.expr1: 10}) + # two full + r = self.env["mis.kpi.data.test.item"]._query_kpi_data( + "2017-05-01", "2017-05-20", [] + ) + self.assertEqual(r, {self.expr1: (10 * 10 + 20 * 10) / 20}) + # two half + r = self.env["mis.kpi.data.test.item"]._query_kpi_data( + "2017-05-06", "2017-05-15", [] + ) + self.assertEqual(r, {self.expr1: (10 * 5 + 20 * 5) / 10}) + # more than covered range + r = self.env["mis.kpi.data.test.item"]._query_kpi_data( + "2017-01-01", "2017-05-31", [] + ) + self.assertEqual(r, {self.expr1: (10 * 10 + 20 * 10 + 30 * 5) / 25}) diff --git a/odex25_accounting/mis_builder/tests/test_mis_report_instance.py b/odex25_accounting/mis_builder/tests/test_mis_report_instance.py new file mode 100644 index 000000000..82394038d --- /dev/null +++ b/odex25_accounting/mis_builder/tests/test_mis_report_instance.py @@ -0,0 +1,551 @@ +# Copyright 2016 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import odoo.tests.common as common +from odoo.tools import test_reports + +from ..models.accounting_none import AccountingNone +from ..models.mis_report import TYPE_STR, SubKPITupleLengthError, SubKPIUnknownTypeError + + +class TestMisReportInstance(common.HttpCase): + """Basic integration test to exercise mis.report.instance. + + We don't check the actual results here too much as computation correctness + should be covered by lower level unit tests. + """ + + def setUp(self): + super(TestMisReportInstance, self).setUp() + partner_model_id = self.env.ref("base.model_res_partner").id + partner_create_date_field_id = self.env.ref( + "base.field_res_partner__create_date" + ).id + partner_debit_field_id = self.env.ref("account.field_res_partner__debit").id + # create a report with 2 subkpis and one query + self.report = self.env["mis.report"].create( + dict( + name="test report", + subkpi_ids=[ + (0, 0, dict(name="sk1", description="subkpi 1", sequence=1)), + (0, 0, dict(name="sk2", description="subkpi 2", sequence=2)), + ], + query_ids=[ + ( + 0, + 0, + dict( + name="partner", + model_id=partner_model_id, + field_ids=[(4, partner_debit_field_id, None)], + date_field=partner_create_date_field_id, + aggregate="sum", + ), + ) + ], + ) + ) + # create another report with 2 subkpis, no query + self.report_2 = self.env["mis.report"].create( + dict( + name="another test report", + subkpi_ids=[ + ( + 0, + 0, + dict( + name="subkpi1_report2", + description="subkpi 1, report 2", + sequence=1, + ), + ), + ( + 0, + 0, + dict( + name="subkpi2_report2", + description="subkpi 2, report 2", + sequence=2, + ), + ), + ], + ) + ) + # Third report, 2 subkpis, no query + self.report_3 = self.env["mis.report"].create( + dict( + name="test report 3", + subkpi_ids=[ + ( + 0, + 0, + dict( + name="subkpi1_report3", + description="subkpi 1, report 3", + sequence=1, + ), + ), + ( + 0, + 0, + dict( + name="subkpi2_report3", + description="subkpi 2, report 3", + sequence=2, + ), + ), + ], + ) + ) + # kpi with accounting formulas + self.kpi1 = self.env["mis.report.kpi"].create( + dict( + report_id=self.report.id, + description="kpi 1", + name="k1", + multi=True, + expression_ids=[ + ( + 0, + 0, + dict(name="bale[200%]", subkpi_id=self.report.subkpi_ids[0].id), + ), + ( + 0, + 0, + dict(name="balp[200%]", subkpi_id=self.report.subkpi_ids[1].id), + ), + ], + ) + ) + # kpi with accounting formula and query + self.kpi2 = self.env["mis.report.kpi"].create( + dict( + report_id=self.report.id, + description="kpi 2", + name="k2", + multi=True, + expression_ids=[ + ( + 0, + 0, + dict(name="balp[200%]", subkpi_id=self.report.subkpi_ids[0].id), + ), + ( + 0, + 0, + dict( + name="partner.debit", subkpi_id=self.report.subkpi_ids[1].id + ), + ), + ], + ) + ) + # kpi with a simple expression summing other multi-valued kpis + self.env["mis.report.kpi"].create( + dict( + report_id=self.report.id, + description="kpi 4", + name="k4", + multi=False, + expression="k1 + k2 + k3", + ) + ) + # kpi with 2 constants + self.env["mis.report.kpi"].create( + dict( + report_id=self.report.id, + description="kpi 3", + name="k3", + multi=True, + expression_ids=[ + ( + 0, + 0, + dict( + name="AccountingNone", + subkpi_id=self.report.subkpi_ids[0].id, + ), + ), + (0, 0, dict(name="1.0", subkpi_id=self.report.subkpi_ids[1].id)), + ], + ) + ) + # kpi with a NameError (x not defined) + self.env["mis.report.kpi"].create( + dict( + report_id=self.report.id, + description="kpi 5", + name="k5", + multi=True, + expression_ids=[ + (0, 0, dict(name="x", subkpi_id=self.report.subkpi_ids[0].id)), + (0, 0, dict(name="1.0", subkpi_id=self.report.subkpi_ids[1].id)), + ], + ) + ) + # string-type kpi + self.env["mis.report.kpi"].create( + dict( + report_id=self.report.id, + description="kpi 6", + name="k6", + multi=True, + type=TYPE_STR, + expression_ids=[ + (0, 0, dict(name='"bla"', subkpi_id=self.report.subkpi_ids[0].id)), + ( + 0, + 0, + dict(name='"blabla"', subkpi_id=self.report.subkpi_ids[1].id), + ), + ], + ) + ) + # kpi that references another subkpi by name + self.env["mis.report.kpi"].create( + dict( + report_id=self.report.id, + description="kpi 7", + name="k7", + multi=True, + expression_ids=[ + (0, 0, dict(name="k3.sk1", subkpi_id=self.report.subkpi_ids[0].id)), + (0, 0, dict(name="k3.sk2", subkpi_id=self.report.subkpi_ids[1].id)), + ], + ) + ) + # Report 2 : kpi with AccountingNone value + self.env["mis.report.kpi"].create( + dict( + report_id=self.report_2.id, + description="AccountingNone kpi", + name="AccountingNoneKPI", + multi=False, + ) + ) + # Report 2 : 'classic' kpi with values for each sub-KPI + self.env["mis.report.kpi"].create( + dict( + report_id=self.report_2.id, + description="Classic kpi", + name="classic_kpi_r2", + multi=True, + expression_ids=[ + ( + 0, + 0, + dict( + name="bale[200%]", subkpi_id=self.report_2.subkpi_ids[0].id + ), + ), + ( + 0, + 0, + dict( + name="balp[200%]", subkpi_id=self.report_2.subkpi_ids[1].id + ), + ), + ], + ) + ) + # Report 3 : kpi with wrong tuple length + self.env["mis.report.kpi"].create( + dict( + report_id=self.report_3.id, + description="Wrong tuple length kpi", + name="wrongTupleLen", + multi=False, + expression="('hello', 'does', 'this', 'work')", + ) + ) + # Report 3 : 'classic' kpi + self.env["mis.report.kpi"].create( + dict( + report_id=self.report_3.id, + description="Classic kpi", + name="classic_kpi_r2", + multi=True, + expression_ids=[ + ( + 0, + 0, + dict( + name="bale[200%]", subkpi_id=self.report_3.subkpi_ids[0].id + ), + ), + ( + 0, + 0, + dict( + name="balp[200%]", subkpi_id=self.report_3.subkpi_ids[1].id + ), + ), + ], + ) + ) + # create a report instance + self.report_instance = self.env["mis.report.instance"].create( + dict( + name="test instance", + report_id=self.report.id, + company_id=self.env.ref("base.main_company").id, + period_ids=[ + ( + 0, + 0, + dict( + name="p1", + mode="relative", + type="d", + subkpi_ids=[(4, self.report.subkpi_ids[0].id, None)], + ), + ), + ( + 0, + 0, + dict( + name="p2", + mode="fix", + manual_date_from="2014-01-01", + manual_date_to="2014-12-31", + ), + ), + ], + ) + ) + # same for report 2 + self.report_instance_2 = self.env["mis.report.instance"].create( + dict( + name="test instance 2", + report_id=self.report_2.id, + company_id=self.env.ref("base.main_company").id, + period_ids=[ + ( + 0, + 0, + dict( + name="p3", + mode="fix", + manual_date_from="2019-01-01", + manual_date_to="2019-12-31", + ), + ) + ], + ) + ) + # and for report 3 + self.report_instance_3 = self.env["mis.report.instance"].create( + dict( + name="test instance 3", + report_id=self.report_3.id, + company_id=self.env.ref("base.main_company").id, + period_ids=[ + ( + 0, + 0, + dict( + name="p4", + mode="fix", + manual_date_from="2019-01-01", + manual_date_to="2019-12-31", + ), + ) + ], + ) + ) + + def test_compute(self): + matrix = self.report_instance._compute_matrix() + for row in matrix.iter_rows(): + vals = [c.val for c in row.iter_cells()] + if row.kpi.name == "k3": + # k3 is constant + self.assertEqual(vals, [AccountingNone, AccountingNone, 1.0]) + elif row.kpi.name == "k6": + # k6 is a string kpi + self.assertEqual(vals, ["bla", "bla", "blabla"]) + elif row.kpi.name == "k7": + # k7 references k3 via subkpi names + self.assertEqual(vals, [AccountingNone, AccountingNone, 1.0]) + + def test_multi_company_compute(self): + self.report_instance.write( + { + "multi_company": True, + "company_ids": [(6, 0, self.report_instance.company_id.ids)], + } + ) + self.report_instance.report_id.kpi_ids.write({"auto_expand_accounts": True}) + matrix = self.report_instance._compute_matrix() + for row in matrix.iter_rows(): + if row.account_id: + account = self.env["account.account"].browse(row.account_id) + self.assertEqual( + row.label, + "%s %s [%s]" + % (account.code, account.name, account.company_id.name), + ) + self.report_instance.write({"multi_company": False}) + matrix = self.report_instance._compute_matrix() + for row in matrix.iter_rows(): + if row.account_id: + account = self.env["account.account"].browse(row.account_id) + self.assertEqual(row.label, "{} {}".format(account.code, account.name)) + + def test_evaluate(self): + company = self.env.ref("base.main_company") + aep = self.report._prepare_aep(company) + r = self.report.evaluate(aep, date_from="2014-01-01", date_to="2014-12-31") + self.assertEqual(r["k3"], (AccountingNone, 1.0)) + self.assertEqual(r["k6"], ("bla", "blabla")) + self.assertEqual(r["k7"], (AccountingNone, 1.0)) + + def test_json(self): + self.report_instance.compute() + + def test_drilldown(self): + action = self.report_instance.drilldown( + dict(expr="balp[200%]", period_id=self.report_instance.period_ids[0].id) + ) + account_ids = ( + self.env["account.account"].search([("code", "=like", "200%")]).ids + ) + self.assertTrue(("account_id", "in", tuple(account_ids)) in action["domain"]) + self.assertEqual(action["res_model"], "account.move.line") + + def test_drilldown_action_name_with_account(self): + period = self.report_instance.period_ids[0] + account = self.env["account.account"].search([], limit=1) + args = { + "period_id": period.id, + "kpi_id": self.kpi1.id, + "account_id": account.id, + } + action_name = self.report_instance._get_drilldown_action_name(args) + expected_name = "{kpi} - {account} - {period}".format( + kpi=self.kpi1.description, + account=account.display_name, + period=period.display_name, + ) + assert action_name == expected_name + + def test_drilldown_action_name_without_account(self): + period = self.report_instance.period_ids[0] + args = { + "period_id": period.id, + "kpi_id": self.kpi1.id, + } + action_name = self.report_instance._get_drilldown_action_name(args) + expected_name = "{kpi} - {period}".format( + kpi=self.kpi1.description, + period=period.display_name, + ) + assert action_name == expected_name + + def test_qweb(self): + self.report_instance.print_pdf() # get action + test_reports.try_report( + self.env.cr, + self.env.uid, + "mis_builder.report_mis_report_instance", + [self.report_instance.id], + report_type="qweb-pdf", + ) + + def test_xlsx(self): + self.report_instance.export_xls() # get action + test_reports.try_report( + self.env.cr, + self.env.uid, + "mis_builder.mis_report_instance_xlsx", + [self.report_instance.id], + report_type="xlsx", + ) + + def test_get_kpis_by_account_id(self): + account_ids = ( + self.env["account.account"].search([("code", "=like", "200%")]).mapped("id") + ) + kpi200 = {self.kpi1, self.kpi2} + res = self.report.get_kpis_by_account_id(self.env.ref("base.main_company")) + for account_id in account_ids: + self.assertTrue(account_id in res) + self.assertEqual(res[account_id], kpi200) + + def test_kpi_name_get_name_search(self): + r = self.env["mis.report.kpi"].name_search("k1") + self.assertEqual(len(r), 1) + self.assertEqual(r[0][0], self.kpi1.id) + self.assertEqual(r[0][1], "kpi 1 (k1)") + r = self.env["mis.report.kpi"].name_search("kpi 1") + self.assertEqual(len(r), 1) + self.assertEqual(r[0][0], self.kpi1.id) + self.assertEqual(r[0][1], "kpi 1 (k1)") + + def test_kpi_expr_name_get_name_search(self): + r = self.env["mis.report.kpi.expression"].name_search("k1") + self.assertEqual( + [i[1] for i in r], + ["kpi 1 / subkpi 1 (k1.sk1)", "kpi 1 / subkpi 2 (k1.sk2)"], + ) + r = self.env["mis.report.kpi.expression"].name_search("k1.sk1") + self.assertEqual([i[1] for i in r], ["kpi 1 / subkpi 1 (k1.sk1)"]) + r = self.env["mis.report.kpi.expression"].name_search("k4") + self.assertEqual([i[1] for i in r], ["kpi 4 (k4)"]) + + def test_multi_company_onchange(self): + # not multi company + self.assertTrue(self.report_instance.company_id) + self.assertFalse(self.report_instance.multi_company) + self.assertFalse(self.report_instance.company_ids) + self.assertEqual( + self.report_instance.query_company_ids[0], self.report_instance.company_id + ) + # create a child company + self.env["res.company"].create( + dict(name="company 2", parent_id=self.report_instance.company_id.id) + ) + companies = self.env["res.company"].search( + [("id", "child_of", self.report_instance.company_id.id)] + ) + self.report_instance.multi_company = True + # multi company, company_ids not set + self.assertEqual( + self.report_instance.query_company_ids[0], self.report_instance.company_id + ) + # set company_ids + self.report_instance._onchange_company() + self.assertTrue(self.report_instance.multi_company) + self.assertEqual(self.report_instance.company_ids, companies) + self.assertEqual(self.report_instance.query_company_ids, companies) + # reset single company mode + self.report_instance.multi_company = False + self.assertEqual( + self.report_instance.query_company_ids[0], self.report_instance.company_id + ) + self.report_instance._onchange_company() + self.assertFalse(self.report_instance.company_ids) + + def test_mis_report_analytic_filters(self): + # Check that matrix has no values when using a filter with a non + # existing account + matrix = self.report_instance.with_context( + mis_report_filters={"analytic_account_id": {"value": 999}} + )._compute_matrix() + for row in matrix.iter_rows(): + vals = [c.val for c in row.iter_cells()] + if row.kpi.name == "k1": + self.assertEqual(vals, [AccountingNone, AccountingNone, AccountingNone]) + elif row.kpi.name == "k2": + self.assertEqual(vals, [AccountingNone, AccountingNone, None]) + elif row.kpi.name == "k4": + self.assertEqual(vals, [AccountingNone, AccountingNone, 1.0]) + + def test_raise_when_unknown_kpi_value_type(self): + with self.assertRaises(SubKPIUnknownTypeError): + self.report_instance_2.compute() + + def test_raise_when_wrong_tuple_length_with_subkpis(self): + with self.assertRaises(SubKPITupleLengthError): + self.report_instance_3.compute() diff --git a/odex25_accounting/mis_builder/tests/test_mis_safe_eval.py b/odex25_accounting/mis_builder/tests/test_mis_safe_eval.py new file mode 100644 index 000000000..c6947fe9c --- /dev/null +++ b/odex25_accounting/mis_builder/tests/test_mis_safe_eval.py @@ -0,0 +1,25 @@ +# Copyright 2016 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import odoo.tests.common as common + +from ..models.mis_safe_eval import DataError, NameDataError, mis_safe_eval + + +class TestMisSafeEval(common.TransactionCase): + def test_nominal(self): + val = mis_safe_eval("a + 1", {"a": 1}) + self.assertEqual(val, 2) + + def test_exceptions(self): + val = mis_safe_eval("1/0", {}) # division by zero + self.assertTrue(isinstance(val, DataError)) + self.assertEqual(val.name, "#DIV/0") + val = mis_safe_eval("1a", {}) # syntax error + self.assertTrue(isinstance(val, DataError)) + self.assertEqual(val.name, "#ERR") + + def test_name_error(self): + val = mis_safe_eval("a + 1", {}) + self.assertTrue(isinstance(val, NameDataError)) + self.assertEqual(val.name, "#NAME") diff --git a/odex25_accounting/mis_builder/tests/test_multi_company_aep.py b/odex25_accounting/mis_builder/tests/test_multi_company_aep.py new file mode 100644 index 000000000..cd7988918 --- /dev/null +++ b/odex25_accounting/mis_builder/tests/test_multi_company_aep.py @@ -0,0 +1,207 @@ +# Copyright 2014 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import datetime + +import odoo.tests.common as common +from odoo import fields +from odoo.tools.safe_eval import safe_eval + +from ..models.accounting_none import AccountingNone +from ..models.aep import AccountingExpressionProcessor as AEP + + +class TestMultiCompanyAEP(common.TransactionCase): + def setUp(self): + super(TestMultiCompanyAEP, self).setUp() + self.res_company = self.env["res.company"] + self.account_model = self.env["account.account"] + self.move_model = self.env["account.move"] + self.journal_model = self.env["account.journal"] + self.currency_model = self.env["res.currency"] + self.curr_year = datetime.date.today().year + self.prev_year = self.curr_year - 1 + self.usd = self.currency_model.search([("name", "=", "USD")]) + self.eur = self.currency_model.search([("name", "=", "EUR")]) + # create company A and B + self.company_eur = self.res_company.create( + {"name": "CYEUR", "currency_id": self.eur.id} + ) + self.company_usd = self.res_company.create( + {"name": "CYUSD", "currency_id": self.usd.id} + ) + self.env["res.currency.rate"].search([]).unlink() + type_ar = self.browse_ref("account.data_account_type_receivable") + type_in = self.browse_ref("account.data_account_type_revenue") + for company, divider in [(self.company_eur, 1.0), (self.company_usd, 2.0)]: + # create receivable bs account + company_key = company.name + setattr( + self, + "account_ar_" + company_key, + self.account_model.create( + { + "company_id": company.id, + "code": "400AR", + "name": "Receivable", + "user_type_id": type_ar.id, + "reconcile": True, + } + ), + ) + # create income pl account + setattr( + self, + "account_in_" + company_key, + self.account_model.create( + { + "company_id": company.id, + "code": "700IN", + "name": "Income", + "user_type_id": type_in.id, + } + ), + ) + # create journal + setattr( + self, + "journal" + company_key, + self.journal_model.create( + { + "company_id": company.id, + "name": "Sale journal", + "code": "VEN", + "type": "sale", + } + ), + ) + # create move in december last year + self._create_move( + journal=getattr(self, "journal" + company_key), + date=datetime.date(self.prev_year, 12, 1), + amount=100 / divider, + debit_acc=getattr(self, "account_ar_" + company_key), + credit_acc=getattr(self, "account_in_" + company_key), + ) + # create move in january this year + self._create_move( + journal=getattr(self, "journal" + company_key), + date=datetime.date(self.curr_year, 1, 1), + amount=300 / divider, + debit_acc=getattr(self, "account_ar_" + company_key), + credit_acc=getattr(self, "account_in_" + company_key), + ) + # create move in february this year + self._create_move( + journal=getattr(self, "journal" + company_key), + date=datetime.date(self.curr_year, 3, 1), + amount=500 / divider, + debit_acc=getattr(self, "account_ar_" + company_key), + credit_acc=getattr(self, "account_in_" + company_key), + ) + + def _create_move(self, journal, date, amount, debit_acc, credit_acc): + move = self.move_model.create( + { + "journal_id": journal.id, + "date": fields.Date.to_string(date), + "line_ids": [ + (0, 0, {"name": "/", "debit": amount, "account_id": debit_acc.id}), + ( + 0, + 0, + {"name": "/", "credit": amount, "account_id": credit_acc.id}, + ), + ], + } + ) + move._post() + return move + + def _do_queries(self, companies, currency, date_from, date_to): + # create the AEP, and prepare the expressions we'll need + aep = AEP(companies, currency) + aep.parse_expr("bali[]") + aep.parse_expr("bale[]") + aep.parse_expr("balp[]") + aep.parse_expr("balu[]") + aep.parse_expr("bali[700IN]") + aep.parse_expr("bale[700IN]") + aep.parse_expr("balp[700IN]") + aep.parse_expr("bali[400AR]") + aep.parse_expr("bale[400AR]") + aep.parse_expr("balp[400AR]") + aep.parse_expr("debp[400A%]") + aep.parse_expr("crdp[700I%]") + aep.parse_expr("bali[400%]") + aep.parse_expr("bale[700%]") + aep.done_parsing() + aep.do_queries( + date_from=fields.Date.to_string(date_from), + date_to=fields.Date.to_string(date_to), + target_move="posted", + ) + return aep + + def _eval(self, aep, expr): + eval_dict = {"AccountingNone": AccountingNone} + return safe_eval(aep.replace_expr(expr), eval_dict) + + def _eval_by_account_id(self, aep, expr): + res = {} + eval_dict = {"AccountingNone": AccountingNone} + for account_id, replaced_exprs in aep.replace_exprs_by_account_id([expr]): + res[account_id] = safe_eval(replaced_exprs[0], eval_dict) + return res + + def test_aep_basic(self): + # let's query for december, one company + aep = self._do_queries( + self.company_eur, + None, + datetime.date(self.prev_year, 12, 1), + datetime.date(self.prev_year, 12, 31), + ) + self.assertEqual(self._eval(aep, "balp[700IN]"), -100) + aep = self._do_queries( + self.company_usd, + None, + datetime.date(self.prev_year, 12, 1), + datetime.date(self.prev_year, 12, 31), + ) + self.assertEqual(self._eval(aep, "balp[700IN]"), -50) + # let's query for december, two companies + aep = self._do_queries( + self.company_eur | self.company_usd, + self.eur, + datetime.date(self.prev_year, 12, 1), + datetime.date(self.prev_year, 12, 31), + ) + self.assertEqual(self._eval(aep, "balp[700IN]"), -150) + + def test_aep_multi_currency(self): + date_from = datetime.date(self.prev_year, 12, 1) + date_to = datetime.date(self.prev_year, 12, 31) + today = datetime.date.today() + self.env["res.currency.rate"].create( + dict(currency_id=self.usd.id, name=date_to, rate=1.1) + ) + self.env["res.currency.rate"].create( + dict(currency_id=self.usd.id, name=today, rate=1.2) + ) + # let's query for december, one company, default currency = eur + aep = self._do_queries(self.company_eur, None, date_from, date_to) + self.assertEqual(self._eval(aep, "balp[700IN]"), -100) + # let's query for december, two companies + aep = self._do_queries( + self.company_eur | self.company_usd, self.eur, date_from, date_to + ) + self.assertAlmostEqual(self._eval(aep, "balp[700IN]"), -100 - 50 / 1.1) + # let's query for december, one company, currency = usd + aep = self._do_queries(self.company_eur, self.usd, date_from, date_to) + self.assertAlmostEqual(self._eval(aep, "balp[700IN]"), -100 * 1.1) + # let's query for december, two companies, currency = usd + aep = self._do_queries( + self.company_eur | self.company_usd, self.usd, date_from, date_to + ) + self.assertAlmostEqual(self._eval(aep, "balp[700IN]"), -100 * 1.1 - 50) diff --git a/odex25_accounting/mis_builder/tests/test_period_dates.py b/odex25_accounting/mis_builder/tests/test_period_dates.py new file mode 100644 index 000000000..fb72627dd --- /dev/null +++ b/odex25_accounting/mis_builder/tests/test_period_dates.py @@ -0,0 +1,159 @@ +# Copyright 2017 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import odoo.tests.common as common +from odoo import fields + +from ..models.mis_report_instance import ( + MODE_FIX, + MODE_NONE, + MODE_REL, + SRC_SUMCOL, + DateFilterForbidden, + DateFilterRequired, +) +from .common import assert_matrix + + +class TestPeriodDates(common.TransactionCase): + def setUp(self): + super(TestPeriodDates, self).setUp() + self.report_obj = self.env["mis.report"] + self.instance_obj = self.env["mis.report.instance"] + self.period_obj = self.env["mis.report.instance.period"] + self.report = self.report_obj.create(dict(name="test-report")) + self.instance = self.instance_obj.create( + dict(name="test-instance", report_id=self.report.id, comparison_mode=False) + ) + self.assertEqual(len(self.instance.period_ids), 1) + self.period = self.instance.period_ids[0] + + def assertDateEqual(self, first, second, msg=None): + self.assertEqual(first, fields.Date.from_string(second), msg) + + def test_date_filter_constraints(self): + self.instance.comparison_mode = True + with self.assertRaises(DateFilterRequired): + self.period.write(dict(mode=MODE_NONE)) + with self.assertRaises(DateFilterForbidden): + self.period.write(dict(mode=MODE_FIX, source=SRC_SUMCOL)) + + def test_simple_mode(self): + # not comparison_mode + self.assertFalse(self.instance.comparison_mode) + period = self.instance.period_ids[0] + self.assertEqual(period.date_from, self.instance.date_from) + self.assertEqual(period.date_to, self.instance.date_to) + + def tests_mode_none(self): + self.instance.comparison_mode = True + self.period.write(dict(mode=MODE_NONE, source=SRC_SUMCOL)) + self.assertFalse(self.period.date_from) + self.assertFalse(self.period.date_to) + self.assertTrue(self.period.valid) + + def tests_mode_fix(self): + self.instance.comparison_mode = True + self.period.write( + dict( + mode=MODE_FIX, + manual_date_from="2017-01-01", + manual_date_to="2017-12-31", + ) + ) + self.assertDateEqual(self.period.date_from, "2017-01-01") + self.assertDateEqual(self.period.date_to, "2017-12-31") + self.assertTrue(self.period.valid) + + def test_rel_day(self): + self.instance.write(dict(comparison_mode=True, date="2017-01-01")) + self.period.write(dict(mode=MODE_REL, type="d", offset="-2")) + self.assertDateEqual(self.period.date_from, "2016-12-30") + self.assertDateEqual(self.period.date_to, "2016-12-30") + self.assertTrue(self.period.valid) + + def test_rel_day_ytd(self): + self.instance.write(dict(comparison_mode=True, date="2019-05-03")) + self.period.write(dict(mode=MODE_REL, type="d", offset="-2", is_ytd=True)) + self.assertDateEqual(self.period.date_from, "2019-01-01") + self.assertDateEqual(self.period.date_to, "2019-05-01") + self.assertTrue(self.period.valid) + + def test_rel_week(self): + self.instance.write(dict(comparison_mode=True, date="2016-12-30")) + self.period.write(dict(mode=MODE_REL, type="w", offset="1", duration=2)) + # from Monday to Sunday, the week after 2016-12-30 + self.assertDateEqual(self.period.date_from, "2017-01-02") + self.assertDateEqual(self.period.date_to, "2017-01-15") + self.assertTrue(self.period.valid) + + def test_rel_week_ytd(self): + self.instance.write(dict(comparison_mode=True, date="2019-05-27")) + self.period.write( + dict(mode=MODE_REL, type="w", offset="1", duration=2, is_ytd=True) + ) + self.assertDateEqual(self.period.date_from, "2019-01-01") + self.assertDateEqual(self.period.date_to, "2019-06-16") + self.assertTrue(self.period.valid) + + def test_rel_month(self): + self.instance.write(dict(comparison_mode=True, date="2017-01-05")) + self.period.write(dict(mode=MODE_REL, type="m", offset="1")) + self.assertDateEqual(self.period.date_from, "2017-02-01") + self.assertDateEqual(self.period.date_to, "2017-02-28") + self.assertTrue(self.period.valid) + + def test_rel_month_ytd(self): + self.instance.write(dict(comparison_mode=True, date="2019-05-15")) + self.period.write(dict(mode=MODE_REL, type="m", offset="-1", is_ytd=True)) + self.assertDateEqual(self.period.date_from, "2019-01-01") + self.assertDateEqual(self.period.date_to, "2019-04-30") + self.assertTrue(self.period.valid) + + def test_rel_year(self): + self.instance.write(dict(comparison_mode=True, date="2017-05-06")) + self.period.write(dict(mode=MODE_REL, type="y", offset="1")) + self.assertDateEqual(self.period.date_from, "2018-01-01") + self.assertDateEqual(self.period.date_to, "2018-12-31") + self.assertTrue(self.period.valid) + + def test_rel_date_range(self): + # create a few date ranges + date_range_type = self.env["date.range.type"].create(dict(name="Year")) + for year in (2016, 2017, 2018): + self.env["date.range"].create( + dict( + type_id=date_range_type.id, + name="%d" % year, + date_start="%d-01-01" % year, + date_end="%d-12-31" % year, + company_id=False, + ) + ) + self.instance.write(dict(comparison_mode=True, date="2017-06-15")) + self.period.write( + dict( + mode=MODE_REL, + type="date_range", + date_range_type_id=date_range_type.id, + offset="-1", + duration=3, + ) + ) + self.assertDateEqual(self.period.date_from, "2016-01-01") + self.assertDateEqual(self.period.date_to, "2018-12-31") + self.assertTrue(self.period.valid) + + def test_dates_in_expr(self): + self.env["mis.report.kpi"].create( + dict( + report_id=self.report.id, + name="k1", + description="kpi 1", + expression="(date_to - date_from).days + 1", + ) + ) + self.instance.date_from = "2017-01-01" + self.instance.date_to = "2017-01-31" + matrix = self.instance._compute_matrix() + assert_matrix(matrix, [[31]]) diff --git a/odex25_accounting/mis_builder/tests/test_render.py b/odex25_accounting/mis_builder/tests/test_render.py new file mode 100644 index 000000000..7c1234c61 --- /dev/null +++ b/odex25_accounting/mis_builder/tests/test_render.py @@ -0,0 +1,317 @@ +# Copyright 2016 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import odoo.tests.common as common + +from ..models.accounting_none import AccountingNone +from ..models.data_error import DataError +from ..models.mis_report_style import CMP_DIFF, CMP_PCT, TYPE_NUM, TYPE_PCT, TYPE_STR + + +class TestRendering(common.TransactionCase): + def setUp(self): + super(TestRendering, self).setUp() + self.style_obj = self.env["mis.report.style"] + self.kpi_obj = self.env["mis.report.kpi"] + self.style = self.style_obj.create(dict(name="teststyle")) + self.lang = ( + self.env["res.lang"] + .with_context(active_test=False) + .search([("code", "=", "en_US")])[0] + ) + + def _render(self, value, type=TYPE_NUM): + style_props = self.style_obj.merge([self.style]) + return self.style_obj.render(self.lang, style_props, type, value) + + def _compare_and_render( + self, value, base_value, type=TYPE_NUM, compare_method=CMP_PCT + ): + style_props = self.style_obj.merge([self.style]) + r = self.style_obj.compare_and_render( + self.lang, style_props, type, compare_method, value, base_value + )[:2] + if r[0]: + return (round(r[0], 8), r[1]) + else: + return r + + def test_render(self): + self.assertEqual(u"1", self._render(1)) + self.assertEqual(u"1", self._render(1.1)) + self.assertEqual(u"2", self._render(1.6)) + self.style.dp_inherit = False + self.style.dp = 2 + self.assertEqual(u"1.00", self._render(1)) + self.assertEqual(u"1.10", self._render(1.1)) + self.assertEqual(u"1.60", self._render(1.6)) + self.assertEqual(u"1.61", self._render(1.606)) + self.assertEqual(u"12,345.67", self._render(12345.67)) + + def test_render_negative(self): + # non breaking hyphen + self.assertEqual(u"\u20111", self._render(-1)) + + def test_render_zero(self): + self.assertEqual(u"0", self._render(0)) + self.assertEqual(u"", self._render(None)) + self.assertEqual(u"", self._render(AccountingNone)) + + def test_render_suffix(self): + self.style.suffix_inherit = False + self.style.suffix = u"€" + self.assertEqual(u"1\xa0€", self._render(1)) + self.style.suffix = u"k€" + self.style.divider_inherit = False + self.style.divider = "1e3" + self.assertEqual(u"1\xa0k€", self._render(1000)) + + def test_render_prefix(self): + self.style.prefix_inherit = False + self.style.prefix = u"$" + self.assertEqual(u"$\xa01", self._render(1)) + self.style.prefix = u"k$" + self.style.divider_inherit = False + self.style.divider = "1e3" + self.assertEqual(u"k$\xa01", self._render(1000)) + + def test_render_divider(self): + self.style.divider_inherit = False + self.style.divider = "1e3" + self.style.dp_inherit = False + self.style.dp = 0 + self.assertEqual(u"1", self._render(1000)) + self.style.divider = "1e6" + self.style.dp = 3 + self.assertEqual(u"0.001", self._render(1000)) + self.style.divider = "1e-3" + self.style.dp = 0 + self.assertEqual(u"1,000", self._render(1)) + self.style.divider = "1e-6" + self.style.dp = 0 + self.assertEqual(u"1,000,000", self._render(1)) + + def test_render_pct(self): + self.assertEqual(u"100\xa0%", self._render(1, TYPE_PCT)) + self.assertEqual(u"50\xa0%", self._render(0.5, TYPE_PCT)) + self.style.dp_inherit = False + self.style.dp = 2 + self.assertEqual(u"51.23\xa0%", self._render(0.5123, TYPE_PCT)) + + def test_render_string(self): + self.assertEqual(u"", self._render("", TYPE_STR)) + self.assertEqual(u"", self._render(None, TYPE_STR)) + self.assertEqual(u"abcdé", self._render(u"abcdé", TYPE_STR)) + + def test_compare_num_pct(self): + self.assertEqual((1.0, u"+100.0\xa0%"), self._compare_and_render(100, 50)) + self.assertEqual((0.5, u"+50.0\xa0%"), self._compare_and_render(75, 50)) + self.assertEqual((0.5, u"+50.0\xa0%"), self._compare_and_render(-25, -50)) + self.assertEqual((1.0, u"+100.0\xa0%"), self._compare_and_render(0, -50)) + self.assertEqual((2.0, u"+200.0\xa0%"), self._compare_and_render(50, -50)) + self.assertEqual((-0.5, u"\u201150.0\xa0%"), self._compare_and_render(25, 50)) + self.assertEqual((-1.0, u"\u2011100.0\xa0%"), self._compare_and_render(0, 50)) + self.assertEqual((-2.0, u"\u2011200.0\xa0%"), self._compare_and_render(-50, 50)) + self.assertEqual((-0.5, u"\u201150.0\xa0%"), self._compare_and_render(-75, -50)) + self.assertEqual( + (AccountingNone, u""), self._compare_and_render(50, AccountingNone) + ) + self.assertEqual((AccountingNone, u""), self._compare_and_render(50, None)) + self.assertEqual((AccountingNone, u""), self._compare_and_render(50, 50)) + self.assertEqual((0.002, u"+0.2\xa0%"), self._compare_and_render(50.1, 50)) + self.assertEqual((AccountingNone, u""), self._compare_and_render(50.01, 50)) + self.assertEqual( + (-1.0, u"\u2011100.0\xa0%"), self._compare_and_render(AccountingNone, 50) + ) + self.assertEqual( + (-1.0, u"\u2011100.0\xa0%"), self._compare_and_render(None, 50) + ) + self.assertEqual( + (AccountingNone, u""), self._compare_and_render(DataError("#ERR", "."), 1) + ) + self.assertEqual( + (AccountingNone, u""), self._compare_and_render(1, DataError("#ERR", ".")) + ) + + def test_compare_num_diff(self): + self.assertEqual( + (25, u"+25"), self._compare_and_render(75, 50, TYPE_NUM, CMP_DIFF) + ) + self.assertEqual( + (-25, u"\u201125"), self._compare_and_render(25, 50, TYPE_NUM, CMP_DIFF) + ) + self.style.suffix_inherit = False + self.style.suffix = u"€" + self.assertEqual( + (-25, u"\u201125\xa0€"), + self._compare_and_render(25, 50, TYPE_NUM, CMP_DIFF), + ) + self.style.suffix = u"" + self.assertEqual( + (50.0, u"+50"), + self._compare_and_render(50, AccountingNone, TYPE_NUM, CMP_DIFF), + ) + self.assertEqual( + (50.0, u"+50"), self._compare_and_render(50, None, TYPE_NUM, CMP_DIFF) + ) + self.assertEqual( + (-50.0, u"\u201150"), + self._compare_and_render(AccountingNone, 50, TYPE_NUM, CMP_DIFF), + ) + self.assertEqual( + (-50.0, u"\u201150"), self._compare_and_render(None, 50, TYPE_NUM, CMP_DIFF) + ) + self.style.dp_inherit = False + self.style.dp = 2 + self.assertEqual( + (0.1, u"+0.10"), self._compare_and_render(1.1, 1.0, TYPE_NUM, CMP_DIFF) + ) + self.assertEqual( + (AccountingNone, u""), + self._compare_and_render(1.001, 1.0, TYPE_NUM, CMP_DIFF), + ) + + def test_compare_pct(self): + self.assertEqual( + (0.25, u"+25\xa0pp"), self._compare_and_render(0.75, 0.50, TYPE_PCT) + ) + self.assertEqual( + (AccountingNone, u""), self._compare_and_render(0.751, 0.750, TYPE_PCT) + ) + + def test_compare_pct_result_type(self): + style_props = self.style_obj.merge([self.style]) + result = self.style_obj.compare_and_render( + self.lang, style_props, TYPE_PCT, CMP_DIFF, 0.75, 0.50 + ) + self.assertEqual(result[3], TYPE_NUM) + + def test_merge(self): + self.style.color = "#FF0000" + self.style.color_inherit = False + style_props = self.style_obj.merge([self.style]) + self.assertEqual(style_props, {"color": "#FF0000"}) + style_dict = {"color": "#00FF00", "dp": 0} + style_props = self.style_obj.merge([self.style, style_dict]) + self.assertEqual(style_props, {"color": "#00FF00", "dp": 0}) + style2 = self.style_obj.create( + dict( + name="teststyle2", + dp_inherit=False, + dp=1, + # color_inherit=True: will not be applied + color="#0000FF", + ) + ) + style_props = self.style_obj.merge([self.style, style_dict, style2]) + self.assertEqual(style_props, {"color": "#00FF00", "dp": 1}) + + def test_css(self): + self.style.color_inherit = False + self.style.color = "#FF0000" + self.style.background_color_inherit = False + self.style.background_color = "#0000FF" + self.style.suffix_inherit = False + self.style.suffix = "s" + self.style.prefix_inherit = False + self.style.prefix = "p" + self.style.font_style_inherit = False + self.style.font_style = "italic" + self.style.font_weight_inherit = False + self.style.font_weight = "bold" + self.style.font_size_inherit = False + self.style.font_size = "small" + self.style.indent_level_inherit = False + self.style.indent_level = 2 + style_props = self.style_obj.merge([self.style]) + css = self.style_obj.to_css_style(style_props) + self.assertEqual( + css, + "font-style: italic; " + "font-weight: bold; " + "font-size: small; " + "color: #FF0000; " + "background-color: #0000FF; " + "text-indent: 2em", + ) + css = self.style_obj.to_css_style(style_props, no_indent=True) + self.assertEqual( + css, + "font-style: italic; " + "font-weight: bold; " + "font-size: small; " + "color: #FF0000; " + "background-color: #0000FF", + ) + + def test_xslx(self): + self.style.color_inherit = False + self.style.color = "#FF0000" + self.style.background_color_inherit = False + self.style.background_color = "#0000FF" + self.style.suffix_inherit = False + self.style.suffix = "s" + self.style.prefix_inherit = False + self.style.prefix = "p" + self.style.dp_inherit = False + self.style.dp = 2 + self.style.font_style_inherit = False + self.style.font_style = "italic" + self.style.font_weight_inherit = False + self.style.font_weight = "bold" + self.style.font_size_inherit = False + self.style.font_size = "small" + self.style.indent_level_inherit = False + self.style.indent_level = 2 + style_props = self.style_obj.merge([self.style]) + xlsx = self.style_obj.to_xlsx_style(TYPE_NUM, style_props) + self.assertEqual( + xlsx, + { + "italic": True, + "bold": True, + "size": 9, + "font_color": u"#FF0000", + "bg_color": u"#0000FF", + "num_format": u'"p "#,##0.00" s"', + "indent": 2, + }, + ) + xlsx = self.style_obj.to_xlsx_style(TYPE_NUM, style_props, no_indent=True) + self.assertEqual( + xlsx, + { + "italic": True, + "bold": True, + "size": 9, + "font_color": u"#FF0000", + "bg_color": u"#0000FF", + "num_format": u'"p "#,##0.00" s"', + }, + ) + # percent type ignore prefix and suffix + xlsx = self.style_obj.to_xlsx_style(TYPE_PCT, style_props, no_indent=True) + self.assertEqual( + xlsx, + { + "italic": True, + "bold": True, + "size": 9, + "font_color": u"#FF0000", + "bg_color": u"#0000FF", + "num_format": u"0.00%", + }, + ) + + # str type have no num_format style + xlsx = self.style_obj.to_xlsx_style(TYPE_STR, style_props, no_indent=True) + self.assertEqual( + xlsx, + { + "italic": True, + "bold": True, + "size": 9, + "font_color": u"#FF0000", + "bg_color": u"#0000FF", + }, + ) diff --git a/odex25_accounting/mis_builder/tests/test_simple_array.py b/odex25_accounting/mis_builder/tests/test_simple_array.py new file mode 100644 index 000000000..36d8e131b --- /dev/null +++ b/odex25_accounting/mis_builder/tests/test_simple_array.py @@ -0,0 +1,7 @@ +# Copyright 2014 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from ..models import simple_array +from .common import load_doctests + +load_tests = load_doctests(simple_array) diff --git a/odex25_accounting/mis_builder/tests/test_subreport.py b/odex25_accounting/mis_builder/tests/test_subreport.py new file mode 100644 index 000000000..5f24bf520 --- /dev/null +++ b/odex25_accounting/mis_builder/tests/test_subreport.py @@ -0,0 +1,96 @@ +# Copyright 2020 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo.tests.common import SavepointCase + +from odoo.addons.mis_builder.models.expression_evaluator import ExpressionEvaluator +from odoo.addons.mis_builder.models.mis_report_subreport import ( + InvalidNameError, + ParentLoopError, +) + + +class TestMisSubreport(SavepointCase): + @classmethod + def setUpClass(cls): + super(TestMisSubreport, cls).setUpClass() + # create report + cls.subreport = cls.env["mis.report"].create(dict(name="test subreport")) + cls.subreport_kpi1 = cls.env["mis.report.kpi"].create( + dict( + report_id=cls.subreport.id, + name="sk1", + description="subreport kpi 1", + expression="11", + ) + ) + cls.report = cls.env["mis.report"].create( + dict( + name="test report", + subreport_ids=[ + (0, 0, dict(name="subreport", subreport_id=cls.subreport.id)) + ], + ) + ) + cls.report_kpi1 = cls.env["mis.report.kpi"].create( + dict( + report_id=cls.report.id, + name="k1", + description="report kpi 1", + expression="subreport.sk1 + 1", + ) + ) + cls.parent_report = cls.env["mis.report"].create( + dict( + name="parent report", + subreport_ids=[(0, 0, dict(name="report", subreport_id=cls.report.id))], + ) + ) + cls.parent_report_kpi1 = cls.env["mis.report.kpi"].create( + dict( + report_id=cls.parent_report.id, + name="pk1", + description="parent report kpi 1", + expression="report.k1 + 1", + ) + ) + + def test_basic(self): + ee = ExpressionEvaluator(aep=None, date_from="2017-01-01", date_to="2017-01-16") + d = self.report._evaluate(ee) + assert d["k1"] == 12 + + def test_two_levels(self): + ee = ExpressionEvaluator(aep=None, date_from="2017-01-01", date_to="2017-01-16") + d = self.parent_report._evaluate(ee) + assert d["pk1"] == 13 + + def test_detect_loop(self): + with self.assertRaises(ParentLoopError): + self.report.write( + dict( + subreport_ids=[ + ( + 0, + 0, + dict(name="preport1", subreport_id=self.parent_report.id), + ) + ] + ) + ) + with self.assertRaises(ParentLoopError): + self.report.write( + dict( + subreport_ids=[ + ( + 0, + 0, + dict(name="preport2", subreport_id=self.report.id), + ) + ] + ) + ) + + def test_invalid_name(self): + with self.assertRaises(InvalidNameError): + self.report.subreport_ids[0].name = "ab c" diff --git a/odex25_accounting/mis_builder/tests/test_utc_midnight.py b/odex25_accounting/mis_builder/tests/test_utc_midnight.py new file mode 100644 index 000000000..344af9406 --- /dev/null +++ b/odex25_accounting/mis_builder/tests/test_utc_midnight.py @@ -0,0 +1,19 @@ +# Copyright 2014 ACSONE SA/NV () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import odoo.tests.common as common + +from ..models.mis_report import _utc_midnight + + +class TestUtcMidnight(common.TransactionCase): + def test_utc_midnight(self): + date_to_convert = "2014-07-05" + date_time_convert = _utc_midnight(date_to_convert, "Europe/Brussels") + self.assertEqual(date_time_convert, "2014-07-04 22:00:00") + date_time_convert = _utc_midnight(date_to_convert, "Europe/Brussels", add_day=1) + self.assertEqual(date_time_convert, "2014-07-05 22:00:00") + date_time_convert = _utc_midnight(date_to_convert, "US/Pacific") + self.assertEqual(date_time_convert, "2014-07-05 07:00:00") + date_time_convert = _utc_midnight(date_to_convert, "US/Pacific", add_day=1) + self.assertEqual(date_time_convert, "2014-07-06 07:00:00") diff --git a/odex25_accounting/mis_builder/views/mis_report.xml b/odex25_accounting/mis_builder/views/mis_report.xml new file mode 100644 index 000000000..466f006ed --- /dev/null +++ b/odex25_accounting/mis_builder/views/mis_report.xml @@ -0,0 +1,321 @@ + + + + mis.report.view.tree + mis.report + + + + + + + + + mis.report.view.form + mis.report + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + + mis.report.view.kpi.form + mis.report.kpi + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    + Expressions can be any valid python expressions. +

    +

    + The following special elements are recognized in + the expressions to compute accounting data: + + {bal|crd|deb|pbal|nbal}{pieu}[account + selector][journal items domain] + + . +

    +
      +
    • + bal, crd, deb, pbal, nbal + : balance, debit, credit, positive balance, + negative balance. +
    • +
    • + p, i, e + : respectively variation over the period, + initial balance, ending balance +
    • +
    • + The + account selector + is a like expression on the account code (eg + 70%, etc). +
    • +
    • + The + journal items domain + is an Odoo domain filter on journal items. +
    • +
    • + balu[] + : (u for unallocated) is a special + expression that shows the unallocated + profit/loss of previous + fiscal years. +
    • +
    +

    + Expressions can involve other KPI, sub KPI and + query results by name (eg kpi1 + kpi2, + kpi2.subkpi1, query1.field1). +

    +

    + Additionally following variables are available + in the evaluation context: +

    +
      +
    • + sum, min, max, len, avg + : behave as expected, very similar to the + python builtins. +
    • +
    • + datetime, datetime, dateutil + : the python modules. +
    • +
    • + date_from, date_to + : beginning and end date of the period. +
    • +
    • + AccountingNone + : a null value that behaves as 0 in + arithmetic operations. +
    • +
    +
    +
    + +
    +

    Examples:

    +
      +
    • + bal[70] + : variation of the balance of account 70 + over the period (it is the same as balp[70]. +
    • +
    • + bali[70,60] + : initial balance of accounts 70 and 60. +
    • +
    • + bale[1%%] + : balance of accounts starting with 1 at end + of period. +
    • +
    • + crdp[40%] + : sum of all credits on accounts starting + with 40 during the period. +
    • +
    • + + debp[55%][('journal_id.code', '=', + 'BNK1')] + + : sum of all debits on accounts 55 and + journal BNK1 during the period. +
    • +
    • + + balp[('user_type_id', '=', + ref('account. + data_account_type_receivable').id)][] + + : variation of the balance of all receivable + accounts over the period. +
    • +
    • + + balp[][('tax_line_id.tag_ids', '=', + ref('l10n_be.tax_tag_56').id)] + + : balance of move lines related to tax grid + 56. +
    • +
    • + pbale[55%] + : sum of all ending balances of accounts + starting with 55 whose + ending balance is positive. +
    • +
    +
    +
    +
    +
    +
    +
    +
    +
    + + MIS Report Templates + + mis.report + tree,form + + + +
    diff --git a/odex25_accounting/mis_builder/views/mis_report_instance.xml b/odex25_accounting/mis_builder/views/mis_report_instance.xml new file mode 100644 index 000000000..d180c0619 --- /dev/null +++ b/odex25_accounting/mis_builder/views/mis_report_instance.xml @@ -0,0 +1,408 @@ + + + + + + + + diff --git a/odex25_accounting/odex25_account_accountant/views/product_views.xml b/odex25_accounting/odex25_account_accountant/views/product_views.xml new file mode 100644 index 000000000..32068535c --- /dev/null +++ b/odex25_accounting/odex25_account_accountant/views/product_views.xml @@ -0,0 +1,31 @@ + + + + res.partner.form + res.partner + + + + account.group_account_manager + + + Accounting + + + Accounting + + + + + + product.template.form.inherit + product.template + 5 + + + + account.group_account_invoice,account.group_account_readonly + + + + diff --git a/odex25_accounting/odex25_account_accountant/views/res_config_settings_views.xml b/odex25_accounting/odex25_account_accountant/views/res_config_settings_views.xml new file mode 100644 index 000000000..e4dc27267 --- /dev/null +++ b/odex25_accounting/odex25_account_accountant/views/res_config_settings_views.xml @@ -0,0 +1,107 @@ + + + + res.config.settings.view.form.inherit.account.accountant + res.config.settings + + +
    + Accounting + Accounting +
    +
    +
    +
    +
    +
    + Fiscal Year +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + 0 +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    + Inter-Banks Transfers +
    + Account used when transferring between banks +
    +
    +
    +
    +
    +
    +
    + + + + diff --git a/odex25_accounting/odex25_account_accountant/wizard/__init__.py b/odex25_accounting/odex25_account_accountant/wizard/__init__.py new file mode 100644 index 000000000..33eb68558 --- /dev/null +++ b/odex25_accounting/odex25_account_accountant/wizard/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + + +from . import account_change_lock_date diff --git a/odex25_accounting/odex25_account_accountant/wizard/account_change_lock_date.py b/odex25_accounting/odex25_account_accountant/wizard/account_change_lock_date.py new file mode 100644 index 000000000..7c3c0b3dc --- /dev/null +++ b/odex25_accounting/odex25_account_accountant/wizard/account_change_lock_date.py @@ -0,0 +1,35 @@ +from odoo import models, fields, _ +from odoo.exceptions import UserError + + +class AccountChangeLockDate(models.TransientModel): + """ + This wizard is used to change the lock date + """ + _name = 'account.change.lock.date' + _description = 'Change Lock Date' + + period_lock_date = fields.Date( + string='Lock Date for Non-Advisers', + default=lambda self: self.env.company.period_lock_date, + help='Only users with the Adviser role can edit accounts prior to and inclusive of this date. Use it for period locking inside an open fiscal year, for example.') + fiscalyear_lock_date = fields.Date( + string='Lock Date for All Users', + default=lambda self: self.env.company.fiscalyear_lock_date, + help='No users, including Advisers, can edit accounts prior to and inclusive of this date. Use it for fiscal year locking for example.') + tax_lock_date = fields.Date( + "Tax Lock Date", + default=lambda self: self.env.company.tax_lock_date, + help='No users can edit journal entries related to a tax prior and inclusive of this date.') + + + def change_lock_date(self): + if self.user_has_groups('account.group_account_manager'): + self.env.company.sudo().write({ + 'period_lock_date': self.period_lock_date, + 'fiscalyear_lock_date': self.fiscalyear_lock_date, + 'tax_lock_date': self.tax_lock_date, + }) + else: + raise UserError(_('Only Billing Administrators are allowed to change lock dates!')) + return {'type': 'ir.actions.act_window_close'} diff --git a/odex25_accounting/odex25_account_accountant/wizard/account_change_lock_date.xml b/odex25_accounting/odex25_account_accountant/wizard/account_change_lock_date.xml new file mode 100644 index 000000000..de68fd492 --- /dev/null +++ b/odex25_accounting/odex25_account_accountant/wizard/account_change_lock_date.xml @@ -0,0 +1,41 @@ + + + + + + account.change.lock.date.form + account.change.lock.date + +
    + + + + + + + +
    +
    +
    +
    +
    + + + Lock your Fiscal Period + account.change.lock.date + form + + new + + + +
    +
    diff --git a/odex25_accounting/odex25_account_accountant/wizard/reconcile_model_wizard.xml b/odex25_accounting/odex25_account_accountant/wizard/reconcile_model_wizard.xml new file mode 100644 index 000000000..3305d7f46 --- /dev/null +++ b/odex25_accounting/odex25_account_accountant/wizard/reconcile_model_wizard.xml @@ -0,0 +1,44 @@ + + + + + account.reconcile.model.form + account.reconcile.model + +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/odex25_accounting/odex25_account_asset/__init__.py b/odex25_accounting/odex25_account_asset/__init__.py new file mode 100644 index 000000000..024844063 --- /dev/null +++ b/odex25_accounting/odex25_account_asset/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + + +from . import models +from . import wizard +from . import report diff --git a/odex25_accounting/odex25_account_asset/__manifest__.py b/odex25_accounting/odex25_account_asset/__manifest__.py new file mode 100644 index 000000000..7f5238ef1 --- /dev/null +++ b/odex25_accounting/odex25_account_asset/__manifest__.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- + + +{ + 'name': 'Assets Management', + 'description': """ +Assets management +================= +Manage assets owned by a company or a person. +Keeps track of depreciations, and creates corresponding journal entries. + + """, + 'category': 'Odex25-Accounting/Odex25-Accounting', + 'author': 'Expert Co. Ltd.', + 'website': 'http://www.exp-sa.com', + 'sequence': 32, + 'depends': ['odex25_account_reports', ], + 'data': [ + 'security/account_asset_security.xml', + 'security/ir.model.access.csv', + 'wizard/asset_modify_views.xml', + 'wizard/asset_pause_views.xml', + 'wizard/asset_sell_views.xml', + 'views/account_account_views.xml', + 'views/account_asset_views.xml', + 'views/account_deferred_revenue.xml', + 'views/account_deferred_expense.xml', + 'views/account_move_views.xml', + 'views/account_asset_templates.xml', + 'report/account_assets_report_views.xml', + ], + 'demo': [ + 'demo/account_deferred_revenue_demo.xml', + ], + 'qweb': [ + "static/src/xml/account_asset_template.xml", + ], + # 'auto_install': True, +} diff --git a/odex25_accounting/odex25_account_asset/demo/account_deferred_revenue_demo.xml b/odex25_accounting/odex25_account_asset/demo/account_deferred_revenue_demo.xml new file mode 100644 index 000000000..3c92b02be --- /dev/null +++ b/odex25_accounting/odex25_account_asset/demo/account_deferred_revenue_demo.xml @@ -0,0 +1,24 @@ + + + + + + + + Revenue Recognition Maintenance Contract - 1 Years + 12 + 1 + + + + sale + model + + + diff --git a/odex25_accounting/odex25_account_asset/i18n/ar.po b/odex25_accounting/odex25_account_asset/i18n/ar.po new file mode 100644 index 000000000..922dd8b19 --- /dev/null +++ b/odex25_accounting/odex25_account_asset/i18n/ar.po @@ -0,0 +1,2114 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * odex25_account_asset +# +# Translators: +# Sherif Abd Ekmoniem , 2020 +# Eng.Walid Ramadan , 2020 +# Osama Ahmaro , 2020 +# Mustafa Rawi , 2020 +# Sadig Adam , 2020 +# amrnegm , 2020 +# Martin Trigaux, 2020 +# hoxhe Aits , 2020 +# Osoul , 2020 +# Ghaith Gammar , 2020 +# Ali Alrehawi , 2020 +# amal ahmed , 2020 +# Zuhair Hammadi , 2020 +# Shaima Safar , 2020 +# Islam Eldeeb , 2020 +# Mostafa Hanafy , 2020 +# Nisrine Tagri , 2020 +# Tasneem Sarhan , 2020 +# MOHAMMAD IBRAHIM , 2020 +# Talal Albahra , 2020 +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-11-27 13:47+0000\n" +"PO-Revision-Date: 2020-09-07 08:17+0000\n" +"Last-Translator: Talal Albahra , 2020\n" +"Language-Team: Arabic (https://www.transifex.com/odoo/teams/41243/ar/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: ar\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid " (copy)" +msgstr " (نسخة)" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__total_depreciation_entries_count +msgid "# Depreciation Entries" +msgstr " قيود الإهلاك" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__gross_increase_count +msgid "# Gross Increases" +msgstr "الزيادات الإجمالية" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__depreciation_entries_count +msgid "# Posted Depreciation Entries" +msgstr "قيود الإهلاك المُرحلة" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "%s created from invoice" +msgstr "تم انشاؤها من الفاتورة %s" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "(prorata entry)" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "A deferred expense has been created for this move:" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "A deferred revenue has been created for this move:" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "A document linked to %s has been deleted: " +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/wizard/asset_modify.py:0 +#, python-format +msgid "A gross increase has been created" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model,name:odex25_account_asset.model_account_account +msgid "Account" +msgstr "حساب" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__account_asset_counterpart_id +msgid "Account Asset Counterpart" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model,name:odex25_account_asset.model_account_assets_report +msgid "Account Assets Report" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__account_depreciation_id +msgid "Account Depreciation" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__account_depreciation_expense_id +msgid "Account Depreciation Expense" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__user_type_id +msgid "" +"Account Type is used for information purpose, to generate country-specific " +"legal reports, and set the rules to close a fiscal year and generate opening" +" entries." +msgstr "" +"يستخدم نوع الحساب في استخراج التقارير وفقاً للتقارير القانونية المطلوبة في " +"كل دولة، وتضع القواعد اللازمة في إقفال سنة مالية وإنشاء القيد الافتتاحي " +"للسنة المالية اللاحقة." + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__account_depreciation_id +msgid "Account used in the depreciation entries, to decrease the asset value." +msgstr "الحساب المستخدم لقيود إهلاكات الأصل، لتخفيض القيمة الدفترية للأصل." + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__account_depreciation_expense_id +msgid "" +"Account used in the periodical entries, to record a part of the asset as " +"expense." +msgstr "الحساب المستخدم للقيود الدورية لتسجيل قيد مصروف الإهلاك." + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Account used to recognize the expense" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Account used to recognize the revenue" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Account used to record the deferred expense" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Account used to record the deferred income" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__account_asset_id +msgid "" +"Account used to record the purchase of the asset at its original price." +msgstr "الحساب المستخدم لتسجيل قيد شراء الأصل بسعره الأصلي." + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset_sell__gain_account_id +msgid "Account used to write the journal item in case of gain" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_res_company__gain_account_id +msgid "" +"Account used to write the journal item in case of gain while selling an " +"asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset_sell__loss_account_id +msgid "Account used to write the journal item in case of loss" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_res_company__loss_account_id +msgid "" +"Account used to write the journal item in case of loss while selling an " +"asset" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Accounting" +msgstr "الحسابات" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__acquisition_date +#, python-format +msgid "Acquisition Date" +msgstr "تاريخ الاستحواذ" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__action +msgid "Action" +msgstr "إجراء" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_needaction +msgid "Action Needed" +msgstr "إجراء مطلوب" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__active +msgid "Active" +msgstr "نشط" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__activity_ids +msgid "Activities" +msgstr "الأنشطة" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__activity_exception_decoration +msgid "Activity Exception Decoration" +msgstr "زخرفة استثناء النشاط" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__activity_state +msgid "Activity State" +msgstr "حالة النشاط" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__activity_type_icon +msgid "Activity Type Icon" +msgstr "أيقونة نوع النشاط" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "All the lines should be from the same account" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "All the lines should be from the same move type" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "All the lines should be posted" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__already_depreciated_amount_import +msgid "Already Depreciated Amount Import" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__parent_id +msgid "An asset has a parent when it is the result of gaining value" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "An asset has been created for this move:" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__account_analytic_id +msgid "Analytic Account" +msgstr "الحساب التحليلي" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__analytic_tag_ids +msgid "Analytic Tag" +msgstr "الوسم التحليلي" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_revenue_model_search +msgid "Archived" +msgstr "مؤرشف" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#: code:addons/odex25_account_asset/models/account_move.py:0 +#: code:addons/odex25_account_asset/models/account_move.py:0 +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_pause__asset_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__asset_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__asset_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__asset_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__asset_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__asset_id +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_account__asset_type__purchase +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +#, python-format +msgid "Asset" +msgstr "الأصل" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +msgid "Asset Account" +msgstr "حساب الأصل" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__account_asset_id +msgid "Asset Gross Increase Account" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__asset_id_display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__asset_id_display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__asset_id_display_name +msgid "Asset Id Display Name" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__asset_ids_display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__asset_ids_display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__asset_ids_display_name +msgid "Asset Ids Display Name" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move_line__asset_ids +msgid "Asset Linked" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__asset_manually_modified +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__asset_manually_modified +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__asset_manually_modified +msgid "Asset Manually Modified" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_account__asset_model +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_expense_model_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_form_asset_inherit +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_revenue_model_search +msgid "Asset Model" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Asset Model name" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.actions.act_window,name:odex25_account_asset.action_account_asset_model_form +#: model:ir.ui.menu,name:odex25_account_asset.menu_action_account_asset_model_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_purchase_tree +msgid "Asset Models" +msgstr "نموذج الأصل" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__name +msgid "Asset Name" +msgstr "اسم الأصل" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_form_asset_inherit +msgid "Asset Options" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_account__asset_type +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__asset_type +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__asset_asset_type +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__asset_asset_type +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__asset_asset_type +msgid "Asset Type" +msgstr "نوع الأصل" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__asset_value_change +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__asset_value_change +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__asset_value_change +msgid "Asset Value Change" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Asset Values" +msgstr "قيم الأصول" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Asset created" +msgstr "تم إنشاء الأصل" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_move_line__asset_ids +msgid "Asset created from this Journal Item" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Asset paused" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Asset sold or disposed. Accounting entry awaiting for validation." +msgstr "تم بيع أو تخريد الأصل، القيود المحاسبية في انتظار المراجعة والترحيل." + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/wizard/asset_modify.py:0 +#, python-format +msgid "Asset unpaused" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Asset(s)" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model,name:odex25_account_asset.model_account_asset +msgid "Asset/Revenue Recognition" +msgstr "إثبات الأصل/الربح" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#: model:ir.actions.act_window,name:odex25_account_asset.action_account_asset_form +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__asset_ids +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__asset_ids +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__asset_ids +#: model:ir.ui.menu,name:odex25_account_asset.menu_action_account_asset_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_purchase_tree +#, python-format +msgid "Assets" +msgstr "الأصول" + +#. module: odex25_account_asset +#: model:ir.ui.menu,name:odex25_account_asset.menu_finance_config_assets +msgid "Assets and Revenues" +msgstr "الأصول والإيرادات" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +msgid "Assets in closed state" +msgstr "الأصول المُقفلة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +msgid "Assets in draft and open states" +msgstr "الأصول المسودة والجارية" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_attachment_count +msgid "Attachment Count" +msgstr "عدد المرفقات" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_form_asset_inherit +msgid "Automate Asset" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_form_asset_inherit +msgid "Automate Deferred Expense" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_form_asset_inherit +msgid "Automate Deferred Revenue" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__book_value +#, python-format +msgid "Book Value" +msgstr "القيمة الدفترية" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_account__can_create_asset +msgid "Can Create Asset" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_modify_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_pause_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_sell_form +msgid "Cancel" +msgstr "الغاء" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Category of asset" +msgstr "فئة الأصل" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#, python-format +msgid "Characteristics" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__children_ids +msgid "Children" +msgstr "الفروع" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__method +msgid "" +"Choose the method to use to compute the amount of depreciation lines.\n" +" * Straight Line: Calculated on basis of: Gross Value / Number of Depreciations\n" +" * Declining: Calculated on basis of: Residual Value * Declining Factor\n" +" * Declining then Straight Line: Like Declining but with a minimum depreciation value equal to the straight line value." +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__state__close +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +msgid "Closed" +msgstr "مغلق" + +#. module: odex25_account_asset +#: model:ir.model,name:odex25_account_asset.model_res_company +msgid "Companies" +msgstr "شركات" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__company_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__company_id +msgid "Company" +msgstr "شركة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Compute Depreciation" +msgstr "احتساب الإهلاك" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Compute Expense" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Compute Revenue" +msgstr "حساب الأرباح" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Confirm" +msgstr "تأكيد" + +#. module: odex25_account_asset +#: model:ir.actions.server,name:odex25_account_asset.action_account_aml_to_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_account__create_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_move_line_tree +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_move_line_tree_grouped_inherit +msgid "Create Asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_account__create_asset__validate +msgid "Create and validate" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_account__create_asset__draft +msgid "Create in draft" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__create_uid +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_pause__create_uid +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__create_uid +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__create_uid +msgid "Created by" +msgstr "أنشئ بواسطة" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__create_date +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_pause__create_date +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__create_date +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__create_date +msgid "Created on" +msgstr "أنشئ في" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__asset_depreciated_value +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__asset_depreciated_value +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__asset_depreciated_value +msgid "Cumulative Depreciation" +msgstr "مجمع الإهلاك" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Cumulative Expense" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Cumulative Revenue" +msgstr "الأرباح التراكمية" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__currency_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__currency_id +msgid "Currency" +msgstr "العملة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +msgid "Current" +msgstr "الجاري" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Current Values" +msgstr "القيم الحالية" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__invoice_id +msgid "Customer Invoice" +msgstr "فاتورة العميل" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__date +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +msgid "Date" +msgstr "التاريخ" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#, python-format +msgid "Dec. then Straight" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__method__degressive +#, python-format +msgid "Declining" +msgstr "انخفاض" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__method_progress_factor +msgid "Declining Factor" +msgstr "عامل الانخفاض" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__method__degressive_then_linear +msgid "Declining then Straight Line" +msgstr "الانخفاض ثم الخط المستقيم" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_account__asset_type__expense +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__asset_type__expense +#, python-format +msgid "Deferred Expense" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_expense_tree +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_expense_model_search +msgid "Deferred Expense Account" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Deferred Expense Amount" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_form_asset_inherit +msgid "Deferred Expense Model" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Deferred Expense Model name" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.actions.act_window,name:odex25_account_asset.action_account_expense_model_form +#: model:ir.ui.menu,name:odex25_account_asset.menu_action_account_expense_model_recognition +msgid "Deferred Expense Models" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_form_asset_inherit +msgid "Deferred Expense Options" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Deferred Expense name" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Deferred Expense(s)" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#: model:ir.actions.act_window,name:odex25_account_asset.action_account_expense_form +#: model:ir.ui.menu,name:odex25_account_asset.menu_action_account_expense_recognition +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_tree +#, python-format +msgid "Deferred Expenses" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_expense_tree +msgid "Deferred Expenses Models" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_account__asset_type__sale +#, python-format +msgid "Deferred Revenue" +msgstr "الأرباح المُرحلة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_sale_tree +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_revenue_model_search +msgid "Deferred Revenue Account" +msgstr "حساب الإيرادات المُرحلة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Deferred Revenue Amount" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_form_asset_inherit +msgid "Deferred Revenue Model" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Deferred Revenue Model name" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.actions.act_window,name:odex25_account_asset.action_account_revenue_model_form +#: model:ir.ui.menu,name:odex25_account_asset.menu_action_account_revenue_model_recognition +msgid "Deferred Revenue Models" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_form_asset_inherit +msgid "Deferred Revenue Options" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Deferred Revenue name" +msgstr "اسم الأرباح المُرحلة" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Deferred Revenue(s)" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#: model:ir.actions.act_window,name:odex25_account_asset.action_account_revenue_form +#: model:ir.ui.menu,name:odex25_account_asset.menu_action_account_revenue_recognition +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_sale_tree +#, python-format +msgid "Deferred Revenues" +msgstr "إيرادات مدفوعة مقدمًا" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_sale_tree +msgid "Deferred Revenues Models" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Deferred expense" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Deferred expense created" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Deferred revenue" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Deferred revenue created" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__value_residual +msgid "Depreciable Amount" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__value_residual +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__asset_remaining_value +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__asset_remaining_value +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__asset_remaining_value +msgid "Depreciable Value" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Depreciated Amount" +msgstr "المبلغ المستهلك" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +#, python-format +msgid "Depreciation" +msgstr "إهلاك" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__account_depreciation_id +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_search +msgid "Depreciation Account" +msgstr "حساب الإهلاك" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Depreciation Board" +msgstr "جدول الإهلاكات" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Depreciation Date" +msgstr "تاريخ الإهلاك" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__depreciation_move_ids +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Depreciation Lines" +msgstr "بنود الإهلاك" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Depreciation Method" +msgstr "طريقة الإهلاك" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__depreciation_number_import +msgid "Depreciation Number Import" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.actions.client,name:odex25_account_asset.action_account_report_assets +#: model:ir.ui.menu,name:odex25_account_asset.menu_action_account_report_assets +msgid "Depreciation Schedule" +msgstr "جدول الإهلاك" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#, python-format +msgid "Depreciation Table Report" +msgstr "تقرير جدول الإهلاك" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/wizard/asset_modify.py:0 +#, python-format +msgid "Depreciation board modified" +msgstr "تم تعديل جدول الإهلاكات" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Depreciation entry %s posted (%s)" +msgstr "بند الإهلاك %s تم ترحيله (%s)" + + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Depreciation entry %s reversed (%s)" +msgstr "قيد الإهلاك %s تم عكسه (%s)" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__display_account_asset_id +msgid "Display Account Asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__display_model_choice +msgid "Display Model Choice" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_account__display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_pause__display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_assets_report__display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move_line__display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_res_company__display_name +msgid "Display Name" +msgstr "الاسم المعروض" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Disposal" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__disposal_date +msgid "Disposal Date" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Disposal Move" +msgstr "حركة التخريد" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Disposal Moves" +msgstr "حركات التخريد" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset_sell__action__dispose +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_sell_form +msgid "Dispose" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__state__draft +msgid "Draft" +msgstr "مسودة" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__draft_asset_ids +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__draft_asset_ids +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__draft_asset_ids +msgid "Draft Asset" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Duration" +msgstr "المدة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Existing Depreciation Schedule" +msgstr "جدول الإهلاك الحالي" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Existing Depreciations" +msgstr "الإهلاكات الحالية" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_tree +#, python-format +msgid "Expense" +msgstr "المصروف" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__account_depreciation_expense_id +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_expense_tree +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_expense_model_search +msgid "Expense Account" +msgstr "حساب المصروفات" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Expense Board" +msgstr "لوحة المصروفات" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Expense Date" +msgstr "تاريخ المصروف" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Expense Lines" +msgstr "بنود المصروف" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_expense_tree +msgid "Expense Name" +msgstr "إسم المصروف" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Expense Recognition" +msgstr "الاعتراف بالمصروفات" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#, python-format +msgid "First Depreciation" +msgstr "الإهلاك الأول" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__first_depreciation_date +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "First Depreciation Date" +msgstr "تاريخ أول إهلاك" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__first_depreciation_date_import +msgid "First Depreciation Date Import" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "First Recognition Date" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__account_asset_id +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_search +msgid "Fixed Asset Account" +msgstr "حساب الأصل" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_follower_ids +msgid "Followers" +msgstr "المتابعون" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_channel_ids +msgid "Followers (Channels)" +msgstr "المتابعون (القنوات)" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_partner_ids +msgid "Followers (Partners)" +msgstr "المتابعون (الشركاء)" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__activity_type_icon +msgid "Font awesome icon e.g. fa-tasks" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_account__form_view_ref +msgid "Form View Ref" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +msgid "Future Activities" +msgstr "الأنشطة المستقبلية" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset_sell__gain_or_loss__gain +msgid "Gain" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__gain_account_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_res_company__gain_account_id +msgid "Gain Account" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__gain_or_loss +msgid "Gain Or Loss" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__gain_value +msgid "Gain Value" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +#, python-format +msgid "Gross Increase" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__gross_increase_value +msgid "Gross Increase Value" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_expense_model_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_revenue_model_search +msgid "Group By..." +msgstr "تجميع حسب.." + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_account__id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_pause__id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_assets_report__id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move_line__id +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__id +#: model:ir.model.fields,field_description:odex25_account_asset.field_res_company__id +msgid "ID" +msgstr "المُعرف" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__activity_exception_icon +msgid "Icon" +msgstr "الأيقونة" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__activity_exception_icon +msgid "Icon to indicate an exception activity." +msgstr "الأيقونة للإشارة إلى استثناء النشاط" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__message_needaction +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__message_unread +msgid "If checked, new messages require your attention." +msgstr "إذا كان محددًا، فهناك رسائل جديدة تحتاج لرؤيتها." + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__message_has_error +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__message_has_sms_error +msgid "If checked, some messages have a delivery error." +msgstr "إذا كان محددًا، فقد حدث خطأ في تسليم بعض الرسائل." + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_account__asset_model +msgid "" +"If this is selected, an expense/revenue will be created automatically when " +"Journal Items on this account are posted." +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__first_depreciation_date_import +msgid "" +"In case of an import from another software, provide the first depreciation " +"date in it." +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__depreciation_number_import +msgid "" +"In case of an import from another software, provide the number of " +"depreciations already done before starting with Odoo." +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__already_depreciated_amount_import +msgid "" +"In case of an import from another software, you might need to use this field" +" to have the right depreciation table report. This is the value that was " +"already depreciated with entries not computed from this model" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#, python-format +msgid "" +"In percent.
    For a linear method, the depreciation rate is computed per " +"year.
    For a declining method, it is the declining factor" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_modify_form +msgid "Increase Accounts" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__prorata +msgid "" +"Indicates that the first depreciation entry for this asset have to be done " +"from the asset date (purchase date) instead of the first January / Start " +"date of fiscal year" +msgstr "" +"يشير إلى احتساب بداية الإهلاكات من تاريخ بداية الأصل (تاريخ الشراء) بدلاً عن" +" الأول من يناير / أو تاريخ بداية السنة المالية." + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__invoice_line_id +msgid "Invoice Line" +msgstr "بند الفاتورة" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_is_follower +msgid "Is Follower" +msgstr "متابع" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__salvage_value +msgid "It is the amount you plan to have that you cannot depreciate." +msgstr "" +"هذا هو المبلغ المتبقي ولا يمكن إهلاكه عند الوصول إلى تاريخ انتهاء الأصل." + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__journal_id +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_expense_model_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_revenue_model_search +msgid "Journal" +msgstr "دفتر اليومية" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Journal Entries" +msgstr "القيود اليومية" + +#. module: odex25_account_asset +#: model:ir.model,name:odex25_account_asset.model_account_move +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Journal Entry" +msgstr "قيد اليومية" + +#. module: odex25_account_asset +#: model:ir.model,name:odex25_account_asset.model_account_move_line +msgid "Journal Item" +msgstr "عنصر اليومية" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__original_move_line_ids +#, python-format +msgid "Journal Items" +msgstr "عناصر اليومية" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "" +"Journal Items of {account} should have a label in order to generate an asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_account____last_update +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset____last_update +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_pause____last_update +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell____last_update +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_assets_report____last_update +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move____last_update +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move_line____last_update +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify____last_update +#: model:ir.model.fields,field_description:odex25_account_asset.field_res_company____last_update +msgid "Last Modified on" +msgstr "آخر تعديل في" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__write_uid +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_pause__write_uid +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__write_uid +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__write_uid +msgid "Last Updated by" +msgstr "آخر تحديث بواسطة" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__write_date +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_pause__write_date +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__write_date +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__write_date +msgid "Last Updated on" +msgstr "آخر تحديث في" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +msgid "Late Activities" +msgstr "الأنشطة المتأخرة" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#, python-format +msgid "Linear" +msgstr "قسط ثابت" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset_sell__gain_or_loss__loss +msgid "Loss" +msgstr "خسارة" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__loss_account_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_res_company__loss_account_id +msgid "Loss Account" +msgstr "حساب الخسارة" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_main_attachment_id +msgid "Main Attachment" +msgstr "المرفق الرئيسي" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_form_asset_inherit +msgid "Manage Items" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_has_error +msgid "Message Delivery error" +msgstr "خطأ في تسليم الرسائل" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_ids +msgid "Messages" +msgstr "الرسائل" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__method +#, python-format +msgid "Method" +msgstr "طريقة" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__model_id +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__state__model +msgid "Model" +msgstr "الكائن" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_modify_form +msgid "Modification" +msgstr "تعديل" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_modify_form +msgid "Modification reason" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_modify_form +msgid "Modify" +msgstr "تعديل" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#: model:ir.model,name:odex25_account_asset.model_asset_modify +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_modify_form +#, python-format +msgid "Modify Asset" +msgstr "تعديل الأصل" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Modify Depreciation" +msgstr "تعديل الإهلاكات" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Modify Expense" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Modify Revenue" +msgstr "تعديل الأرباح" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__method_period__1 +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__asset_modify__method_period__1 +msgid "Months" +msgstr "شهور" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_account__multiple_assets_per_line +msgid "Multiple Assets per Line" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_account__multiple_assets_per_line +msgid "" +"Multiple asset items will be generated depending on the bill line quantity " +"instead of 1 global asset." +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__need_date +msgid "Need Date" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_modify_form +msgid "New Values" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_asset_modify__value_residual +msgid "New residual amount for the asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_asset_modify__salvage_value +msgid "New salvage amount for the asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__activity_date_deadline +msgid "Next Activity Deadline" +msgstr "الموعد النهائي للنشاط التالي" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__activity_summary +msgid "Next Activity Summary" +msgstr "ملخص النشاط التالي" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__activity_type_id +msgid "Next Activity Type" +msgstr "نوع النشاط التالي" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Next Period Expense" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Next Period Revenue" +msgstr "أرباح الفترة القادمة" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_account__create_asset__no +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset_sell__gain_or_loss__no +msgid "No" +msgstr "لا" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#, python-format +msgid "No asset account" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__salvage_value +msgid "Not Depreciable Amount" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__salvage_value +msgid "Not Depreciable Value" +msgstr "القيمة الغير قابلة للاستهلاك" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__first_depreciation_date +msgid "" +"Note that this date does not alter the computation of the first journal " +"entry in case of prorata temporis assets. It simply changes its accounting " +"date" +msgstr "" +"لاحظ أن هذا التاريخ لا يغير من كيفية احتساب قيد المحاسبي الأول في حالة " +"الأصول التي تحتسب من تاريخ الشراء. كل ما يفعله هو تغيير تاريخ القيد." + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__number_asset_ids +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__number_asset_ids +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__number_asset_ids +msgid "Number Asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_needaction_counter +msgid "Number of Actions" +msgstr "عدد الإجراءات" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__method_number +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__method_number +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_purchase_tree +msgid "Number of Depreciations" +msgstr "عدد الإهلاكات" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__method_period +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__method_period +msgid "Number of Months in a Period" +msgstr "عدد الشهور في الفترة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_expense_tree +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_sale_tree +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Number of Recognitions" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__gross_increase_count +msgid "Number of assets made to increase the value of the asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__total_depreciation_entries_count +msgid "Number of depreciation entries (posted or not)" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_has_error_counter +msgid "Number of errors" +msgstr "عدد الاخطاء" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__message_needaction_counter +msgid "Number of messages which requires an action" +msgstr "عدد الرسائل التي تتطلب إجراء" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "عدد الرسائل الحادث بها خطأ في التسليم" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__message_unread_counter +msgid "Number of unread messages" +msgstr "عدد الرسائل الجديدة" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__state__paused +msgid "On Hold" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.line_caret_options +msgid "Open Asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__original_value +msgid "Original Value" +msgstr "القيمة الأصلية" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__parent_id +msgid "Parent" +msgstr "الأصل" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_pause_form +msgid "Pause" +msgstr "إيقاف" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#: model:ir.model,name:odex25_account_asset.model_account_asset_pause +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_pause_form +#, python-format +msgid "Pause Asset" +msgstr "إيقاف الأصل مؤقتاً" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Pause Depreciation" +msgstr "إيقاف الإهلاك مؤقتاً" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_pause__date +msgid "Pause date" +msgstr "تاريخ الإيقاف المؤقت" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_expense_tree +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_purchase_tree +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_sale_tree +msgid "Period length" +msgstr "طول المدة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Posted Entries" +msgstr "القيود المُرحّلة" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__prorata_date +msgid "Prorata Date" +msgstr "التاريخ النسبي" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__prorata +msgid "Prorata Temporis" +msgstr "التناسب الزمني" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__asset_type__purchase +msgid "Purchase: Asset" +msgstr "شراء: الأصل" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#, python-format +msgid "Rate" +msgstr "السعر" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__name +msgid "Reason" +msgstr "السبب" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Related Expenses" +msgstr "النفقات ذات الصلة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Related Purchase" +msgstr "المشتريات المرتبطة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Related Sales" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Report of reversal for {name}" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Reset to running" +msgstr "إعادة تعيين للتشغيل" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Residual Amount to Recognize" +msgstr "المبلغ المتبقي للتعرف عليه" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__activity_user_id +msgid "Responsible User" +msgstr "المستخدم المسؤول" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Resume Depreciation" +msgstr "استئناف الاستهلاك" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +#, python-format +msgid "Revenue" +msgstr "الربح" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_sale_tree +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_revenue_model_search +msgid "Revenue Account" +msgstr "حساب الإيرادات" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Revenue Board" +msgstr "جانب الارباح" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Revenue Date" +msgstr "تاريخ الأرباح" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Revenue Lines" +msgstr "بنود الأرباح" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_sale_tree +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_sale_tree +msgid "Revenue Name" +msgstr "اسم الأرباح" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Revenue Recognition" +msgstr "إثبات الإيرادات" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__reversal_move_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__reversal_move_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__reversal_move_id +msgid "Reversal Move" +msgstr "تحرك عكسي" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/wizard/asset_modify.py:0 +#, python-format +msgid "" +"Reverse the depreciation entries posted in the future in order to modify the" +" depreciation" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__state__open +msgid "Running" +msgstr "جاري" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_has_sms_error +msgid "SMS Delivery error" +msgstr "خطأ في تسليم الرسائل القصيرة" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Sale" +msgstr "المبيعات" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__asset_type__sale +msgid "Sale: Revenue Recognition" +msgstr "البيع: إثبات الإيراد" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Save Model" +msgstr "نموذج البيع" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Save model" +msgstr "Save model" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__select_invoice_line_id +msgid "Select Invoice Line" +msgstr "تحديد بند الفاتورة" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset_sell__action__sell +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_sell_form +msgid "Sell" +msgstr "بيع" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#: model:ir.model,name:odex25_account_asset.model_account_asset_sell +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_sell_form +#, python-format +msgid "Sell Asset" +msgstr "بيع الأصل" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Sell or Dispose" +msgstr "بيع أو تخريد" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Set manually the original values or" +msgstr "قم بتعيين القيم يدوياً أو" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Set to Draft" +msgstr "تعيين كمسودة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Set to Running" +msgstr "التعيين كجارٍ" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +msgid "Show all records which has next action date is before today" +msgstr "عرض كافة السجلات المُعين لها تاريخ إجراء تالي يسبق تاريخ اليوم الجاري" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Some fields are missing {}" +msgstr "بعض الحقول مفقودة {}" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Some required values are missing" +msgstr "Some required values are missing" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Start Depreciating" +msgstr "بدء الإهلاك" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__state +msgid "Status" +msgstr "الحالة" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__activity_state +msgid "" +"Status based on activities\n" +"Overdue: Due date is already passed\n" +"Today: Activity date is today\n" +"Planned: Future activities." +msgstr "" +"الحالة على أساس الأنشطة\n" +"المتأخرة: تاريخ الاستحقاق مر\n" +"اليوم: تاريخ النشاط هو اليوم\n" +"المخطط: الأنشطة المستقبلية." + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__method__linear +msgid "Straight Line" +msgstr "خط مستقيم" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__book_value +msgid "" +"Sum of the depreciable value, the salvage value and the book value of all " +"value increase items" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_account__can_create_asset +msgid "" +"Technical field specifying if the account can generate asset depending on " +"it's type. It is used in the account form view." +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_asset_modify__gain_value +msgid "" +"Technical field to know if we should display the fields for the creation of " +"gross increase asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset_sell__gain_or_loss +msgid "" +"Technical field to know is there was a gain or a loss in the selling of the " +"asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__method_period +#: model:ir.model.fields,help:odex25_account_asset.field_asset_modify__method_period +msgid "The amount of time between two depreciations" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_asset_modify__asset_id +msgid "The asset to be modified by this wizard" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__children_ids +msgid "The children are the gains in value of this asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset_sell__invoice_id +msgid "" +"The disposal invoice is needed in order to generate the closing journal " +"entry." +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__method_number +msgid "The number of depreciations needed to depreciate your asset" +msgstr "عدد أقساط الإهلاك المطلوبة حتى تخريد أو انتهاء عمر الأصل" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "The remaining value on the last depreciation line must be 0" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset_sell__invoice_line_id +msgid "There are multiple lines that could be the related to this asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_bank_statement_line__asset_value_change +#: model:ir.model.fields,help:odex25_account_asset.field_account_move__asset_value_change +#: model:ir.model.fields,help:odex25_account_asset.field_account_payment__asset_value_change +msgid "" +"This is a technical field set to true when this move is the result of the " +"changing of value of an asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_bank_statement_line__asset_manually_modified +#: model:ir.model.fields,help:odex25_account_asset.field_account_move__asset_manually_modified +#: model:ir.model.fields,help:odex25_account_asset.field_account_payment__asset_manually_modified +msgid "" +"This is a technical field stating that a depreciation line has been manually" +" modified. It is used to recompute the depreciation table of an " +"asset/deferred revenue." +msgstr "" + +#. module: odex25_account_asset +#. openerp-web +#: code:addons/odex25_account_asset/static/src/js/account_asset_reversed_widget.js:0 +#, python-format +msgid "This move has been reversed" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +msgid "Today Activities" +msgstr "نشاطات اليوم" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#, python-format +msgid "Total" +msgstr "الإجمالي" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Trying to pause an asset without any future depreciation line" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Turn as a deferred expense" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Turn as a deferred revenue" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Turn as an asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__user_type_id +msgid "Type of the account" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__activity_exception_decoration +msgid "Type of the exception activity on record." +msgstr "نوع النشاط الاستثنائي المسجل." + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_unread +msgid "Unread Messages" +msgstr "الرسائل الجديدة" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_unread_counter +msgid "Unread Messages Counter" +msgstr "عدد الرسائل الجديدة" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/wizard/asset_modify.py:0 +#, python-format +msgid "Value decrease for: %(asset)s" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/wizard/asset_modify.py:0 +#: code:addons/odex25_account_asset/wizard/asset_modify.py:0 +#, python-format +msgid "Value increase for: %(asset)s" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__website_message_ids +msgid "Website Messages" +msgstr "رسائل الموقع" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__website_message_ids +msgid "Website communication history" +msgstr "سجل تواصل الموقع" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__state +msgid "" +"When an asset is created, the status is 'Draft'.\n" +"If the asset is confirmed, the status goes in 'Running' and the depreciation lines can be posted in the accounting.\n" +"The 'On Hold' status can be set manually when you want to pause the depreciation of an asset for some time.\n" +"You can manually close an asset when the depreciation is over. If the last line of depreciation is posted, the asset automatically goes in that status." +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__method_period__12 +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__asset_modify__method_period__12 +msgid "Years" +msgstr "عدد السنوات" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "You cannot archive a record that is not closed" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#: code:addons/odex25_account_asset/wizard/asset_sell.py:0 +#, python-format +msgid "" +"You cannot automate the journal entry for an asset that has a running gross " +"increase. Please use 'Dispose' on the increase(s)." +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "" +"You cannot create an asset from lines containing credit and debit on the " +"account or with a null amount" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "You cannot delete a document that is in %s state." +msgstr "لا يمكنك حذف ملف في الحالة %s." + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "" +"You cannot delete an asset linked to posted entries.\n" +"You should either confirm the asset, then, sell or dispose of it, or cancel the linked journal entries." +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "" +"You cannot pause an asset with posted depreciation lines in the future." +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "" +"You cannot reset to draft an entry having a posted deferred revenue/expense" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "e.g. Annual Subscription" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "e.g. Annually Paid Insurance" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "e.g. Laptop iBook" +msgstr "مثال: كمبيوتر محمول" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "select the related purchases" +msgstr "قم بتحديد عمليات الشراء ذات الصلة" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "this move" +msgstr "هذه الحركة" diff --git a/odex25_accounting/odex25_account_asset/i18n/ar_001.po b/odex25_accounting/odex25_account_asset/i18n/ar_001.po new file mode 100644 index 000000000..2b6203ca0 --- /dev/null +++ b/odex25_accounting/odex25_account_asset/i18n/ar_001.po @@ -0,0 +1,2104 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * odex25_account_asset +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-03 07:09+0000\n" +"PO-Revision-Date: 2023-12-03 07:09+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: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid " (copy)" +msgstr " (نسخة)" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__total_depreciation_entries_count +msgid "# Depreciation Entries" +msgstr " قيود الإهلاك" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__gross_increase_count +msgid "# Gross Increases" +msgstr "الزيادات الإجمالية" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__depreciation_entries_count +msgid "# Posted Depreciation Entries" +msgstr "قيود الإهلاك المُرحلة" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "%s created from invoice" +msgstr "تم انشاؤها من الفاتورة %s" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "(prorata entry)" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "A deferred expense has been created for this move:" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "A deferred revenue has been created for this move:" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "A document linked to %s has been deleted: " +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/wizard/asset_modify.py:0 +#, python-format +msgid "A gross increase has been created" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model,name:odex25_account_asset.model_account_account +msgid "Account" +msgstr "حساب" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__account_asset_counterpart_id +msgid "Account Asset Counterpart" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model,name:odex25_account_asset.model_account_assets_report +msgid "Account Assets Report" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__account_depreciation_id +msgid "Account Depreciation" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__account_depreciation_expense_id +msgid "Account Depreciation Expense" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__user_type_id +msgid "" +"Account Type is used for information purpose, to generate country-specific " +"legal reports, and set the rules to close a fiscal year and generate opening" +" entries." +msgstr "" +"يستخدم نوع الحساب في استخراج التقارير وفقاً للتقارير القانونية المطلوبة في " +"كل دولة، وتضع القواعد اللازمة في إقفال سنة مالية وإنشاء القيد الافتتاحي " +"للسنة المالية اللاحقة." + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__account_depreciation_id +msgid "Account used in the depreciation entries, to decrease the asset value." +msgstr "الحساب المستخدم لقيود إهلاكات الأصل، لتخفيض القيمة الدفترية للأصل." + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__account_depreciation_expense_id +msgid "" +"Account used in the periodical entries, to record a part of the asset as " +"expense." +msgstr "الحساب المستخدم للقيود الدورية لتسجيل قيد مصروف الإهلاك." + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Account used to recognize the expense" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Account used to recognize the revenue" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Account used to record the deferred expense" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Account used to record the deferred income" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__account_asset_id +msgid "" +"Account used to record the purchase of the asset at its original price." +msgstr "الحساب المستخدم لتسجيل قيد شراء الأصل بسعره الأصلي." + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset_sell__gain_account_id +msgid "Account used to write the journal item in case of gain" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_res_company__gain_account_id +msgid "" +"Account used to write the journal item in case of gain while selling an " +"asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset_sell__loss_account_id +msgid "Account used to write the journal item in case of loss" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_res_company__loss_account_id +msgid "" +"Account used to write the journal item in case of loss while selling an " +"asset" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Accounting" +msgstr "الحسابات" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__acquisition_date +#, python-format +msgid "Acquisition Date" +msgstr "تاريخ الاستحواذ" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__action +msgid "Action" +msgstr "إجراء" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_needaction +msgid "Action Needed" +msgstr "إجراء مطلوب" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__active +msgid "Active" +msgstr "نشط" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__activity_ids +msgid "Activities" +msgstr "الأنشطة" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__activity_exception_decoration +msgid "Activity Exception Decoration" +msgstr "زخرفة استثناء النشاط" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__activity_state +msgid "Activity State" +msgstr "حالة النشاط" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__activity_type_icon +msgid "Activity Type Icon" +msgstr "أيقونة نوع النشاط" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "All the lines should be from the same account" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "All the lines should be from the same move type" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "All the lines should be posted" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__already_depreciated_amount_import +msgid "Already Depreciated Amount Import" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__parent_id +msgid "An asset has a parent when it is the result of gaining value" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "An asset has been created for this move:" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__account_analytic_id +msgid "Analytic Account" +msgstr "الحساب التحليلي" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__analytic_tag_ids +msgid "Analytic Tag" +msgstr "الوسم التحليلي" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_revenue_model_search +msgid "Archived" +msgstr "مؤرشف" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#: code:addons/odex25_account_asset/models/account_move.py:0 +#: code:addons/odex25_account_asset/models/account_move.py:0 +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_pause__asset_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__asset_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__asset_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__asset_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__asset_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__asset_id +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_account__asset_type__purchase +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +#, python-format +msgid "Asset" +msgstr "الأصل" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +msgid "Asset Account" +msgstr "حساب الأصل" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__account_asset_id +msgid "Asset Gross Increase Account" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__asset_id_display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__asset_id_display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__asset_id_display_name +msgid "Asset Id Display Name" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__asset_ids_display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__asset_ids_display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__asset_ids_display_name +msgid "Asset Ids Display Name" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move_line__asset_ids +msgid "Asset Linked" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__asset_manually_modified +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__asset_manually_modified +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__asset_manually_modified +msgid "Asset Manually Modified" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_account__asset_model +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_expense_model_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_form_asset_inherit +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_revenue_model_search +msgid "Asset Model" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Asset Model name" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.actions.act_window,name:odex25_account_asset.action_account_asset_model_form +#: model:ir.ui.menu,name:odex25_account_asset.menu_action_account_asset_model_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_purchase_tree +msgid "Asset Models" +msgstr "نموذج الأصل" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__name +msgid "Asset Name" +msgstr "اسم الأصل" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_form_asset_inherit +msgid "Asset Options" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_account__asset_type +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__asset_type +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__asset_asset_type +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__asset_asset_type +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__asset_asset_type +msgid "Asset Type" +msgstr "نوع الأصل" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__asset_value_change +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__asset_value_change +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__asset_value_change +msgid "Asset Value Change" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Asset Values" +msgstr "قيم الأصول" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Asset created" +msgstr "تم إنشاء الأصل" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_move_line__asset_ids +msgid "Asset created from this Journal Item" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Asset paused" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Asset sold or disposed. Accounting entry awaiting for validation." +msgstr "تم بيع أو تخريد الأصل، القيود المحاسبية في انتظار المراجعة والترحيل." + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/wizard/asset_modify.py:0 +#, python-format +msgid "Asset unpaused" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Asset(s)" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model,name:odex25_account_asset.model_account_asset +msgid "Asset/Revenue Recognition" +msgstr "إثبات الأصل/الربح" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#: model:ir.actions.act_window,name:odex25_account_asset.action_account_asset_form +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__asset_ids +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__asset_ids +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__asset_ids +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_purchase_tree +#, python-format +msgid "Assets" +msgstr "الأصول" + +#. module: odex25_account_asset +#: model:ir.ui.menu,name:odex25_account_asset.menu_action_account_asset_form +msgid "Assets Register" +msgstr "الأصول" + +#. module: odex25_account_asset +#: model:ir.ui.menu,name:odex25_account_asset.menu_finance_config_assets +msgid "Assets and Revenues" +msgstr "الأصول والإيرادات" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +msgid "Assets in closed state" +msgstr "الأصول المُقفلة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +msgid "Assets in draft and open states" +msgstr "الأصول المسودة والجارية" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_attachment_count +msgid "Attachment Count" +msgstr "عدد المرفقات" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_form_asset_inherit +msgid "Automate Asset" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_form_asset_inherit +msgid "Automate Deferred Expense" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_form_asset_inherit +msgid "Automate Deferred Revenue" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__book_value +#, python-format +msgid "Book Value" +msgstr "القيمة الدفترية" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__branch_id +msgid "Branch" +msgstr "الفرع" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_account__can_create_asset +msgid "Can Create Asset" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_modify_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_pause_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_sell_form +msgid "Cancel" +msgstr "الغاء" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Category of asset" +msgstr "فئة الأصل" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#, python-format +msgid "Characteristics" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__children_ids +msgid "Children" +msgstr "الفروع" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__method +msgid "" +"Choose the method to use to compute the amount of depreciation lines.\n" +" * Straight Line: Calculated on basis of: Gross Value / Number of Depreciations\n" +" * Declining: Calculated on basis of: Residual Value * Declining Factor\n" +" * Declining then Straight Line: Like Declining but with a minimum depreciation value equal to the straight line value." +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__state__close +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +msgid "Closed" +msgstr "مغلق" + +#. module: odex25_account_asset +#: model:ir.model,name:odex25_account_asset.model_res_company +msgid "Companies" +msgstr "شركات" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__company_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__company_id +msgid "Company" +msgstr "شركة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Compute Depreciation" +msgstr "احتساب الإهلاك" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Compute Expense" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Compute Revenue" +msgstr "حساب الأرباح" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Confirm" +msgstr "تأكيد" + +#. module: odex25_account_asset +#: model:ir.actions.server,name:odex25_account_asset.action_account_aml_to_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_account__create_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_move_line_tree +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_move_line_tree_grouped_inherit +msgid "Create Asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_account__create_asset__validate +msgid "Create and validate" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_account__create_asset__draft +msgid "Create in draft" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__create_uid +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_pause__create_uid +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__create_uid +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__create_uid +msgid "Created by" +msgstr "أنشئ بواسطة" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__create_date +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_pause__create_date +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__create_date +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__create_date +msgid "Created on" +msgstr "أنشئ في" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__asset_depreciated_value +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__asset_depreciated_value +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__asset_depreciated_value +msgid "Cumulative Depreciation" +msgstr "مجمع الإهلاك" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Cumulative Expense" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Cumulative Revenue" +msgstr "الأرباح التراكمية" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__currency_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__currency_id +msgid "Currency" +msgstr "العملة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +msgid "Current" +msgstr "الجاري" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Current Values" +msgstr "القيم الحالية" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__invoice_id +msgid "Customer Invoice" +msgstr "فاتورة العميل" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__date +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +msgid "Date" +msgstr "التاريخ" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#, python-format +msgid "Dec. then Straight" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__method__degressive +#, python-format +msgid "Declining" +msgstr "انخفاض" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__method_progress_factor +msgid "Declining Factor" +msgstr "عامل الانخفاض" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__method__degressive_then_linear +msgid "Declining then Straight Line" +msgstr "الانخفاض ثم الخط المستقيم" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_account__asset_type__expense +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__asset_type__expense +#, python-format +msgid "Deferred Expense" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_expense_tree +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_expense_model_search +msgid "Deferred Expense Account" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Deferred Expense Amount" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_form_asset_inherit +msgid "Deferred Expense Model" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Deferred Expense Model name" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.actions.act_window,name:odex25_account_asset.action_account_expense_model_form +#: model:ir.ui.menu,name:odex25_account_asset.menu_action_account_expense_model_recognition +msgid "Deferred Expense Models" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_form_asset_inherit +msgid "Deferred Expense Options" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Deferred Expense name" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Deferred Expense(s)" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#: model:ir.actions.act_window,name:odex25_account_asset.action_account_expense_form +#: model:ir.ui.menu,name:odex25_account_asset.menu_action_account_expense_recognition +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_tree +#, python-format +msgid "Deferred Expenses" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_expense_tree +msgid "Deferred Expenses Models" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_account__asset_type__sale +#, python-format +msgid "Deferred Revenue" +msgstr "الأرباح المُرحلة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_sale_tree +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_revenue_model_search +msgid "Deferred Revenue Account" +msgstr "حساب الإيرادات المُرحلة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Deferred Revenue Amount" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_form_asset_inherit +msgid "Deferred Revenue Model" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Deferred Revenue Model name" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.actions.act_window,name:odex25_account_asset.action_account_revenue_model_form +#: model:ir.ui.menu,name:odex25_account_asset.menu_action_account_revenue_model_recognition +msgid "Deferred Revenue Models" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_form_asset_inherit +msgid "Deferred Revenue Options" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Deferred Revenue name" +msgstr "اسم الأرباح المُرحلة" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Deferred Revenue(s)" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#: model:ir.actions.act_window,name:odex25_account_asset.action_account_revenue_form +#: model:ir.ui.menu,name:odex25_account_asset.menu_action_account_revenue_recognition +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_sale_tree +#, python-format +msgid "Deferred Revenues" +msgstr "إيرادات مدفوعة مقدمًا" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_sale_tree +msgid "Deferred Revenues Models" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Deferred expense" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Deferred expense created" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Deferred revenue" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Deferred revenue created" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__value_residual +msgid "Depreciable Amount" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__value_residual +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__asset_remaining_value +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__asset_remaining_value +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__asset_remaining_value +msgid "Depreciable Value" +msgstr "القيمة القابلة للإستهلاك" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Depreciated Amount" +msgstr "المبلغ المستهلك" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +#, python-format +msgid "Depreciation" +msgstr "إهلاك" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__account_depreciation_id +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_search +msgid "Depreciation Account" +msgstr "حساب الإهلاك" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Depreciation Board" +msgstr "جدول الإهلاكات" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Depreciation Date" +msgstr "تاريخ الإهلاك" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__depreciation_move_ids +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Depreciation Lines" +msgstr "بنود الإهلاك" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Depreciation Method" +msgstr "طريقة الإهلاك" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__depreciation_number_import +msgid "Depreciation Number Import" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.actions.client,name:odex25_account_asset.action_account_report_assets +#: model:ir.ui.menu,name:odex25_account_asset.menu_action_account_report_assets +msgid "Depreciation Schedule" +msgstr "جدول الإهلاك" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#, python-format +msgid "Depreciation Table Report" +msgstr "تقرير جدول الإهلاك" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/wizard/asset_modify.py:0 +#, python-format +msgid "Depreciation board modified" +msgstr "تم تعديل جدول الإهلاكات" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Depreciation entry %s posted (%s)" +msgstr "بند الإهلاك %s تم ترحيله (%s)" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Depreciation entry %s reversed (%s)" +msgstr "قيد الإهلاك %s تم عكسه (%s)" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__display_account_asset_id +msgid "Display Account Asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__display_model_choice +msgid "Display Model Choice" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_account__display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_pause__display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_assets_report__display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move_line__display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__display_name +#: model:ir.model.fields,field_description:odex25_account_asset.field_res_company__display_name +msgid "Display Name" +msgstr "الاسم المعروض" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Disposal" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__disposal_date +msgid "Disposal Date" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Disposal Move" +msgstr "حركة التخريد" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Disposal Moves" +msgstr "حركات التخريد" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset_sell__action__dispose +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_sell_form +msgid "Dispose" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__state__draft +msgid "Draft" +msgstr "مسودة" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__draft_asset_ids +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__draft_asset_ids +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__draft_asset_ids +msgid "Draft Asset" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Duration" +msgstr "المدة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Existing Depreciation Schedule" +msgstr "جدول الإهلاك الحالي" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Existing Depreciations" +msgstr "الإهلاكات الحالية" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_tree +#, python-format +msgid "Expense" +msgstr "المصروف" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__account_depreciation_expense_id +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_expense_tree +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_expense_model_search +msgid "Expense Account" +msgstr "حساب المصروفات" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Expense Board" +msgstr "لوحة المصروفات" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Expense Date" +msgstr "تاريخ المصروف" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Expense Lines" +msgstr "بنود المصروف" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_expense_tree +msgid "Expense Name" +msgstr "إسم المصروف" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Expense Recognition" +msgstr "الاعتراف بالمصروفات" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#, python-format +msgid "First Depreciation" +msgstr "الإهلاك الأول" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__first_depreciation_date +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "First Depreciation Date" +msgstr "تاريخ أول إهلاك" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__first_depreciation_date_import +msgid "First Depreciation Date Import" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "First Recognition Date" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__account_asset_id +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_search +msgid "Fixed Asset Account" +msgstr "حساب الأصل" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_follower_ids +msgid "Followers" +msgstr "المتابعون" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_channel_ids +msgid "Followers (Channels)" +msgstr "المتابعون (القنوات)" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_partner_ids +msgid "Followers (Partners)" +msgstr "المتابعون (الشركاء)" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__activity_type_icon +msgid "Font awesome icon e.g. fa-tasks" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_account__form_view_ref +msgid "Form View Ref" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +msgid "Future Activities" +msgstr "الأنشطة المستقبلية" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset_sell__gain_or_loss__gain +msgid "Gain" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__gain_account_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_res_company__gain_account_id +msgid "Gain Account" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__gain_or_loss +msgid "Gain Or Loss" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__gain_value +msgid "Gain Value" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +#, python-format +msgid "Gross Increase" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__gross_increase_value +msgid "Gross Increase Value" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_expense_model_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_revenue_model_search +msgid "Group By..." +msgstr "تجميع حسب.." + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_account__id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_pause__id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_assets_report__id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move_line__id +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__id +#: model:ir.model.fields,field_description:odex25_account_asset.field_res_company__id +msgid "ID" +msgstr "المُعرف" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__activity_exception_icon +msgid "Icon" +msgstr "الأيقونة" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__activity_exception_icon +msgid "Icon to indicate an exception activity." +msgstr "الأيقونة للإشارة إلى استثناء النشاط" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__message_needaction +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__message_unread +msgid "If checked, new messages require your attention." +msgstr "إذا كان محددًا، فهناك رسائل جديدة تحتاج لرؤيتها." + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__message_has_error +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__message_has_sms_error +msgid "If checked, some messages have a delivery error." +msgstr "إذا كان محددًا، فقد حدث خطأ في تسليم بعض الرسائل." + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_account__asset_model +msgid "" +"If this is selected, an expense/revenue will be created automatically when " +"Journal Items on this account are posted." +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__first_depreciation_date_import +msgid "" +"In case of an import from another software, provide the first depreciation " +"date in it." +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__depreciation_number_import +msgid "" +"In case of an import from another software, provide the number of " +"depreciations already done before starting with Odoo." +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__already_depreciated_amount_import +msgid "" +"In case of an import from another software, you might need to use this field" +" to have the right depreciation table report. This is the value that was " +"already depreciated with entries not computed from this model" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#, python-format +msgid "" +"In percent.
    For a linear method, the depreciation rate is computed per " +"year.
    For a declining method, it is the declining factor" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_modify_form +msgid "Increase Accounts" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__prorata +msgid "" +"Indicates that the first depreciation entry for this asset have to be done " +"from the asset date (purchase date) instead of the first January / Start " +"date of fiscal year" +msgstr "" +"يشير إلى احتساب بداية الإهلاكات من تاريخ بداية الأصل (تاريخ الشراء) بدلاً عن" +" الأول من يناير / أو تاريخ بداية السنة المالية." + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__invoice_line_id +msgid "Invoice Line" +msgstr "بند الفاتورة" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_is_follower +msgid "Is Follower" +msgstr "متابع" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__salvage_value +msgid "It is the amount you plan to have that you cannot depreciate." +msgstr "" +"هذا هو المبلغ المتبقي ولا يمكن إهلاكه عند الوصول إلى تاريخ انتهاء الأصل." + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__journal_id +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_expense_model_search +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_revenue_model_search +msgid "Journal" +msgstr "دفتر اليومية" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Journal Entries" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model,name:odex25_account_asset.model_account_move +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Journal Entry" +msgstr "قيد اليومية" + +#. module: odex25_account_asset +#: model:ir.model,name:odex25_account_asset.model_account_move_line +msgid "Journal Item" +msgstr "عنصر اليومية" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__original_move_line_ids +#, python-format +msgid "Journal Items" +msgstr "عناصر اليومية" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "" +"Journal Items of {account} should have a label in order to generate an asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_account____last_update +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset____last_update +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_pause____last_update +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell____last_update +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_assets_report____last_update +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move____last_update +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move_line____last_update +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify____last_update +#: model:ir.model.fields,field_description:odex25_account_asset.field_res_company____last_update +msgid "Last Modified on" +msgstr "آخر تعديل في" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__write_uid +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_pause__write_uid +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__write_uid +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__write_uid +msgid "Last Updated by" +msgstr "آخر تحديث بواسطة" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__write_date +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_pause__write_date +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__write_date +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__write_date +msgid "Last Updated on" +msgstr "آخر تحديث في" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +msgid "Late Activities" +msgstr "الأنشطة المتأخرة" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#, python-format +msgid "Linear" +msgstr "قسط ثابت" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset_sell__gain_or_loss__loss +msgid "Loss" +msgstr "خسارة" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__loss_account_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_res_company__loss_account_id +msgid "Loss Account" +msgstr "حساب الخسارة" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_main_attachment_id +msgid "Main Attachment" +msgstr "المرفق الرئيسي" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_form_asset_inherit +msgid "Manage Items" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_has_error +msgid "Message Delivery error" +msgstr "خطأ في تسليم الرسائل" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_ids +msgid "Messages" +msgstr "الرسائل" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__method +#, python-format +msgid "Method" +msgstr "طريقة" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__model_id +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__state__model +msgid "Model" +msgstr "الكائن" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_modify_form +msgid "Modification" +msgstr "تعديل" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_modify_form +msgid "Modification reason" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_modify_form +msgid "Modify" +msgstr "تعديل" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#: model:ir.model,name:odex25_account_asset.model_asset_modify +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_modify_form +#, python-format +msgid "Modify Asset" +msgstr "تعديل الأصل" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Modify Depreciation" +msgstr "تعديل الإهلاكات" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Modify Expense" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Modify Revenue" +msgstr "تعديل الأرباح" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__method_period__1 +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__asset_modify__method_period__1 +msgid "Months" +msgstr "شهور" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_account__multiple_assets_per_line +msgid "Multiple Assets per Line" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_account__multiple_assets_per_line +msgid "" +"Multiple asset items will be generated depending on the bill line quantity " +"instead of 1 global asset." +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__my_activity_date_deadline +msgid "My Activity Deadline" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__need_date +msgid "Need Date" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_modify_form +msgid "New Values" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_asset_modify__value_residual +msgid "New residual amount for the asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_asset_modify__salvage_value +msgid "New salvage amount for the asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__activity_date_deadline +msgid "Next Activity Deadline" +msgstr "الموعد النهائي للنشاط التالي" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__activity_summary +msgid "Next Activity Summary" +msgstr "ملخص النشاط التالي" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__activity_type_id +msgid "Next Activity Type" +msgstr "نوع النشاط التالي" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Next Period Expense" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Next Period Revenue" +msgstr "أرباح الفترة القادمة" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_account__create_asset__no +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset_sell__gain_or_loss__no +msgid "No" +msgstr "لا" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#, python-format +msgid "No asset account" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__salvage_value +msgid "Not Depreciable Amount" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__salvage_value +msgid "Not Depreciable Value" +msgstr "القيمة الغير قابلة للاستهلاك" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__first_depreciation_date +msgid "" +"Note that this date does not alter the computation of the first journal " +"entry in case of prorata temporis assets. It simply changes its accounting " +"date" +msgstr "" +"لاحظ أن هذا التاريخ لا يغير من كيفية احتساب قيد المحاسبي الأول في حالة " +"الأصول التي تحتسب من تاريخ الشراء. كل ما يفعله هو تغيير تاريخ القيد." + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__number_asset_ids +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__number_asset_ids +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__number_asset_ids +msgid "Number Asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_needaction_counter +msgid "Number of Actions" +msgstr "عدد الإجراءات" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__method_number +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__method_number +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_purchase_tree +msgid "Number of Depreciations" +msgstr "عدد الإهلاكات" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__method_period +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__method_period +msgid "Number of Months in a Period" +msgstr "عدد الشهور في الفترة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_expense_tree +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_sale_tree +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Number of Recognitions" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__gross_increase_count +msgid "Number of assets made to increase the value of the asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__total_depreciation_entries_count +msgid "Number of depreciation entries (posted or not)" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_has_error_counter +msgid "Number of errors" +msgstr "عدد الاخطاء" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__message_needaction_counter +msgid "Number of messages which requires an action" +msgstr "عدد الرسائل التي تتطلب إجراء" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "عدد الرسائل الحادث بها خطأ في التسليم" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__message_unread_counter +msgid "Number of unread messages" +msgstr "عدد الرسائل الجديدة" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__state__paused +msgid "On Hold" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.line_caret_options +msgid "Open Asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__original_value +msgid "Original Value" +msgstr "القيمة الأصلية" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__parent_id +msgid "Parent" +msgstr "الأصل" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_pause_form +msgid "Pause" +msgstr "إيقاف" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#: model:ir.model,name:odex25_account_asset.model_account_asset_pause +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_pause_form +#, python-format +msgid "Pause Asset" +msgstr "إيقاف الأصل مؤقتاً" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Pause Depreciation" +msgstr "إيقاف الإهلاك مؤقتاً" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_pause__date +msgid "Pause date" +msgstr "تاريخ الإيقاف المؤقت" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_expense_tree +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_purchase_tree +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_sale_tree +msgid "Period length" +msgstr "طول المدة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Posted Entries" +msgstr "القيود المُرحّلة" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__prorata_date +msgid "Prorata Date" +msgstr "التاريخ النسبي" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__prorata +msgid "Prorata Temporis" +msgstr "التناسب الزمني" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__asset_type__purchase +msgid "Purchase: Asset" +msgstr "شراء: الأصل" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#, python-format +msgid "Rate" +msgstr "السعر" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_asset_modify__name +msgid "Reason" +msgstr "السبب" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "Related Expenses" +msgstr "النفقات ذات الصلة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Related Purchase" +msgstr "المشتريات المرتبطة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Related Sales" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Report of reversal for {name}" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Reset to running" +msgstr "إعادة تعيين للتشغيل" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Residual Amount to Recognize" +msgstr "المبلغ المتبقي للتعرف عليه" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__activity_user_id +msgid "Responsible User" +msgstr "المستخدم المسؤول" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Resume Depreciation" +msgstr "استئناف الاستهلاك" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +#, python-format +msgid "Revenue" +msgstr "الربح" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_sale_tree +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_revenue_model_search +msgid "Revenue Account" +msgstr "حساب الإيرادات" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Revenue Board" +msgstr "جانب الارباح" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Revenue Date" +msgstr "تاريخ الأرباح" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Revenue Lines" +msgstr "بنود الأرباح" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_model_sale_tree +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_sale_tree +msgid "Revenue Name" +msgstr "اسم الأرباح" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "Revenue Recognition" +msgstr "إثبات الإيرادات" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_bank_statement_line__reversal_move_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_move__reversal_move_id +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_payment__reversal_move_id +msgid "Reversal Move" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/wizard/asset_modify.py:0 +#, python-format +msgid "" +"Reverse the depreciation entries posted in the future in order to modify the" +" depreciation" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__state__open +msgid "Running" +msgstr "جاري" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_has_sms_error +msgid "SMS Delivery error" +msgstr "خطأ في تسليم الرسائل القصيرة" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Sale" +msgstr "المبيعات" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__asset_type__sale +msgid "Sale: Revenue Recognition" +msgstr "البيع: إثبات الإيراد" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Save Model" +msgstr "نموذج البيع" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Save model" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset_sell__select_invoice_line_id +msgid "Select Invoice Line" +msgstr "تحديد بند الفاتورة" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset_sell__action__sell +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_sell_form +msgid "Sell" +msgstr "بيع" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#: model:ir.model,name:odex25_account_asset.model_account_asset_sell +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.asset_sell_form +#, python-format +msgid "Sell Asset" +msgstr "بيع الأصل" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Sell or Dispose" +msgstr "بيع أو تخريد" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Set manually the original values or" +msgstr "قم بتعيين القيم يدوياً أو" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Set to Draft" +msgstr "تعيين كمسودة" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Set to Running" +msgstr "التعيين كجارٍ" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +msgid "Show all records which has next action date is before today" +msgstr "عرض كافة السجلات المُعين لها تاريخ إجراء تالي يسبق تاريخ اليوم الجاري" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Some fields are missing {}" +msgstr "بعض الحقول مفقودة {}" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Some required values are missing" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "Start Depreciating" +msgstr "بدء الإهلاك" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__state +msgid "Status" +msgstr "الحالة" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__activity_state +msgid "" +"Status based on activities\n" +"Overdue: Due date is already passed\n" +"Today: Activity date is today\n" +"Planned: Future activities." +msgstr "" +"الحالة على أساس الأنشطة\n" +"المتأخرة: تاريخ الاستحقاق مر\n" +"اليوم: تاريخ النشاط هو اليوم\n" +"المخطط: الأنشطة المستقبلية." + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__method__linear +msgid "Straight Line" +msgstr "خط مستقيم" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__book_value +msgid "" +"Sum of the depreciable value, the salvage value and the book value of all " +"value increase items" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_account__can_create_asset +msgid "" +"Technical field specifying if the account can generate asset depending on " +"it's type. It is used in the account form view." +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_asset_modify__gain_value +msgid "" +"Technical field to know if we should display the fields for the creation of " +"gross increase asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset_sell__gain_or_loss +msgid "" +"Technical field to know is there was a gain or a loss in the selling of the " +"asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__method_period +#: model:ir.model.fields,help:odex25_account_asset.field_asset_modify__method_period +msgid "The amount of time between two depreciations" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_asset_modify__asset_id +msgid "The asset to be modified by this wizard" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__children_ids +msgid "The children are the gains in value of this asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset_sell__invoice_id +msgid "" +"The disposal invoice is needed in order to generate the closing journal " +"entry." +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__method_number +msgid "The number of depreciations needed to depreciate your asset" +msgstr "عدد أقساط الإهلاك المطلوبة حتى تخريد أو انتهاء عمر الأصل" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "The remaining value on the last depreciation line must be 0" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset_sell__invoice_line_id +msgid "There are multiple lines that could be the related to this asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_bank_statement_line__asset_value_change +#: model:ir.model.fields,help:odex25_account_asset.field_account_move__asset_value_change +#: model:ir.model.fields,help:odex25_account_asset.field_account_payment__asset_value_change +msgid "" +"This is a technical field set to true when this move is the result of the " +"changing of value of an asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_bank_statement_line__asset_manually_modified +#: model:ir.model.fields,help:odex25_account_asset.field_account_move__asset_manually_modified +#: model:ir.model.fields,help:odex25_account_asset.field_account_payment__asset_manually_modified +msgid "" +"This is a technical field stating that a depreciation line has been manually" +" modified. It is used to recompute the depreciation table of an " +"asset/deferred revenue." +msgstr "" + +#. module: odex25_account_asset +#. openerp-web +#: code:addons/odex25_account_asset/static/src/js/account_asset_reversed_widget.js:0 +#, python-format +msgid "This move has been reversed" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_search +msgid "Today Activities" +msgstr "نشاطات اليوم" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/report/account_assets_report.py:0 +#, python-format +msgid "Total" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "Trying to pause an asset without any future depreciation line" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Turn as a deferred expense" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Turn as a deferred revenue" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "Turn as an asset" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__user_type_id +msgid "Type of the account" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__activity_exception_decoration +msgid "Type of the exception activity on record." +msgstr "نوع النشاط الاستثنائي المسجل." + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_unread +msgid "Unread Messages" +msgstr "الرسائل الجديدة" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__message_unread_counter +msgid "Unread Messages Counter" +msgstr "عدد الرسائل الجديدة" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/wizard/asset_modify.py:0 +#, python-format +msgid "Value decrease for: %(asset)s" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/wizard/asset_modify.py:0 +#: code:addons/odex25_account_asset/wizard/asset_modify.py:0 +#, python-format +msgid "Value increase for: %(asset)s" +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields,field_description:odex25_account_asset.field_account_asset__website_message_ids +msgid "Website Messages" +msgstr "رسائل الموقع" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__website_message_ids +msgid "Website communication history" +msgstr "سجل تواصل الموقع" + +#. module: odex25_account_asset +#: model:ir.model.fields,help:odex25_account_asset.field_account_asset__state +msgid "" +"When an asset is created, the status is 'Draft'.\n" +"If the asset is confirmed, the status goes in 'Running' and the depreciation lines can be posted in the accounting.\n" +"The 'On Hold' status can be set manually when you want to pause the depreciation of an asset for some time.\n" +"You can manually close an asset when the depreciation is over. If the last line of depreciation is posted, the asset automatically goes in that status." +msgstr "" + +#. module: odex25_account_asset +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__account_asset__method_period__12 +#: model:ir.model.fields.selection,name:odex25_account_asset.selection__asset_modify__method_period__12 +msgid "Years" +msgstr "عدد السنوات" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "You cannot archive a record that is not closed" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#: code:addons/odex25_account_asset/wizard/asset_sell.py:0 +#, python-format +msgid "" +"You cannot automate the journal entry for an asset that has a running gross " +"increase. Please use 'Dispose' on the increase(s)." +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "" +"You cannot create an asset from lines containing credit and debit on the " +"account or with a null amount" +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "You cannot delete a document that is in %s state." +msgstr "لا يمكنك حذف ملف في الحالة %s." + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "" +"You cannot delete an asset linked to posted entries.\n" +"You should either confirm the asset, then, sell or dispose of it, or cancel the linked journal entries." +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "" +"You cannot pause an asset with posted depreciation lines in the future." +msgstr "" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_move.py:0 +#, python-format +msgid "" +"You cannot reset to draft an entry having a posted deferred revenue/expense" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_revenue_form +msgid "e.g. Annual Subscription" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_expense_form +msgid "e.g. Annually Paid Insurance" +msgstr "" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "e.g. Laptop iBook" +msgstr "مثال: كمبيوتر محمول" + +#. module: odex25_account_asset +#: model_terms:ir.ui.view,arch_db:odex25_account_asset.view_account_asset_form +msgid "select the related purchases" +msgstr "قم بتحديد عمليات الشراء ذات الصلة" + +#. module: odex25_account_asset +#: code:addons/odex25_account_asset/models/account_asset.py:0 +#, python-format +msgid "this move" +msgstr "هذه الحركة" diff --git a/odex25_accounting/odex25_account_asset/models/__init__.py b/odex25_accounting/odex25_account_asset/models/__init__.py new file mode 100644 index 000000000..03f4ce9a9 --- /dev/null +++ b/odex25_accounting/odex25_account_asset/models/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- + + +from . import account +from . import account_asset +from . import account_move +from . import res_company diff --git a/odex25_accounting/odex25_account_asset/models/account.py b/odex25_accounting/odex25_account_asset/models/account.py new file mode 100644 index 000000000..4276d78e4 --- /dev/null +++ b/odex25_accounting/odex25_account_asset/models/account.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + + +from odoo import api, fields, models, _ + + +class AccountAccount(models.Model): + _inherit = 'account.account' + + asset_model = fields.Many2one('account.asset', domain=lambda self: [('state', '=', 'model'), ('asset_type', '=', self.asset_type)], help="If this is selected, an expense/revenue will be created automatically when Journal Items on this account are posted.") + create_asset = fields.Selection([('no', 'No'), ('draft', 'Create in draft'), ('validate', 'Create and validate')], required=True, default='no') + can_create_asset = fields.Boolean(compute="_compute_can_create_asset", help="""Technical field specifying if the account can generate asset depending on it's type. It is used in the account form view.""") + form_view_ref = fields.Char(compute='_compute_can_create_asset') + asset_type = fields.Selection([('sale', 'Deferred Revenue'), ('expense', 'Deferred Expense'), ('purchase', 'Asset')], compute='_compute_can_create_asset') + # decimal quantities are not supported, quantities are rounded to the lower int + multiple_assets_per_line = fields.Boolean(string='Multiple Assets per Line', default=False, + help="Multiple asset items will be generated depending on the bill line quantity instead of 1 global asset.") + + @api.depends('user_type_id') + def _compute_can_create_asset(self): + for record in self: + if record.auto_generate_asset(): + record.asset_type = 'purchase' + elif record.auto_generate_deferred_revenue(): + record.asset_type = 'sale' + elif record.auto_generate_deferred_expense(): + record.asset_type = 'expense' + else: + record.asset_type = False + + record.can_create_asset = record.asset_type != False + + record.form_view_ref = { + 'purchase': 'odex25_account_asset.view_account_asset_form', + 'sale': 'odex25_account_asset.view_account_asset_revenue_form', + 'expense': 'odex25_account_asset.view_account_asset_expense_form', + }.get(record.asset_type) + + def auto_generate_asset(self): + return self.user_type_id in self.get_asset_accounts_type() + + def auto_generate_deferred_revenue(self): + return self.user_type_id in self.get_deferred_revenue_accounts_type() + + def auto_generate_deferred_expense(self): + return self.user_type_id in self.get_deferred_expense_accounts_type() + + def get_asset_accounts_type(self): + return self.env.ref('account.data_account_type_fixed_assets') + self.env.ref('account.data_account_type_non_current_assets') + + def get_deferred_revenue_accounts_type(self): + return self.env.ref('account.data_account_type_current_liabilities') + self.env.ref('account.data_account_type_non_current_liabilities') + + def get_deferred_expense_accounts_type(self): + return self.env.ref('account.data_account_type_current_assets') + self.env.ref('account.data_account_type_prepayments') diff --git a/odex25_accounting/odex25_account_asset/models/account_asset.py b/odex25_accounting/odex25_account_asset/models/account_asset.py new file mode 100644 index 000000000..81e7da9d8 --- /dev/null +++ b/odex25_accounting/odex25_account_asset/models/account_asset.py @@ -0,0 +1,843 @@ +# -*- coding: utf-8 -*- + + +import calendar +from dateutil.relativedelta import relativedelta +from math import copysign + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError +from odoo.tools import float_compare, float_is_zero, float_round + + +class AccountAsset(models.Model): + _name = 'account.asset' + _description = 'Asset/Revenue Recognition' + _inherit = ['mail.thread', 'mail.activity.mixin'] + + depreciation_entries_count = fields.Integer(compute='_entry_count', string='# Posted Depreciation Entries') + gross_increase_count = fields.Integer(compute='_entry_count', string='# Gross Increases', + help="Number of assets made to increase the value of the asset") + total_depreciation_entries_count = fields.Integer(compute='_entry_count', string='# Depreciation Entries', + help="Number of depreciation entries (posted or not)") + + name = fields.Char(string='Asset Name', compute='_compute_name', store=True, required=True, + states={'draft': [('readonly', False)], 'model': [('readonly', False)]}, tracking=True) + currency_id = fields.Many2one('res.currency', string='Currency', required=True, readonly=True, + states={'draft': [('readonly', False)]}, + default=lambda self: self.env.company.currency_id.id) + company_id = fields.Many2one('res.company', string='Company', required=True, readonly=True, + states={'draft': [('readonly', False)]}, + default=lambda self: self.env.company) + state = fields.Selection( + [('model', 'Model'), ('draft', 'Draft'), ('open', 'Running'), ('paused', 'On Hold'), ('close', 'Closed')], + 'Status', copy=False, default='draft', + help="When an asset is created, the status is 'Draft'.\n" + "If the asset is confirmed, the status goes in 'Running' and the depreciation lines can be posted in the accounting.\n" + "The 'On Hold' status can be set manually when you want to pause the depreciation of an asset for some time.\n" + "You can manually close an asset when the depreciation is over. If the last line of depreciation is posted, the asset automatically goes in that status.") + active = fields.Boolean(default=True) + asset_type = fields.Selection( + [('sale', 'Sale: Revenue Recognition'), ('purchase', 'Purchase: Asset'), ('expense', 'Deferred Expense')], + compute='_compute_asset_type', store=True, index=True) + + # Depreciation params + method = fields.Selection([('linear', 'Straight Line'), ('degressive', 'Declining'), + ('degressive_then_linear', 'Declining then Straight Line')], string='Method', + readonly=True, states={'draft': [('readonly', False)], 'model': [('readonly', False)]}, + default='linear', tracking=True, + help="Choose the method to use to compute the amount of depreciation lines.\n" + " * Straight Line: Calculated on basis of: Gross Value / Number of Depreciations\n" + " * Declining: Calculated on basis of: Residual Value * Declining Factor\n" + " * Declining then Straight Line: Like Declining but with a minimum depreciation value equal to the straight line value.") + method_number = fields.Integer(string='Number of Depreciations', readonly=True, tracking=True, + states={'draft': [('readonly', False)], 'model': [('readonly', False)]}, default=5, + help="The number of depreciations needed to depreciate your asset") + method_period = fields.Selection([('1', 'Months'), ('12', 'Years')], string='Number of Months in a Period', + readonly=True, default='12', + states={'draft': [('readonly', False)], 'model': [('readonly', False)]}, + help="The amount of time between two depreciations", tracking=True) + method_progress_factor = fields.Float(string='Declining Factor', readonly=True, default=0.3, + states={'draft': [('readonly', False)], 'model': [('readonly', False)]}) + prorata = fields.Boolean(string='Prorata Temporis', readonly=True, tracking=True, + states={'draft': [('readonly', False)], 'model': [('readonly', False)]}, + help='Indicates that the first depreciation entry for this asset have to be done from the asset date (purchase date) instead of the first January / Start date of fiscal year') + prorata_date = fields.Date( + string='Prorata Date', + readonly=True, states={'draft': [('readonly', False)]}, tracking=True) + account_asset_id = fields.Many2one('account.account', string='Fixed Asset Account', tracking=True, + compute='_compute_value', + help="Account used to record the purchase of the asset at its original price.", + store=True, + states={'draft': [('readonly', False)], 'model': [('readonly', False)]}, + domain="[('company_id', '=', company_id), ('is_off_balance', '=', False),('internal_type','!=','view')]") + account_depreciation_id = fields.Many2one('account.account', string='Depreciation Account', tracking=True, + readonly=True, + states={'draft': [('readonly', False)], 'model': [('readonly', False)]}, + domain="[('internal_type', '=', 'other'), ('deprecated', '=', False), ('company_id', '=', company_id), ('is_off_balance', '=', False)]", + help="Account used in the depreciation entries, to decrease the asset value.") + account_depreciation_expense_id = fields.Many2one('account.account', string='Expense Account', tracking=True, + readonly=True, states={'draft': [('readonly', False)], + 'model': [('readonly', False)]}, + domain="[('internal_type', '=', 'other'), ('deprecated', '=', False), ('company_id', '=', company_id), ('is_off_balance', '=', False)]", + help="Account used in the periodical entries, to record a part of the asset as expense.") + + journal_id = fields.Many2one('account.journal', string='Journal', tracking=True, readonly=True, + states={'draft': [('readonly', False)], 'model': [('readonly', False)]}, + domain="[('type', '=', 'general'), ('company_id', '=', company_id)]") + + # Values + original_value = fields.Monetary(string="Original Value", compute='_compute_value', store=True, readonly=True, + states={'draft': [('readonly', False)]}) + book_value = fields.Monetary(string='Book Value', readonly=True, compute='_compute_book_value', store=True, + help="Sum of the depreciable value, the salvage value and the book value of all value increase items") + value_residual = fields.Monetary(string='Depreciable Value', compute='_compute_value_residual') + salvage_value = fields.Monetary(string='Not Depreciable Value', readonly=True, + states={'draft': [('readonly', False)]}, + help="It is the amount you plan to have that you cannot depreciate.") + gross_increase_value = fields.Monetary(string="Gross Increase Value", compute="_compute_book_value", + compute_sudo=True) + + # Links with entries + depreciation_move_ids = fields.One2many('account.move', 'asset_id', string='Depreciation Lines', readonly=True, + states={'draft': [('readonly', False)], 'open': [('readonly', False)], + 'paused': [('readonly', False)]}) + original_move_line_ids = fields.Many2many('account.move.line', 'asset_move_line_rel', 'asset_id', 'line_id', + string='Journal Items', readonly=True, + states={'draft': [('readonly', False)]}, copy=False) + + # Analytic + account_analytic_id = fields.Many2one('account.analytic.account', string='Analytic Account', tracking=True, + domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]") + analytic_tag_ids = fields.Many2many('account.analytic.tag', string='Analytic Tag', tracking=True, + domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]") + + # Dates + first_depreciation_date = fields.Date( + string='First Depreciation Date', + compute='_compute_first_depreciation_date', store=True, readonly=False, + help='Note that this date does not alter the computation of the first journal entry in case of prorata temporis assets. It simply changes its accounting date', + ) + acquisition_date = fields.Date(compute='_compute_acquisition_date', store=True, + states={'draft': [('readonly', False)]}) + disposal_date = fields.Date(readonly=True, states={'draft': [('readonly', False)]}, + compute="_compute_disposal_date", store=True) + + # model-related fields + model_id = fields.Many2one('account.asset', string='Model', change_default=True, readonly=True, + states={'draft': [('readonly', False)]}, domain="[('company_id', '=', company_id)]") + user_type_id = fields.Many2one('account.account.type', related="account_asset_id.user_type_id", + string="Type of the account") + display_model_choice = fields.Boolean(compute="_compute_value", compute_sudo=True) + display_account_asset_id = fields.Boolean(compute="_compute_value", compute_sudo=True) + + # Capital gain + parent_id = fields.Many2one('account.asset', help="An asset has a parent when it is the result of gaining value") + children_ids = fields.One2many('account.asset', 'parent_id', + help="The children are the gains in value of this asset") + + # Adapt for import fields + already_depreciated_amount_import = fields.Monetary( + help="In case of an import from another software, you might need to use this field to have the right depreciation table report. This is the value that was already depreciated with entries not computed from this model", + default=0.0) + depreciation_number_import = fields.Integer( + help="In case of an import from another software, provide the number of depreciations already done before starting with Odoo.", + default=0) + first_depreciation_date_import = fields.Date( + help="In case of an import from another software, provide the first depreciation date in it.") + + @api.depends('depreciation_move_ids.date', 'state') + def _compute_disposal_date(self): + for asset in self: + if asset.state == 'close': + dates = asset.depreciation_move_ids.filtered(lambda m: m.date).mapped('date') + asset.disposal_date = dates and max(dates) + else: + asset.disposal_date = False + + @api.depends('original_move_line_ids', 'original_move_line_ids.account_id', 'asset_type') + def _compute_value(self): + for record in self: + misc_journal_id = self.env['account.journal'].search( + [('type', '=', 'general'), ('company_id', '=', record.company_id.id)], limit=1) + if not record.original_move_line_ids: + record.account_asset_id = record.account_asset_id or False + if not record.account_asset_id and ( + record.state == 'model' or not record.account_asset_id or record.asset_type != 'purchase'): + record.account_asset_id = record.account_depreciation_id if record.asset_type in ( + 'purchase', 'expense') else record.account_depreciation_expense_id + record.original_value = record.original_value or False + record.display_model_choice = record.state == 'draft' and self.env['account.asset'].search( + [('state', '=', 'model'), ('asset_type', '=', record.asset_type)]) + record.display_account_asset_id = True + continue + if any(line.move_id.state == 'draft' for line in record.original_move_line_ids): + raise UserError(_("All the lines should be posted")) + if any(account != record.original_move_line_ids[0].account_id for account in + record.original_move_line_ids.mapped('account_id')): + raise UserError(_("All the lines should be from the same account")) + if any(type != record.original_move_line_ids[0].move_id.move_type for type in + record.original_move_line_ids.mapped('move_id.move_type')): + raise UserError(_("All the lines should be from the same move type")) + record.account_asset_id = record.original_move_line_ids[0].account_id + record.display_model_choice = record.state == 'draft' and self.env['account.asset'].search_count( + [('state', '=', 'model'), ('account_asset_id.user_type_id', '=', record.user_type_id.id)]) + record.display_account_asset_id = False + if not record.journal_id: + record.journal_id = misc_journal_id + total_credit = sum(line.credit for line in record.original_move_line_ids) + total_debit = sum(line.debit for line in record.original_move_line_ids) + record.original_value = total_credit + total_debit + if record.account_asset_id.multiple_assets_per_line and len(record.original_move_line_ids) == 1: + record.original_value /= max(1, int(record.original_move_line_ids.quantity)) + if (total_credit and total_debit) or record.original_value == 0: + raise UserError( + _("You cannot create an asset from lines containing credit and debit on the account or with a null amount")) + + @api.depends('original_move_line_ids', 'prorata_date', 'first_depreciation_date') + def _compute_acquisition_date(self): + for record in self: + record.acquisition_date = record.acquisition_date or min(record.original_move_line_ids.mapped('date') + [ + record.prorata_date or record.first_depreciation_date or fields.Date.today()]) + + @api.onchange('original_move_line_ids') + def _onchange_original_move_line_ids(self): + # Force the recompute + self.acquisition_date = False + self._compute_acquisition_date() + + @api.depends('original_move_line_ids') + def _compute_name(self): + for record in self: + record.name = record.name or (record.original_move_line_ids and record.original_move_line_ids[0].name or '') + + @api.depends('original_move_line_ids') + @api.depends_context('asset_type') + def _compute_asset_type(self): + for record in self: + if not record.asset_type and 'asset_type' in self.env.context: + record.asset_type = self.env.context['asset_type'] + if not record.asset_type and record.original_move_line_ids: + account = record.original_move_line_ids.account_id + record.asset_type = account.asset_type + + @api.depends('original_value', 'salvage_value', 'already_depreciated_amount_import', 'depreciation_move_ids.state') + def _compute_value_residual(self): + for record in self: + record.value_residual = record.original_value - record.salvage_value - record.already_depreciated_amount_import - abs( + sum(record.depreciation_move_ids.filtered(lambda m: m.state == 'posted').mapped('amount_total'))) + + @api.depends('value_residual', 'salvage_value', 'children_ids.book_value') + def _compute_book_value(self): + for record in self: + record.book_value = record.value_residual + record.salvage_value + sum( + record.children_ids.mapped('book_value')) + record.gross_increase_value = sum(record.children_ids.mapped('original_value')) + + @api.onchange('prorata') + def _onchange_prorata(self): + if self.prorata: + self.prorata_date = fields.Date.today() + + @api.onchange('depreciation_move_ids') + def _onchange_depreciation_move_ids(self): + seq = 0 + asset_remaining_value = self.original_value + cumulated_depreciation = 0 + for m in self.depreciation_move_ids.sorted(lambda x: x.date): + seq += 1 + if not m.reversal_move_id: + asset_remaining_value -= m.amount_total + cumulated_depreciation += m.amount_total + if not m.asset_manually_modified: + continue + m.asset_manually_modified = False + m.asset_remaining_value = asset_remaining_value + m.asset_depreciated_value = cumulated_depreciation + for older_move in self.depreciation_move_ids.sorted(lambda x: x.date)[seq:]: + if not older_move.reversal_move_id: + asset_remaining_value -= older_move.amount_total + cumulated_depreciation += older_move.amount_total + older_move.asset_remaining_value = asset_remaining_value + older_move.asset_depreciated_value = cumulated_depreciation + + @api.onchange('account_depreciation_id') + def _onchange_account_depreciation_id(self): + """ + The field account_asset_id is required but invisible in the Deferred Revenue Model form. + Therefore, set it when account_depreciation_id changes. + """ + if self.asset_type in ('sale', 'expense') and self.state == 'model': + self.account_asset_id = self.account_depreciation_id + + @api.onchange('account_asset_id') + def _onchange_account_asset_id(self): + self.display_model_choice = self.state == 'draft' and self.env['account.asset'].search_count( + [('state', '=', 'model'), ('user_type_id', '=', self.user_type_id.id)]) + if self.asset_type in ('purchase', 'expense'): + self.account_depreciation_id = self.account_depreciation_id or self.account_asset_id + else: + self.account_depreciation_expense_id = self.account_depreciation_expense_id or self.account_asset_id + + @api.onchange('model_id') + def _onchange_model_id(self): + model = self.model_id + if model: + self.method = model.method + self.method_number = model.method_number + self.method_period = model.method_period + self.method_progress_factor = model.method_progress_factor + self.prorata = model.prorata + self.prorata_date = fields.Date.today() + self.account_analytic_id = model.account_analytic_id.id + self.analytic_tag_ids = [(6, 0, model.analytic_tag_ids.ids)] + self.account_depreciation_id = model.account_depreciation_id + self.account_depreciation_expense_id = model.account_depreciation_expense_id + self.journal_id = model.journal_id + self.account_asset_id = model.account_asset_id + + @api.onchange('asset_type') + def _onchange_type(self): + if self.state != 'model': + if self.asset_type == 'sale': + self.prorata = True + self.method_period = '1' + else: + self.method_period = '12' + + @api.depends('acquisition_date', 'original_move_line_ids', 'method_period', 'company_id') + def _compute_first_depreciation_date(self): + for record in self: + pre_depreciation_date = record.acquisition_date or min(record.original_move_line_ids.mapped('date'), + default=record.acquisition_date) or fields.Date.today() + depreciation_date = pre_depreciation_date + relativedelta(day=31) + # ... or fiscalyear depending the number of period + if record.method_period == '12': + depreciation_date = depreciation_date + relativedelta( + month=int(record.company_id.fiscalyear_last_month)) + depreciation_date = depreciation_date + relativedelta(day=record.company_id.fiscalyear_last_day) + if depreciation_date < pre_depreciation_date: + depreciation_date = depreciation_date + relativedelta(years=1) + record.first_depreciation_date = depreciation_date + + def unlink(self): + for asset in self: + if asset.state in ['open', 'paused', 'close']: + raise UserError(_( + 'You cannot delete a document that is in %s state.', + dict(self._fields['state']._description_selection(self.env)).get(asset.state) + )) + + posted_amount = len(asset.depreciation_move_ids.filtered(lambda x: x.state == 'posted')) + if posted_amount > 0: + raise UserError(_('You cannot delete an asset linked to posted entries.' + '\nYou should either confirm the asset, then, sell or dispose of it,' + ' or cancel the linked journal entries.')) + + for line in asset.original_move_line_ids: + body = _('A document linked to %s has been deleted: ') % (line.name or _('this move')) + body += '%s' % (asset.id, asset.name) + line.move_id.message_post(body=body) + return super(AccountAsset, self).unlink() + + def _compute_board_amount(self, computation_sequence, residual_amount, total_amount_to_depr, max_depreciation_nb, + starting_sequence, depreciation_date): + amount = 0 + if computation_sequence == max_depreciation_nb: + # last depreciation always takes the asset residual amount + amount = residual_amount + else: + if self.method in ('degressive', 'degressive_then_linear'): + amount = residual_amount * self.method_progress_factor + if self.method in ('linear', 'degressive_then_linear'): + nb_depreciation = max_depreciation_nb - starting_sequence + if self.prorata: + nb_depreciation -= 1 + linear_amount = min(total_amount_to_depr / nb_depreciation, residual_amount) + if self.method == 'degressive_then_linear': + amount = max(linear_amount, amount) + else: + amount = linear_amount + return amount + + def compute_depreciation_board(self): + self.ensure_one() + amount_change_ids = self.depreciation_move_ids.filtered( + lambda x: x.asset_value_change and not x.reversal_move_id).sorted(key=lambda l: l.date) + # print(self.asset_value_change, 'x.asset_value_change') + posted_depreciation_move_ids = self.depreciation_move_ids.filtered( + lambda x: x.state == 'posted' and not x.asset_value_change and not x.reversal_move_id).sorted( + key=lambda l: l.date) + print(posted_depreciation_move_ids, 'posted_depreciation_move_ids') + already_depreciated_amount = sum([m.amount_total for m in posted_depreciation_move_ids]) + depreciation_number = self.method_number + if self.prorata: + depreciation_number += 1 + starting_sequence = 0 + amount_to_depreciate = self.value_residual + sum([m.amount_total for m in amount_change_ids]) + depreciation_date = self.first_depreciation_date + # if we already have some previous validated entries, starting date is last entry + method period + if posted_depreciation_move_ids and posted_depreciation_move_ids[-1].date: + last_depreciation_date = fields.Date.from_string(posted_depreciation_move_ids[-1].date) + if last_depreciation_date > depreciation_date: # in case we unpause the asset + depreciation_date = last_depreciation_date + relativedelta(months=+int(self.method_period)) + commands = [(2, line_id.id, False) for line_id in + self.depreciation_move_ids.filtered(lambda x: x.state == 'draft')] + newlines = self._recompute_board(depreciation_number, starting_sequence, amount_to_depreciate, + depreciation_date, already_depreciated_amount, amount_change_ids) + newline_vals_list = [] + for newline_vals in newlines: + # no need of amount field, as it is computed and we don't want to trigger its inverse function + del (newline_vals['amount_total']) + newline_vals_list.append(newline_vals) + new_moves = self.env['account.move'].create(newline_vals_list) + for move in new_moves: + commands.append((4, move.id)) + return self.write({'depreciation_move_ids': commands}) + + def _recompute_board(self, depreciation_number, starting_sequence, amount_to_depreciate, depreciation_date, + already_depreciated_amount, amount_change_ids): + self.ensure_one() + residual_amount = amount_to_depreciate + # Remove old unposted depreciation lines. We cannot use unlink() with One2many field + move_vals = [] + prorata = self.prorata and not self.env.context.get("ignore_prorata") + if amount_to_depreciate != 0.0: + for asset_sequence in range(starting_sequence + 1, depreciation_number + 1): + while amount_change_ids and amount_change_ids[0].date <= depreciation_date: + if not amount_change_ids[0].reversal_move_id: + residual_amount -= amount_change_ids[0].amount_total + amount_to_depreciate -= amount_change_ids[0].amount_total + already_depreciated_amount += amount_change_ids[0].amount_total + amount_change_ids[0].write({ + 'asset_remaining_value': float_round(residual_amount, + precision_rounding=self.currency_id.rounding), + 'asset_depreciated_value': amount_to_depreciate - residual_amount + already_depreciated_amount, + }) + amount_change_ids -= amount_change_ids[0] + amount = self._compute_board_amount(asset_sequence, residual_amount, amount_to_depreciate, + depreciation_number, starting_sequence, depreciation_date) + prorata_factor = 1 + move_ref = self.name + ' (%s/%s)' % ( + prorata and asset_sequence - 1 or asset_sequence, self.method_number) + if prorata and asset_sequence == 1: + move_ref = self.name + ' ' + _('(prorata entry)') + first_date = self.prorata_date + if int(self.method_period) % 12 != 0: + month_days = calendar.monthrange(first_date.year, first_date.month)[1] + days = month_days - first_date.day + 1 + prorata_factor = days / month_days + else: + total_days = (depreciation_date.year % 4) and 365 or 366 + days = (self.company_id.compute_fiscalyear_dates(first_date)['date_to'] - first_date).days + 1 + prorata_factor = days / total_days + amount = self.currency_id.round(amount * prorata_factor) + if float_is_zero(amount, precision_rounding=self.currency_id.rounding): + continue + residual_amount -= amount + move_vals.append(self.env['account.move']._prepare_move_for_asset_depreciation({ + 'amount': amount, + 'asset_id': self, + 'move_ref': move_ref, + 'date': depreciation_date, + 'asset_remaining_value': float_round(residual_amount, precision_rounding=self.currency_id.rounding), + 'asset_depreciated_value': amount_to_depreciate - residual_amount + already_depreciated_amount, + })) + + depreciation_date = depreciation_date + relativedelta(months=+int(self.method_period)) + # datetime doesn't take into account that the number of days is not the same for each month + if int(self.method_period) % 12 != 0: + max_day_in_month = calendar.monthrange(depreciation_date.year, depreciation_date.month)[1] + depreciation_date = depreciation_date.replace(day=max_day_in_month) + return move_vals + + @api.model + def _get_views(self, type): + form_view = self.env.ref('odex25_account_asset.view_account_asset_form') + tree_view = self.env.ref('odex25_account_asset.view_account_asset_purchase_tree') + if type == 'sale': + form_view = self.env.ref('odex25_account_asset.view_account_asset_revenue_form') + tree_view = self.env.ref('odex25_account_asset.view_account_asset_sale_tree') + elif type == 'expense': + form_view = self.env.ref('odex25_account_asset.view_account_asset_expense_form') + tree_view = self.env.ref('odex25_account_asset.view_account_asset_expense_tree') + return [[tree_view.id, "tree"], [form_view.id, "form"]] + + def action_asset_modify(self): + """ Returns an action opening the asset modification wizard. + """ + self.ensure_one() + new_wizard = self.env['asset.modify'].create({ + 'asset_id': self.id, + }) + return { + 'name': _('Modify Asset'), + 'view_mode': 'form', + 'res_model': 'asset.modify', + 'type': 'ir.actions.act_window', + 'target': 'new', + 'res_id': new_wizard.id, + 'context': self.env.context, + } + + def action_asset_pause(self): + """ Returns an action opening the asset pause wizard.""" + self.ensure_one() + new_wizard = self.env['account.asset.pause'].create({ + 'asset_id': self.id, + }) + return { + 'name': _('Pause Asset'), + 'view_mode': 'form', + 'res_model': 'account.asset.pause', + 'type': 'ir.actions.act_window', + 'target': 'new', + 'res_id': new_wizard.id, + } + + def action_set_to_close(self): + """ Returns an action opening the asset pause wizard.""" + self.ensure_one() + new_wizard = self.env['account.asset.sell'].create({ + 'asset_id': self.id, + }) + return { + 'name': _('Sell Asset'), + 'view_mode': 'form', + 'res_model': 'account.asset.sell', + 'type': 'ir.actions.act_window', + 'target': 'new', + 'res_id': new_wizard.id, + } + + def action_save_model(self): + form_ref = { + 'purchase': 'odex25_account_asset.view_account_asset_form', + 'sale': 'odex25_account_asset.view_account_asset_revenue_form', + 'expense': 'odex25_account_asset.view_account_asset_expense_form', + }.get(self.asset_type) + + return { + 'name': _('Save model'), + 'views': [[self.env.ref(form_ref).id, "form"]], + 'res_model': 'account.asset', + 'type': 'ir.actions.act_window', + 'context': { + 'default_state': 'model', + 'default_account_asset_id': self.account_asset_id.id, + 'default_account_depreciation_id': self.account_depreciation_id.id, + 'default_account_depreciation_expense_id': self.account_depreciation_expense_id.id, + 'default_journal_id': self.journal_id.id, + 'default_method': self.method, + 'default_method_number': self.method_number, + 'default_method_period': self.method_period, + 'default_method_progress_factor': self.method_progress_factor, + 'default_prorata': self.prorata, + 'default_prorata_date': self.prorata_date, + 'default_analytic_tag_ids': [(6, 0, self.analytic_tag_ids.ids)], + 'original_asset': self.id, + } + } + + def open_entries(self): + return { + 'name': _('Journal Entries'), + 'view_mode': 'tree,form', + 'res_model': 'account.move', + 'views': [(self.env.ref('account.view_move_tree').id, 'tree'), (False, 'form')], + 'type': 'ir.actions.act_window', + 'domain': [('id', 'in', self.depreciation_move_ids.ids)], + 'context': dict(self._context, create=False), + } + + def open_related_entries(self): + return { + 'name': _('Journal Items'), + 'view_mode': 'tree,form', + 'res_model': 'account.move.line', + 'view_id': False, + 'type': 'ir.actions.act_window', + 'domain': [('id', 'in', self.original_move_line_ids.ids)], + } + + def open_increase(self): + return { + 'name': _('Gross Increase'), + 'view_mode': 'tree,form', + 'res_model': 'account.asset', + 'view_id': False, + 'type': 'ir.actions.act_window', + 'domain': [('id', 'in', self.children_ids.ids)], + 'views': self.env['account.asset']._get_views(self.asset_type), + } + + def validate(self): + fields = [ + 'method', + 'method_number', + 'method_period', + 'method_progress_factor', + 'salvage_value', + 'original_move_line_ids', + ] + ref_tracked_fields = self.env['account.asset'].fields_get(fields) + self.write({'state': 'open'}) + for asset in self: + tracked_fields = ref_tracked_fields.copy() + if asset.method == 'linear': + del (tracked_fields['method_progress_factor']) + dummy, tracking_value_ids = asset._message_track(tracked_fields, dict.fromkeys(fields)) + asset_name = { + 'purchase': (_('Asset created'), _('An asset has been created for this move:')), + 'sale': (_('Deferred revenue created'), _('A deferred revenue has been created for this move:')), + 'expense': (_('Deferred expense created'), _('A deferred expense has been created for this move:')), + }[asset.asset_type] + msg = asset_name[1] + ' %s' % (asset.id, asset.name) + asset.message_post(body=asset_name[0], tracking_value_ids=tracking_value_ids) + for move_id in asset.original_move_line_ids.mapped('move_id'): + move_id.message_post(body=msg) + if not asset.depreciation_move_ids: + asset.compute_depreciation_board() + asset._check_depreciations() + asset.depreciation_move_ids._post() + + def _return_disposal_view(self, move_ids): + name = _('Disposal Move') + view_mode = 'form' + if len(move_ids) > 1: + name = _('Disposal Moves') + view_mode = 'tree,form' + return { + 'name': name, + 'view_mode': view_mode, + 'res_model': 'account.move', + 'type': 'ir.actions.act_window', + 'target': 'current', + 'res_id': move_ids[0], + 'domain': [('id', 'in', move_ids)] + } + + def _get_disposal_moves(self, invoice_line_ids, disposal_date): + def get_line(asset, amount, account): + return (0, 0, { + 'name': asset.name, + 'account_id': account.id, + 'debit': 0.0 if float_compare(amount, 0.0, precision_digits=prec) > 0 else -amount, + 'credit': amount if float_compare(amount, 0.0, precision_digits=prec) > 0 else 0.0, + 'analytic_account_id': account_analytic_id.id if asset.asset_type == 'sale' else False, + 'analytic_tag_ids': [(6, 0, analytic_tag_ids.ids)] if asset.asset_type == 'sale' else False, + 'currency_id': company_currency != current_currency and current_currency.id or False, + 'amount_currency': company_currency != current_currency and - 1.0 * asset.value_residual or 0.0, + }) + + move_ids = [] + assert len(self) == len(invoice_line_ids) + for asset, invoice_line_id in zip(self, invoice_line_ids): + if disposal_date < max(asset.depreciation_move_ids.filtered( + lambda x: not x.reversal_move_id and x.state == 'posted').mapped('date') or [fields.Date.today()]): + if invoice_line_id: + raise UserError( + 'There are depreciation posted after the invoice date (%s).\nPlease revert them or change the date of the invoice.' % disposal_date) + else: + raise UserError('There are depreciation posted in the future, please revert them.') + account_analytic_id = asset.account_analytic_id + analytic_tag_ids = asset.analytic_tag_ids + company_currency = asset.company_id.currency_id + current_currency = asset.currency_id + prec = company_currency.decimal_places + unposted_depreciation_move_ids = asset.depreciation_move_ids.filtered(lambda x: x.state == 'draft') + if unposted_depreciation_move_ids: + old_values = { + 'method_number': asset.method_number, + } + + # Remove all unposted depr. lines + commands = [(2, line_id.id, False) for line_id in unposted_depreciation_move_ids] + + # Create a new depr. line with the residual amount and post it + asset_sequence = len(asset.depreciation_move_ids) - len(unposted_depreciation_move_ids) + 1 + + initial_amount = asset.original_value + initial_account = asset.original_move_line_ids.account_id if len( + asset.original_move_line_ids.account_id) == 1 else asset.account_asset_id + depreciated_amount = copysign( + sum(asset.depreciation_move_ids.filtered(lambda r: r.state == 'posted').mapped('amount_total')), + -initial_amount) + depreciation_account = asset.account_depreciation_id + invoice_amount = copysign(invoice_line_id.price_subtotal, -initial_amount) + invoice_account = invoice_line_id.account_id + difference = -initial_amount - depreciated_amount - invoice_amount + difference_account = asset.company_id.gain_account_id if difference > 0 else asset.company_id.loss_account_id + line_datas = [(initial_amount, initial_account), (depreciated_amount, depreciation_account), + (invoice_amount, invoice_account), (difference, difference_account)] + if not invoice_line_id: + del line_datas[2] + vals = { + 'amount_total': current_currency._convert(asset.value_residual, company_currency, asset.company_id, + disposal_date), + 'asset_id': asset.id, + 'ref': asset.name + ': ' + (_('Disposal') if not invoice_line_id else _('Sale')), + 'asset_remaining_value': 0, + 'asset_depreciated_value': max(asset.depreciation_move_ids.filtered(lambda x: x.state == 'posted'), + key=lambda x: x.date, + default=self.env['account.move']).asset_depreciated_value, + 'date': disposal_date, + 'journal_id': asset.journal_id.id, + 'line_ids': [get_line(asset, amount, account) for amount, account in line_datas if account], + } + commands.append((0, 0, vals)) + asset.write({'depreciation_move_ids': commands, 'method_number': asset_sequence}) + tracked_fields = self.env['account.asset'].fields_get(['method_number']) + changes, tracking_value_ids = asset._message_track(tracked_fields, old_values) + if changes: + asset.message_post(body=_('Asset sold or disposed. Accounting entry awaiting for validation.'), + tracking_value_ids=tracking_value_ids) + move_ids += self.env['account.move'].search([('asset_id', '=', asset.id), ('state', '=', 'draft')]).ids + + return move_ids + + def set_to_close(self, invoice_line_id, date=None): + self.ensure_one() + disposal_date = date or fields.Date.today() + if invoice_line_id and self.children_ids.filtered( + lambda a: a.state in ('draft', 'open') or a.value_residual > 0): + raise UserError( + _("You cannot automate the journal entry for an asset that has a running gross increase. Please use 'Dispose' on the increase(s).")) + full_asset = self + self.children_ids + move_ids = full_asset._get_disposal_moves([invoice_line_id] * len(full_asset), disposal_date) + full_asset.write({'state': 'close'}) + if move_ids: + return self._return_disposal_view(move_ids) + + def set_to_draft(self): + self.write({'state': 'draft'}) + + def set_to_running(self): + if self.depreciation_move_ids and not max(self.depreciation_move_ids, + key=lambda m: m.date).asset_remaining_value == 0: + self.env['asset.modify'].create({'asset_id': self.id, 'name': _('Reset to running')}).modify() + self.write({'state': 'open'}) + + def resume_after_pause(self): + """ Sets an asset in 'paused' state back to 'open'. + A Depreciation line is created automatically to remove from the + depreciation amount the proportion of time spent + in pause in the current period. + """ + self.ensure_one() + return self.with_context(resume_after_pause=True).action_asset_modify() + + def pause(self, pause_date): + """ Sets an 'open' asset in 'paused' state, generating first a depreciation + line corresponding to the ratio of time spent within the current depreciation + period before putting the asset in pause. This line and all the previous + unposted ones are then posted. + """ + self.ensure_one() + + all_lines_before_pause = self.depreciation_move_ids.filtered(lambda x: x.date <= pause_date) + line_before_pause = all_lines_before_pause and max(all_lines_before_pause, key=lambda x: x.date) + following_lines = self.depreciation_move_ids.filtered(lambda x: x.date > pause_date) + if following_lines: + if any(line.state == 'posted' for line in following_lines): + raise UserError(_("You cannot pause an asset with posted depreciation lines in the future.")) + + if self.prorata: + first_following = min(following_lines, key=lambda x: x.date) + depreciation_period_start = line_before_pause and line_before_pause.date or self.prorata_date or self.first_depreciation_date + try: + time_ratio = ((pause_date - depreciation_period_start).days) / ( + first_following.date - depreciation_period_start).days + new_line = self._insert_depreciation_line(line_before_pause, + first_following.amount_total * time_ratio, + _("Asset paused"), pause_date) + if pause_date <= fields.Date.today(): + new_line._post() + except ZeroDivisionError: + pass + + self.write({'state': 'paused'}) + self.depreciation_move_ids.filtered(lambda x: x.state == 'draft').unlink() + self.message_post(body=_("Asset paused")) + else: + raise UserError(_("Trying to pause an asset without any future depreciation line")) + + def _insert_depreciation_line(self, line_before, amount, label, depreciation_date): + """ Inserts a new line in the depreciation board, shifting the sequence of + all the following lines from one unit. + :param line_before: The depreciation line after which to insert the new line, + or none if the inserted line should take the first position. + :param amount: The depreciation amount of the new line. + :param label: The name to give to the new line. + :param date: The date to give to the new line. + """ + self.ensure_one() + moveObj = self.env['account.move'] + + new_line = moveObj.create(moveObj._prepare_move_for_asset_depreciation({ + 'amount': amount, + 'asset_id': self, + 'move_ref': self.name + ': ' + label, + 'date': depreciation_date, + 'asset_remaining_value': self.value_residual - amount, + 'asset_depreciated_value': line_before and (line_before.asset_depreciated_value + amount) or amount, + })) + return new_line + + @api.onchange('company_id') + def _onchange_company_id(self): + self.currency_id = self.company_id.currency_id.id + + @api.depends('depreciation_move_ids.state', 'parent_id') + def _entry_count(self): + for asset in self: + res = self.env['account.move'].search_count( + [('asset_id', '=', asset.id), ('state', '=', 'posted'), ('reversal_move_id', '=', False)]) + asset.depreciation_entries_count = res or 0 + asset.total_depreciation_entries_count = len(asset.depreciation_move_ids) + asset.gross_increase_count = len(asset.children_ids) + + def copy_data(self, default=None): + if default is None: + default = {} + if self.state == 'model': + default.update(state='model') + default['name'] = self.name + _(' (copy)') + default['account_asset_id'] = self.account_asset_id.id + return super(AccountAsset, self).copy_data(default) + + @api.model_create_multi + def create(self, vals_list): + for vals in vals_list: + if 'state' in vals and vals['state'] != 'draft' and not ( + set(vals) - set({'account_depreciation_id', 'account_depreciation_expense_id', 'journal_id'})): + raise UserError(_("Some required values are missing")) + if self._context.get('import_file', False) and 'category_id' in vals: + changed_vals = self.onchange_category_id_values(vals['category_id'])['value'] + # To avoid to overwrite vals explicitly set by the import + [changed_vals.pop(key, None) for key in vals.keys()] + vals.update(changed_vals) + new_recs = super(AccountAsset, self.with_context(mail_create_nolog=True)).create(vals_list) + # if original_value is passed in vals, make sure the right value is set (as a different original_value may have been computed by _compute_value()) + for i in range(len(vals_list)): + if 'original_value' in vals_list[i]: + new_recs[i].original_value = vals_list[i]['original_value'] + if self.env.context.get('original_asset'): + # When original_asset is set, only one asset is created since its from the form view + original_asset = self.env['account.asset'].browse(self.env.context.get('original_asset')) + original_asset.model_id = new_recs + return new_recs + + @api.constrains('active', 'state') + def _check_active(self): + for record in self: + if not record.active and record.state != 'close': + raise UserError(_('You cannot archive a record that is not closed')) + + @api.constrains('depreciation_move_ids') + def _check_depreciations(self): + for record in self: + if record.state == 'open' and record.depreciation_move_ids and not record.currency_id.is_zero( + record.depreciation_move_ids.filtered(lambda x: not x.reversal_move_id).sorted( + lambda x: (x.date, x.id))[-1].asset_remaining_value): + raise UserError(_("The remaining value on the last depreciation line must be 0")) diff --git a/odex25_accounting/odex25_account_asset/models/account_move.py b/odex25_accounting/odex25_account_asset/models/account_move.py new file mode 100644 index 000000000..fb279b657 --- /dev/null +++ b/odex25_accounting/odex25_account_asset/models/account_move.py @@ -0,0 +1,336 @@ +# -*- coding: utf-8 -*- + + +import math +from odoo import api, fields, models, _ +from odoo.exceptions import UserError +from odoo.tools import float_compare, float_round +from odoo.tools.misc import formatLang +from dateutil.relativedelta import relativedelta + + +class AccountMove(models.Model): + _inherit = 'account.move' + + asset_id = fields.Many2one('account.asset', string='Asset', index=True, ondelete='cascade', copy=False, + domain="[('company_id', '=', company_id)]") + asset_asset_type = fields.Selection(related='asset_id.asset_type') + asset_remaining_value = fields.Monetary(string='Depreciable Value', copy=False) + asset_depreciated_value = fields.Monetary(string='Cumulative Depreciation', copy=False) + asset_manually_modified = fields.Boolean( + help='This is a technical field stating that a depreciation line has been manually modified. It is used to recompute the depreciation table of an asset/deferred revenue.', + copy=False) + asset_value_change = fields.Boolean( + help='This is a technical field set to true when this move is the result of the changing of value of an asset') + asset_ids = fields.One2many('account.asset', string='Assets', compute="_compute_asset_ids") + asset_ids_display_name = fields.Char( + compute="_compute_asset_ids") # just a button label. That's to avoid a plethora of different buttons defined in xml + asset_id_display_name = fields.Char( + compute="_compute_asset_ids") # just a button label. That's to avoid a plethora of different buttons defined in xml + number_asset_ids = fields.Integer(compute="_compute_asset_ids") + draft_asset_ids = fields.Boolean(compute="_compute_asset_ids") + + # reversed_entry_id is set on the reversal move but there is no way of knowing is a move has been reversed without this + reversal_move_id = fields.One2many('account.move', 'reversed_entry_id') + + @api.onchange('amount_total') + def _onchange_amount(self): + self.asset_manually_modified = True + + def _post(self, soft=True): + # OVERRIDE + posted = super()._post(soft) + + # log the post of a depreciation + posted._log_depreciation_asset() + + # look for any asset to create, in case we just posted a bill on an account + # configured to automatically create assets + posted._auto_create_asset() + return posted + + def _reverse_moves(self, default_values_list=None, cancel=False): + for move in self: + # Report the value of this move to the next draft move or create a new one + if move.asset_id: + # Set back the amount in the asset as the depreciation is now void + move.asset_id.value_residual += move.amount_total + # Recompute the status of the asset for all depreciations posted after the reversed entry + for later_posted in move.asset_id.depreciation_move_ids.filtered( + lambda m: m.date >= move.date and m.state == 'posted'): + later_posted.asset_depreciated_value -= move.amount_total + later_posted.asset_remaining_value += move.amount_total + first_draft = min(move.asset_id.depreciation_move_ids.filtered(lambda m: m.state == 'draft'), + key=lambda m: m.date, default=None) + if first_draft: + # If there is a draft, simply move/add the depreciation amount here + # The depreciated and remaining values don't need to change + first_draft.amount_total += move.amount_total + else: + # If there was no draft move left, create one + last_date = max(move.asset_id.depreciation_move_ids.mapped('date')) + method_period = move.asset_id.method_period + + self.create(self._prepare_move_for_asset_depreciation({ + 'asset_id': move.asset_id, + 'move_ref': _('Report of reversal for {name}').format(name=move.asset_id.name), + 'amount': move.amount_total, + 'date': last_date + ( + relativedelta(months=1) if method_period == "1" else relativedelta(years=1)), + 'asset_depreciated_value': move.amount_total + max( + move.asset_id.depreciation_move_ids.mapped('asset_depreciated_value')), + 'asset_remaining_value': 0, + })) + + msg = _('Depreciation entry %s reversed (%s)') % ( + move.name, formatLang(self.env, move.amount_total, currency_obj=move.company_id.currency_id)) + move.asset_id.message_post(body=msg) + + # If an asset was created for this move, delete it when reversing the move + for line in move.line_ids: + for asset in line.asset_ids: + if asset.state == 'draft' or all( + state == 'draft' for state in asset.depreciation_move_ids.mapped('state')): + asset.state = 'draft' + asset.unlink() + + return super(AccountMove, self)._reverse_moves(default_values_list, cancel) + + def button_cancel(self): + # OVERRIDE + res = super(AccountMove, self).button_cancel() + self.env['account.asset'].sudo().search([('original_move_line_ids.move_id', 'in', self.ids)]).write( + {'active': False}) + return res + + def button_draft(self): + for move in self: + if any(asset_id.state != 'draft' for asset_id in move.asset_ids): + raise UserError(_('You cannot reset to draft an entry having a posted deferred revenue/expense')) + return super(AccountMove, self).button_draft() + + def _log_depreciation_asset(self): + for move in self.filtered(lambda m: m.asset_id): + asset = move.asset_id + msg = _('Depreciation entry %s posted (%s)') % ( + move.name, formatLang(self.env, move.amount_total, currency_obj=move.company_id.currency_id)) + asset.message_post(body=msg) + + def _auto_create_asset(self): + create_list = [] + invoice_list = [] + auto_validate = [] + for move in self: + if not move.is_invoice(): + continue + + for move_line in move.line_ids.filtered(lambda line: not (move.move_type in ( + 'out_invoice', 'out_refund') and line.account_id.user_type_id.internal_group == 'asset')): + if ( + move_line.account_id + and (move_line.account_id.can_create_asset) + and move_line.account_id.create_asset != "no" + and not move.reversed_entry_id + and not (move_line.currency_id or move.currency_id).is_zero(move_line.price_total) + and not move_line.asset_ids + ): + if not move_line.name: + raise UserError( + _('Journal Items of {account} should have a label in order to generate an asset').format( + account=move_line.account_id.display_name)) + if move_line.account_id.multiple_assets_per_line: + # decimal quantities are not supported, quantities are rounded to the lower int + units_quantity = max(1, int(move_line.quantity)) + else: + units_quantity = 1 + vals = { + 'name': move_line.name, + 'company_id': move_line.company_id.id, + 'currency_id': move_line.company_currency_id.id, + 'account_analytic_id': move_line.analytic_account_id.id, + 'analytic_tag_ids': [(6, False, move_line.analytic_tag_ids.ids)], + 'original_move_line_ids': [(6, False, move_line.ids)], + 'state': 'draft', + } + model_id = move_line.account_id.asset_model + if model_id: + vals.update({ + 'model_id': model_id.id, + }) + auto_validate.extend([move_line.account_id.create_asset == 'validate'] * units_quantity) + invoice_list.extend([move] * units_quantity) + create_list.extend([vals] * units_quantity) + + assets = self.env['account.asset'].create(create_list) + for asset, vals, invoice, validate in zip(assets, create_list, invoice_list, auto_validate): + if 'model_id' in vals: + asset._onchange_model_id() + if validate: + asset.validate() + if invoice: + asset_name = { + 'purchase': _('Asset'), + 'sale': _('Deferred revenue'), + 'expense': _('Deferred expense'), + }[asset.asset_type] + msg = _('%s created from invoice') % (asset_name) + msg += ': %s' % (invoice.id, invoice.name) + asset.message_post(body=msg) + return assets + + @api.model + def _prepare_move_for_asset_depreciation(self, vals): + missing_fields = set( + ['asset_id', 'move_ref', 'amount', 'asset_remaining_value', 'asset_depreciated_value']) - set(vals) + if missing_fields: + raise UserError(_('Some fields are missing {}').format(', '.join(missing_fields))) + asset = vals['asset_id'] + account_analytic_id = asset.account_analytic_id + analytic_tag_ids = asset.analytic_tag_ids + depreciation_date = vals.get('date', fields.Date.context_today(self)) + company_currency = asset.company_id.currency_id + current_currency = asset.currency_id + prec = company_currency.decimal_places + amount = current_currency._convert(vals['amount'], company_currency, asset.company_id, depreciation_date) + # Keep the partner on the original invoice if there is only one + partner = asset.original_move_line_ids.mapped('partner_id') + partner = partner[:1] if len(partner) <= 1 else self.env['res.partner'] + if asset.original_move_line_ids and asset.original_move_line_ids[0].move_id.move_type in ['in_refund', + 'out_refund']: + amount = -amount + move_line_1 = { + 'name': asset.name, + 'partner_id': partner.id, + 'account_id': asset.account_depreciation_id.id, + 'debit': 0.0 if float_compare(amount, 0.0, precision_digits=prec) > 0 else -amount, + 'credit': amount if float_compare(amount, 0.0, precision_digits=prec) > 0 else 0.0, + 'analytic_account_id': account_analytic_id.id if asset.asset_type == 'sale' else False, + 'analytic_tag_ids': [(6, 0, analytic_tag_ids.ids)] if asset.asset_type == 'sale' else False, + 'currency_id': current_currency.id, + 'amount_currency': -vals['amount'], + } + move_line_2 = { + 'name': asset.name, + 'partner_id': partner.id, + 'account_id': asset.account_depreciation_expense_id.id, + 'credit': 0.0 if float_compare(amount, 0.0, precision_digits=prec) > 0 else -amount, + 'debit': amount if float_compare(amount, 0.0, precision_digits=prec) > 0 else 0.0, + 'analytic_account_id': account_analytic_id.id if asset.asset_type in ('purchase', 'expense') else False, + 'analytic_tag_ids': [(6, 0, analytic_tag_ids.ids)] if asset.asset_type in ( + 'purchase', 'expense') else False, + 'currency_id': current_currency.id, + 'amount_currency': vals['amount'], + } + move_vals = { + 'ref': vals['move_ref'], + 'partner_id': partner.id, + 'date': depreciation_date, + 'journal_id': asset.journal_id.id, + 'line_ids': [(0, 0, move_line_1), (0, 0, move_line_2)], + 'asset_id': asset.id, + 'asset_remaining_value': vals['asset_remaining_value'], + 'asset_depreciated_value': vals['asset_depreciated_value'], + 'amount_total': amount, + 'name': '/', + 'asset_value_change': vals.get('asset_value_change', False), + 'move_type': 'entry', + 'currency_id': current_currency.id, + } + return move_vals + + @api.depends('line_ids.asset_ids') + def _compute_asset_ids(self): + for record in self: + record.asset_ids = record.mapped('line_ids.asset_ids') + record.number_asset_ids = len(record.asset_ids) + if record.number_asset_ids: + asset_type = { + 'sale': _('Deferred Revenue(s)'), + 'purchase': _('Asset(s)'), + 'expense': _('Deferred Expense(s)') + } + record.asset_ids_display_name = '%s %s' % ( + len(record.asset_ids), asset_type.get(record.asset_ids[0].asset_type)) + else: + record.asset_ids_display_name = '' + record.asset_id_display_name = {'sale': _('Revenue'), 'purchase': _('Asset'), 'expense': _('Expense')}.get( + record.asset_id.asset_type) + record.draft_asset_ids = bool(record.asset_ids.filtered(lambda x: x.state == "draft")) + + @api.model + def create_asset_move(self, vals): + move_vals = self._prepare_move_for_asset_depreciation(vals) + return self.env['account.move'].create(move_vals) + + def open_asset_view(self): + ret = { + 'name': _('Asset'), + 'view_mode': 'form', + 'res_model': 'account.asset', + 'view_id': [v[0] for v in self.env['account.asset']._get_views(self.asset_asset_type) if v[1] == 'form'][0], + 'type': 'ir.actions.act_window', + 'res_id': self.asset_id.id, + 'context': dict(self._context, create=False), + } + if self.asset_asset_type == 'sale': + ret['name'] = _('Deferred Revenue') + elif self.asset_asset_type == 'expense': + ret['name'] = _('Deferred Expense') + return ret + + def action_open_asset_ids(self): + ret = { + 'name': _('Assets'), + 'view_type': 'form', + 'view_mode': 'tree,form', + 'res_model': 'account.asset', + 'view_id': False, + 'type': 'ir.actions.act_window', + 'domain': [('id', 'in', self.asset_ids.ids)], + 'views': self.env['account.asset']._get_views(self.asset_ids[0].asset_type), + } + if self.asset_ids[0].asset_type == 'sale': + ret['name'] = _('Deferred Revenues') + elif self.asset_ids[0].asset_type == 'expense': + ret['name'] = _('Deferred Expenses') + return ret + + +class AccountMoveLine(models.Model): + _inherit = 'account.move.line' + + asset_ids = fields.Many2many('account.asset', 'asset_move_line_rel', 'line_id', 'asset_id', string='Asset Linked', + help="Asset created from this Journal Item", copy=False) + + def _turn_as_asset(self, asset_type, view_name, view): + ctx = self.env.context.copy() + ctx.update({ + 'default_original_move_line_ids': [(6, False, self.env.context['active_ids'])], + 'default_company_id': self.company_id.id, + 'asset_type': asset_type, + }) + if any(line.move_id.state == 'draft' for line in self): + raise UserError(_("All the lines should be posted")) + if any(account != self[0].account_id for account in self.mapped('account_id')): + raise UserError(_("All the lines should be from the same account")) + return { + "name": view_name, + "type": "ir.actions.act_window", + "res_model": "account.asset", + "views": [[view.id, "form"]], + "target": "current", + "context": ctx, + } + + def turn_as_asset(self): + return self._turn_as_asset('purchase', _("Turn as an asset"), + self.env.ref("odex25_account_asset.view_account_asset_form")) + + def turn_as_deferred(self): + balance = sum(aml.debit - aml.credit for aml in self) + if balance > 0: + return self._turn_as_asset('expense', _("Turn as a deferred expense"), + self.env.ref('odex25_account_asset.view_account_asset_expense_form')) + else: + return self._turn_as_asset('sale', _("Turn as a deferred revenue"), + self.env.ref('odex25_account_asset.view_account_asset_revenue_form')) diff --git a/odex25_accounting/odex25_account_asset/models/res_company.py b/odex25_accounting/odex25_account_asset/models/res_company.py new file mode 100644 index 000000000..34a754664 --- /dev/null +++ b/odex25_accounting/odex25_account_asset/models/res_company.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- + + +from odoo import api, fields, models, _ + +class ResCompany(models.Model): + _inherit = "res.company" + + gain_account_id = fields.Many2one('account.account', domain="[('deprecated', '=', False), ('company_id', '=', id)]", help="Account used to write the journal item in case of gain while selling an asset") + loss_account_id = fields.Many2one('account.account', domain="[('deprecated', '=', False), ('company_id', '=', id)]", help="Account used to write the journal item in case of loss while selling an asset") diff --git a/odex25_accounting/odex25_account_asset/report/__init__.py b/odex25_accounting/odex25_account_asset/report/__init__.py new file mode 100644 index 000000000..041f27af4 --- /dev/null +++ b/odex25_accounting/odex25_account_asset/report/__init__.py @@ -0,0 +1,5 @@ + +# -*- coding: utf-8 -*- + + +from . import account_assets_report diff --git a/odex25_accounting/odex25_account_asset/report/account_assets_report.py b/odex25_accounting/odex25_account_asset/report/account_assets_report.py new file mode 100644 index 000000000..8616f2733 --- /dev/null +++ b/odex25_accounting/odex25_account_asset/report/account_assets_report.py @@ -0,0 +1,285 @@ +# -*- coding: utf-8 -*- + + +from odoo import api, fields, models, _ +from odoo.tools import format_date +import copy +import binascii +import struct +import time +import itertools +from collections import defaultdict + +MAX_NAME_LENGTH = 50 + + +class assets_report(models.AbstractModel): + _inherit = 'account.report' + _name = 'account.assets.report' + _description = 'Account Assets Report' + + filter_date = {'mode': 'range', 'filter': 'this_year'} + filter_all_entries = False + filter_hierarchy = True + filter_unfold_all = True + + def _get_report_name(self): + return _('Depreciation Table Report') + + def _get_templates(self): + templates = super(assets_report, self)._get_templates() + templates['main_template'] = 'odex25_account_asset.main_template_asset_report' + return templates + + def get_header(self, options): + start_date = format_date(self.env, options['date']['date_from']) + end_date = format_date(self.env, options['date']['date_to']) + return [ + [ + {'name': ''}, + {'name': _('Characteristics'), 'colspan': 4}, + {'name': _('Assets'), 'colspan': 4}, + {'name': _('Depreciation'), 'colspan': 4}, + {'name': _('Book Value')}, + ], + [ + {'name': ''}, # Description + {'name': _('Acquisition Date'), 'class': 'text-center'}, # Characteristics + {'name': _('First Depreciation'), 'class': 'text-center'}, + {'name': _('Method'), 'class': 'text-center'}, + {'name': _('Rate'), 'class': 'number', 'title': _('In percent.
    For a linear method, the depreciation rate is computed per year.
    For a declining method, it is the declining factor'), 'data-toggle': 'tooltip'}, + {'name': start_date, 'class': 'number'}, # Assets + {'name': _('+'), 'class': 'number'}, + {'name': _('-'), 'class': 'number'}, + {'name': end_date, 'class': 'number'}, + {'name': start_date, 'class': 'number'}, # Depreciation + {'name': _('+'), 'class': 'number'}, + {'name': _('-'), 'class': 'number'}, + {'name': end_date, 'class': 'number'}, + {'name': '', 'class': 'number'}, # Gross + ], + ] + + @api.model + def _init_filter_hierarchy(self, options, previous_options=None): + # overwrite because we don't depend on account.group + if self.filter_hierarchy is not None: + if previous_options and 'hierarchy' in previous_options: + options['hierarchy'] = previous_options['hierarchy'] + else: + options['hierarchy'] = self.filter_hierarchy + + def get_account_codes(self, account): + return [(name, name) for name in self._get_account_group(account.code)[1:]] + + def _get_account_group(self, account_code, parent_group=None, group_dict=None): + """ Get the list of parent groups for this account + return: list containing the main group key, then the name of every group + for this account, beginning by the more general, until the + name of the account itself. + """ + if not account_code: + # This is used if there is no account_asset_id + account_code = '##' + account_code_short = account_code[:2] + group_dict = group_dict or self.env['account.report']._get_account_groups_for_asset_report() + account_id = self.env['account.account'].search([('company_id', '=', self.env.company.id), ('code', '=', account_code)]) + account_string = account_id.display_name if account_id else _("No asset account") + for k, v in group_dict.items(): + try: + if int(account_code_short) == int(k): + return (parent_group or [k]) + [v['name']] + except ValueError: + if k[:2] <= account_code_short <= k[-2:]: + return self._get_account_group(account_code, (parent_group or [k]) + [v['name']], v['children']) + [account_string] + return (parent_group or [account_code_short]) + [account_string] + + def _get_lines(self, options, line_id=None): + options['self'] = self + lines = [] + total = [0] * 9 + asset_lines = self._get_assets_lines(options) + parent_lines = [] + children_lines = defaultdict(list) + for al in asset_lines: + if al['parent_id']: + children_lines[al['parent_id']] += [al] + else: + parent_lines += [al] + for al in parent_lines: + if al['asset_method'] == 'linear' and al['asset_method_number']: # some assets might have 0 depreciations because they dont lose value + asset_depreciation_rate = ('{:.2f} %').format((100.0 / al['asset_method_number']) * (12 / int(al['asset_method_period']))) + elif al['asset_method'] == 'linear': + asset_depreciation_rate = ('{:.2f} %').format(0.0) + else: + asset_depreciation_rate = ('{:.2f} %').format(float(al['asset_method_progress_factor']) * 100) + + depreciation_opening = al['depreciated_start'] - al['depreciation'] + depreciation_closing = al['depreciated_end'] + depreciation_minus = 0.0 + + opening = (al['asset_acquisition_date'] or al['asset_date']) < fields.Date.to_date(options['date']['date_from']) + asset_opening = al['asset_original_value'] if opening else 0.0 + asset_add = 0.0 if opening else al['asset_original_value'] + asset_minus = 0.0 + + if al['import_depreciated']: + asset_opening += asset_add + asset_add = 0 + depreciation_opening += al['import_depreciated'] + depreciation_closing += al['import_depreciated'] + + for child in children_lines[al['asset_id']]: + depreciation_opening += child['depreciated_start'] - child['depreciation'] + depreciation_closing += child['depreciated_end'] + + opening = (child['asset_acquisition_date'] or child['asset_date']) < fields.Date.to_date(options['date']['date_from']) + asset_opening += child['asset_original_value'] if opening else 0.0 + asset_add += 0.0 if opening else child['asset_original_value'] + + depreciation_add = depreciation_closing - depreciation_opening + asset_closing = asset_opening + asset_add + + if al['asset_state'] == 'close' and al['asset_disposal_date'] and al['asset_disposal_date'] < fields.Date.to_date(options['date']['date_to']): + depreciation_minus = depreciation_closing + depreciation_closing = 0.0 + depreciation_opening += depreciation_add + depreciation_add = 0 + asset_minus = asset_closing + asset_closing = 0.0 + + asset_gross = asset_closing - depreciation_closing + + total = [x + y for x, y in zip(total, [asset_opening, asset_add, asset_minus, asset_closing, depreciation_opening, depreciation_add, depreciation_minus, depreciation_closing, asset_gross])] + + id = "_".join([self._get_account_group(al['account_code'])[0], str(al['asset_id'])]) + name = str(al['asset_name']) + line = { + 'id': id, + 'level': 1, + 'name': name if self._context.get('print_mode') or len(name) < MAX_NAME_LENGTH else name[:MAX_NAME_LENGTH - 2] + '...', + 'columns': [ + {'name': al['asset_acquisition_date'] and format_date(self.env, al['asset_acquisition_date']) or '', 'no_format_name': ''}, # Characteristics + {'name': al['asset_date'] and format_date(self.env, al['asset_date']) or '', 'no_format_name': ''}, + {'name': (al['asset_method'] == 'linear' and _('Linear')) or (al['asset_method'] == 'degressive' and _('Declining')) or _('Dec. then Straight'), 'no_format_name': ''}, + {'name': asset_depreciation_rate, 'no_format_name': ''}, + {'name': self.format_value(asset_opening), 'no_format_name': asset_opening}, # Assets + {'name': self.format_value(asset_add), 'no_format_name': asset_add}, + {'name': self.format_value(asset_minus), 'no_format_name': asset_minus}, + {'name': self.format_value(asset_closing), 'no_format_name': asset_closing}, + {'name': self.format_value(depreciation_opening), 'no_format_name': depreciation_opening}, # Depreciation + {'name': self.format_value(depreciation_add), 'no_format_name': depreciation_add}, + {'name': self.format_value(depreciation_minus), 'no_format_name': depreciation_minus}, + {'name': self.format_value(depreciation_closing), 'no_format_name': depreciation_closing}, + {'name': self.format_value(asset_gross), 'no_format_name': asset_gross}, # Gross + ], + 'unfoldable': False, + 'unfolded': False, + 'caret_options': 'account.asset.line', + 'account_id': al['account_id'] + } + if len(name) >= MAX_NAME_LENGTH: + line.update({'title_hover': name}) + lines.append(line) + lines.append({ + 'id': 'total', + 'level': 0, + 'name': _('Total'), + 'columns': [ + {'name': ''}, # Characteristics + {'name': ''}, + {'name': ''}, + {'name': ''}, + {'name': self.format_value(total[0])}, # Assets + {'name': self.format_value(total[1])}, + {'name': self.format_value(total[2])}, + {'name': self.format_value(total[3])}, + {'name': self.format_value(total[4])}, # Depreciation + {'name': self.format_value(total[5])}, + {'name': self.format_value(total[6])}, + {'name': self.format_value(total[7])}, + {'name': self.format_value(total[8])}, # Gross + ], + 'unfoldable': False, + 'unfolded': False, + }) + return lines + + def _get_assets_lines(self, options): + "Get the data from the database" + where_account_move = " AND state != 'cancel'" + if not options.get('all_entries'): + where_account_move = " AND state = 'posted'" + + sql = """ + -- remove all the moves that have been reversed from the search + CREATE TEMPORARY TABLE IF NOT EXISTS temp_account_move () INHERITS (account_move) ON COMMIT DROP; + INSERT INTO temp_account_move SELECT move.* + FROM ONLY account_move move + LEFT JOIN ONLY account_move reversal ON reversal.reversed_entry_id = move.id + WHERE reversal.id IS NULL AND move.asset_id IS NOT NULL AND move.company_id in %(company_ids)s; + + SELECT asset.id as asset_id, + asset.parent_id as parent_id, + asset.name as asset_name, + asset.original_value as asset_original_value, + COALESCE(asset.first_depreciation_date_import, asset.first_depreciation_date) as asset_date, + asset.already_depreciated_amount_import as import_depreciated, + asset.disposal_date as asset_disposal_date, + asset.acquisition_date as asset_acquisition_date, + asset.method as asset_method, + (SELECT COUNT(*) FROM temp_account_move WHERE asset_id = asset.id AND asset_value_change != 't') + COALESCE(asset.depreciation_number_import, 0) as asset_method_number, + asset.method_period as asset_method_period, + asset.method_progress_factor as asset_method_progress_factor, + asset.state as asset_state, + account.code as account_code, + account.name as account_name, + account.id as account_id, + COALESCE(first_move.asset_depreciated_value, move_before.asset_depreciated_value, 0.0) as depreciated_start, + COALESCE(first_move.asset_remaining_value, move_before.asset_remaining_value, 0.0) as remaining_start, + COALESCE(last_move.asset_depreciated_value, move_before.asset_depreciated_value, 0.0) as depreciated_end, + COALESCE(last_move.asset_remaining_value, move_before.asset_remaining_value, 0.0) as remaining_end, + COALESCE(first_move.amount_total, 0.0) as depreciation + FROM account_asset as asset + LEFT JOIN account_account as account ON asset.account_asset_id = account.id + LEFT OUTER JOIN (SELECT MIN(date) as date, asset_id FROM temp_account_move WHERE date >= %(date_from)s AND date <= %(date_to)s {where_account_move} GROUP BY asset_id) min_date_in ON min_date_in.asset_id = asset.id + LEFT OUTER JOIN (SELECT MAX(date) as date, asset_id FROM temp_account_move WHERE date >= %(date_from)s AND date <= %(date_to)s {where_account_move} GROUP BY asset_id) max_date_in ON max_date_in.asset_id = asset.id + LEFT OUTER JOIN (SELECT MAX(date) as date, asset_id FROM temp_account_move WHERE date <= %(date_from)s {where_account_move} GROUP BY asset_id) max_date_before ON max_date_before.asset_id = asset.id + LEFT OUTER JOIN temp_account_move as first_move ON first_move.id = (SELECT m.id FROM temp_account_move m WHERE m.asset_id = asset.id AND m.date = min_date_in.date ORDER BY m.id ASC LIMIT 1) + LEFT OUTER JOIN temp_account_move as last_move ON last_move.id = (SELECT m.id FROM temp_account_move m WHERE m.asset_id = asset.id AND m.date = max_date_in.date ORDER BY m.id DESC LIMIT 1) + LEFT OUTER JOIN temp_account_move as move_before ON move_before.id = (SELECT m.id FROM temp_account_move m WHERE m.asset_id = asset.id AND m.date = max_date_before.date ORDER BY m.id DESC LIMIT 1) + WHERE asset.company_id in %(company_ids)s + AND asset.acquisition_date <= %(date_to)s + AND (asset.disposal_date >= %(date_from)s OR asset.disposal_date IS NULL) + AND asset.state not in ('model', 'draft') + AND asset.asset_type = 'purchase' + AND asset.active = 't' + + ORDER BY account.code, asset.acquisition_date; + """.format(where_account_move=where_account_move) + + date_to = options['date']['date_to'] + date_from = options['date']['date_from'] + if options.get('multi_company', False): + company_ids = tuple(self.env.companies.ids) + else: + company_ids = tuple(self.env.company.ids) + + self.flush() + self.env.cr.execute(sql, {'date_to': date_to, 'date_from': date_from, 'company_ids': company_ids}) + results = self.env.cr.dictfetchall() + self.env.cr.execute("DROP TABLE temp_account_move") # Because tests are run in the same transaction, we need to clean here the SQL INHERITS + return results + + def open_asset(self, options, params=None): + active_id = int(params.get('id').split('_')[-1]) + line = self.env['account.asset'].browse(active_id) + return { + 'name': line.name, + 'type': 'ir.actions.act_window', + 'res_model': 'account.asset', + 'view_mode': 'form', + 'view_id': False, + 'views': [(self.env.ref('odex25_account_asset.view_account_asset_form').id, 'form')], + 'res_id': line.id, + } diff --git a/odex25_accounting/odex25_account_asset/report/account_assets_report_views.xml b/odex25_accounting/odex25_account_asset/report/account_assets_report_views.xml new file mode 100644 index 000000000..baa30a39d --- /dev/null +++ b/odex25_accounting/odex25_account_asset/report/account_assets_report_views.xml @@ -0,0 +1,28 @@ + + + + + + + + + Depreciation Schedule + account_report + + + + + + diff --git a/odex25_accounting/odex25_account_asset/security/account_asset_security.xml b/odex25_accounting/odex25_account_asset/security/account_asset_security.xml new file mode 100644 index 000000000..7dbad6d5a --- /dev/null +++ b/odex25_accounting/odex25_account_asset/security/account_asset_security.xml @@ -0,0 +1,11 @@ + + + + + Account Asset multi-company + + + ['|',('company_id','=',False),('company_id', 'in', company_ids)] + + + diff --git a/odex25_accounting/odex25_account_asset/security/ir.model.access.csv b/odex25_accounting/odex25_account_asset/security/ir.model.access.csv new file mode 100644 index 000000000..a4083a3ed --- /dev/null +++ b/odex25_accounting/odex25_account_asset/security/ir.model.access.csv @@ -0,0 +1,7 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_account_asset,account.asset,model_account_asset,account.group_account_readonly,1,0,0,0 +access_account_asset_manager,account.asset,model_account_asset,account.group_account_manager,1,1,1,1 +access_account_asset_invoicing_payment,account.asset,model_account_asset,account.group_account_invoice,1,0,1,0 +access_asset_modify,access.asset.modify,model_asset_modify,account.group_account_user,1,1,1,0 +access_account_asset_pause,access.account.asset.pause,model_account_asset_pause,account.group_account_user,1,1,1,0 +access_account_asset_sell,access.account.asset.sell,model_account_asset_sell,account.group_account_user,1,1,1,0 diff --git a/odex25_accounting/odex25_account_asset/static/description/icon.png b/odex25_accounting/odex25_account_asset/static/description/icon.png new file mode 100644 index 000000000..899c85343 Binary files /dev/null and b/odex25_accounting/odex25_account_asset/static/description/icon.png differ diff --git a/odex25_accounting/odex25_account_asset/static/description/icon.svg b/odex25_accounting/odex25_account_asset/static/description/icon.svg new file mode 100644 index 000000000..7d215c3ff --- /dev/null +++ b/odex25_accounting/odex25_account_asset/static/description/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/odex25_accounting/odex25_account_asset/static/src/js/account_asset.js b/odex25_accounting/odex25_account_asset/static/src/js/account_asset.js new file mode 100644 index 000000000..7497e6b54 --- /dev/null +++ b/odex25_accounting/odex25_account_asset/static/src/js/account_asset.js @@ -0,0 +1,32 @@ +odoo.define('account_asset.AssetFormView', function(require) { +"use strict"; + +var FormRenderer = require('web.FormRenderer'); +var FormView = require('web.FormView'); +var core = require('web.core'); +var viewRegistry = require('web.view_registry'); + +var _t = core._t; + +var AccountAssetFormRenderer = FormRenderer.extend({ + events: _.extend({}, FormRenderer.prototype.events, { + 'click .add_original_move_line': '_onAddOriginalMoveLine', + }), + /* + * Open the m2o item selection from another button + */ + _onAddOriginalMoveLine: function(ev) { + _.find(this.allFieldWidgets[this.state.id], x => x['name'] == 'original_move_line_ids').onAddRecordOpenDialog(); + }, +}); + +var AssetFormView = FormView.extend({ + config: _.extend({}, FormView.prototype.config, { + Renderer: AccountAssetFormRenderer, + }), +}); + +viewRegistry.add("asset_form", AssetFormView); +return AssetFormView; + +}); diff --git a/odex25_accounting/odex25_account_asset/static/src/js/account_asset_reversed_widget.js b/odex25_accounting/odex25_account_asset/static/src/js/account_asset_reversed_widget.js new file mode 100644 index 000000000..fa7b767e2 --- /dev/null +++ b/odex25_accounting/odex25_account_asset/static/src/js/account_asset_reversed_widget.js @@ -0,0 +1,53 @@ +odoo.define('account_asset.widget', function(require) { +"use strict"; + +/** + * The purpose of this widget is to shows a toggle button on depreciation and + * installment lines for posted/unposted line. When clicked, it calls the method + * create_move on the object account.asset.depreciation.line. + * Note that this widget can only work on the account.asset.depreciation.line + * model as some of its fields are harcoded. + */ + +var AbstractField = require('web.AbstractField'); +var core = require('web.core'); +var registry = require('web.field_registry'); + +var _t = core._t; + +var AccountAssetReversedWidget = AbstractField.extend({ + noLabel: true, + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + /** + * @override + */ + isSet: function () { + return true; // it should always be displayed, whatever its value + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @override + * @private + */ + _render: function () { + if (this.recordData.reversal_move_id.res_ids.length) { + var $icon = $('', { + title: _t('This move has been reversed') + }).addClass('fa fa-exclamation-circle') + this.$el.html($icon); + } + }, + +}); + +registry.add("deprec_lines_reversed", AccountAssetReversedWidget); + +}); diff --git a/odex25_accounting/odex25_account_asset/static/src/scss/account_asset.scss b/odex25_accounting/odex25_account_asset/static/src/scss/account_asset.scss new file mode 100644 index 000000000..07b694160 --- /dev/null +++ b/odex25_accounting/odex25_account_asset/static/src/scss/account_asset.scss @@ -0,0 +1,34 @@ +.o_radio_hide_bullet { + label::before { + display: none; + } + label { + @extend .btn; + @extend .btn-secondary; + } + .custom-control { + @extend .pl-0; + @extend .mr-0; + } + .o_field_radio.o_horizontal.o_field_widget { + margin-bottom: 1px; + } + label::after { + display: none; + } +} + +.o_account_reports_page.o_account_assets_report .o_account_reports_table .o_account_reports_header_hierarchy { + tr:not(:first-child) th { + border: none; + } + tr:first-child th:not(:first-child) { + border: 1px solid black; + } +} + +.o_account_reports_page.o_account_assets_report .o_account_reports_table { + tr:not(:hover) td:nth-child(2n+6), tr:not(:first-child) th:nth-child(2n+6) { + background-color: #F8F8F8; + } +} diff --git a/odex25_accounting/odex25_account_asset/tests/__init__.py b/odex25_accounting/odex25_account_asset/tests/__init__.py new file mode 100644 index 000000000..ca520745a --- /dev/null +++ b/odex25_accounting/odex25_account_asset/tests/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + + +from . import test_account_asset diff --git a/odex25_accounting/odex25_account_asset/tests/test_account_asset.py b/odex25_accounting/odex25_account_asset/tests/test_account_asset.py new file mode 100644 index 000000000..3562c8c96 --- /dev/null +++ b/odex25_accounting/odex25_account_asset/tests/test_account_asset.py @@ -0,0 +1,640 @@ +# -*- coding: utf-8 -*- + +import math +import time + +from datetime import date +from dateutil.relativedelta import relativedelta +from odoo import fields +from odoo.exceptions import UserError, MissingError +from odoo.tests.common import Form +from odoo.addons.odex25_account_reports.tests.common import TestAccountReportsCommon +from unittest.mock import patch + +original_context_today = fields.Date.context_today + +def today(): + # 31'st of december is a particular date because entries are configured + # to be autoposted on that day. The test values dont take it into account + # so we just mock the date and run the 31'st as if it was the 30'th + today = fields.Date.today() + if today.month == 12 and today.day == 31: + today += relativedelta(day=30) + return today + +def context_today(record, timestamp=None): + # Since 31'st december is faked as 30th december, we need to also fake + # context_today that is used in some account_move code (eg. auto_post) + if timestamp == None: + today = date.today() + if today.month == 12 and today.day == 31: + return today + relativedelta(day=30) + return original_context_today(record, timestamp) + + +class TestAccountAsset(TestAccountReportsCommon): + + @classmethod + @patch('odoo.fields.Date.today', return_value=today()) + @patch('odoo.fields.Date.context_today', context_today) + def setUpClass(cls, today_mock): + super(TestAccountAsset, cls).setUpClass() + today = fields.Date.today() + cls.truck = cls.env['account.asset'].create({ + 'account_asset_id': cls.company_data['default_account_expense'].id, + 'account_depreciation_id': cls.company_data['default_account_expense'].id, + 'account_depreciation_expense_id': cls.company_data['default_account_assets'].id, + 'journal_id': cls.company_data['default_journal_misc'].id, + 'asset_type': 'purchase', + 'name': 'truck', + 'acquisition_date': today + relativedelta(years=-6, month=1, day=1), + 'original_value': 10000, + 'salvage_value': 2500, + 'method_number': 10, + 'method_period': '12', + 'method': 'linear', + }) + cls.truck.validate() + cls.env['account.move']._autopost_draft_entries() + cls.assert_counterpart_account_id = cls.company_data['default_account_revenue'].id, + + def update_form_values(self, asset_form): + for i in range(len(asset_form.depreciation_move_ids)): + with asset_form.depreciation_move_ids.edit(i) as line_edit: + line_edit.asset_remaining_value + + @patch('odoo.fields.Date.today', return_value=today()) + @patch('odoo.fields.Date.context_today', context_today) + def test_00_account_asset(self, today_mock): + """Test the lifecycle of an asset""" + self.env.context = {**self.env.context, **{'asset_type': 'purchase'}} + + account_asset_model_fixedassets_test0 = self.env['account.asset'].create({ + 'account_depreciation_id': self.company_data['default_account_assets'].id, + 'account_depreciation_expense_id': self.company_data['default_account_expense'].id, + 'account_asset_id': self.company_data['default_account_assets'].id, + 'journal_id': self.company_data['default_journal_purchase'].id, + 'name': 'Hardware - 3 Years', + 'method_number': 3, + 'method_period': '12', + 'state': 'model', + }) + + account_asset_vehicles_test0 = self.env['account.asset'].create({ + 'salvage_value': 2000.0, + 'state': 'open', + 'method_period': '12', + 'method_number': 5, + 'name': "CEO's Car", + 'original_value': 12000.0, + 'model_id': account_asset_model_fixedassets_test0.id, + }) + + CEO_car = account_asset_vehicles_test0 + # In order to get the fields from the model, I need to trigger the onchange method. + CEO_car._onchange_model_id() + + # In order to test the process of Account Asset, I perform a action to confirm Account Asset. + CEO_car.validate() + + # I check Asset is now in Open state. + self.assertEqual(account_asset_vehicles_test0.state, 'open', + 'Asset should be in Open state') + + # I compute depreciation lines for asset of CEOs Car. + self.assertEqual(CEO_car.method_number, len(CEO_car.depreciation_move_ids), + 'Depreciation lines not created correctly') + + # Check that auto_post is set on the entries, in the future, and we cannot post them. + self.assertTrue(all(CEO_car.depreciation_move_ids.mapped('auto_post'))) + with self.assertRaises(UserError): + CEO_car.depreciation_move_ids.action_post() + + # I Check that After creating all the moves of depreciation lines the state "Running". + CEO_car.depreciation_move_ids.write({'auto_post': False}) + CEO_car.depreciation_move_ids.action_post() + self.assertEqual(account_asset_vehicles_test0.state, 'open', + 'State of asset should be runing') + + closing_invoice = self.env['account.move'].create({ + 'move_type': 'out_invoice', + 'invoice_line_ids': [(0, 0, { + 'debit': 100, + })] + }) + + with self.assertRaises(UserError, msg="You shouldn't be able to close if there are posted entries in the future"): + CEO_car.set_to_close(closing_invoice.invoice_line_ids) + + def test_01_account_asset(self): + """ Test if an an asset is created when an invoice is validated with an + item on an account for generating entries. + """ + self.env.context = {**self.env.context, **{'asset_type': 'purchase'}} + account_asset_model_sale_test0 = self.env['account.asset'].create({ + 'account_depreciation_id': self.company_data['default_account_assets'].id, + 'account_depreciation_expense_id': self.company_data['default_account_revenue'].id, + 'journal_id': self.company_data['default_journal_sale'].id, + 'name': 'Maintenance Contract - 3 Years', + 'method_number': 3, + 'method_period': '12', + 'prorata': True, + 'prorata_date': time.strftime('%Y-01-01'), + 'asset_type': 'sale', + 'state': 'model', + }) + + # The account needs a default model for the invoice to validate the revenue + self.company_data['default_account_assets'].create_asset = 'validate' + self.company_data['default_account_assets'].asset_model = account_asset_model_sale_test0 + + invoice = self.env['account.move'].with_context(asset_type='purchase').create({ + 'move_type': 'in_invoice', + 'partner_id': self.env['res.partner'].create({'name': 'Res Partner 12'}).id, + 'invoice_line_ids': [(0, 0, { + 'name': 'Insurance claim', + 'account_id': self.company_data['default_account_assets'].id, + 'price_unit': 450, + 'quantity': 1, + })], + }) + invoice.action_post() + + recognition = invoice.asset_ids + self.assertEqual(len(recognition), 1, 'One and only one recognition should have been created from invoice.') + + # I confirm revenue recognition. + recognition.validate() + self.assertTrue(recognition.state == 'open', + 'Recognition should be in Open state') + first_invoice_line = invoice.invoice_line_ids[0] + self.assertEqual(recognition.original_value, first_invoice_line.price_subtotal, + 'Recognition value is not same as invoice line.') + + recognition.depreciation_move_ids.write({'auto_post': False}) + recognition.depreciation_move_ids.action_post() + + # I check data in move line and installment line. + first_installment_line = recognition.depreciation_move_ids.sorted(lambda r: r.id)[0] + self.assertAlmostEqual(first_installment_line.asset_remaining_value, recognition.original_value - first_installment_line.amount_total, + msg='Remaining value is incorrect.') + self.assertAlmostEqual(first_installment_line.asset_depreciated_value, first_installment_line.amount_total, + msg='Depreciated value is incorrect.') + + # I check next installment date. + last_installment_date = first_installment_line.date + installment_date = last_installment_date + relativedelta(months=+int(recognition.method_period)) + self.assertEqual(recognition.depreciation_move_ids.sorted(lambda r: r.id)[1].date, installment_date, + 'Installment date is incorrect.') + + @patch('odoo.fields.Date.today', return_value=today()) + @patch('odoo.fields.Date.context_today', context_today) + def test_asset_form(self, today_mock): + """Test the form view of assets""" + asset_form = Form(self.env['account.asset'].with_context(asset_type='purchase')) + asset_form.name = "Test Asset" + asset_form.original_value = 10000 + asset_form.account_depreciation_id = self.company_data['default_account_assets'] + asset_form.account_depreciation_expense_id = self.company_data['default_account_expense'] + asset_form.journal_id = self.company_data['default_journal_misc'] + asset = asset_form.save() + asset.validate() + + # Test that the depreciations are created upon validation of the asset according to the default values + self.assertEqual(len(asset.depreciation_move_ids), 5) + for move in asset.depreciation_move_ids: + self.assertEqual(move.amount_total, 2000) + + # Test that we cannot validate an asset with non zero remaining value of the last depreciation line + asset_form = Form(asset) + with self.assertRaises(UserError): + with self.cr.savepoint(): + with asset_form.depreciation_move_ids.edit(4) as line_edit: + line_edit.amount_total = 1000.0 + asset_form.save() + + # ... but we can with a zero remaining value on the last line. + asset_form = Form(asset) + with asset_form.depreciation_move_ids.edit(4) as line_edit: + line_edit.amount_total = 1000.0 + with asset_form.depreciation_move_ids.edit(3) as line_edit: + line_edit.amount_total = 3000.0 + self.update_form_values(asset_form) + asset_form.save() + + def test_asset_from_move_line_form(self): + """Test that the asset is correcly created from a move line""" + + move_ids = self.env['account.move'].create([{ + 'ref': 'line1', + 'line_ids': [ + (0, 0, { + 'account_id': self.company_data['default_account_expense'].id, + 'debit': 300, + 'name': 'Furniture', + }), + (0, 0, { + 'account_id': self.company_data['default_account_assets'].id, + 'credit': 300, + }), + ] + }, { + 'ref': 'line2', + 'line_ids': [ + (0, 0, { + 'account_id': self.company_data['default_account_expense'].id, + 'debit': 600, + 'name': 'Furniture too', + }), + (0, 0, { + 'account_id': self.company_data['default_account_assets'].id, + 'credit': 600, + }), + ] + }, + ]) + move_ids.action_post() + move_line_ids = move_ids.mapped('line_ids').filtered(lambda x: x.debit) + + asset = self.env['account.asset'].new({'original_move_line_ids': [(6, 0, move_line_ids.ids)]}) + asset_form = Form(self.env['account.asset'].with_context(default_original_move_line_ids=move_line_ids.ids, asset_type='purchase')) + asset_form._values['original_move_line_ids'] = [(6, 0, move_line_ids.ids)] + asset_form._perform_onchange(['original_move_line_ids']) + asset_form.account_depreciation_expense_id = self.company_data['default_account_expense'] + + asset = asset_form.save() + self.assertEqual(asset.value_residual, 900.0) + self.assertIn(asset.name, ['Furniture', 'Furniture too']) + self.assertEqual(asset.journal_id.type, 'general') + self.assertEqual(asset.asset_type, 'purchase') + self.assertEqual(asset.account_asset_id, self.company_data['default_account_expense']) + self.assertEqual(asset.account_depreciation_id, self.company_data['default_account_expense']) + self.assertEqual(asset.account_depreciation_expense_id, self.company_data['default_account_expense']) + + def test_asset_modify_depreciation(self): + """Test the modification of depreciation parameters""" + self.env['asset.modify'].create({ + 'asset_id': self.truck.id, + 'name': 'Test reason', + 'method_number': 10.0, + "account_asset_counterpart_id": self.assert_counterpart_account_id, + }).modify() + + # I check the proper depreciation lines created. + self.assertEqual(10, len(self.truck.depreciation_move_ids.filtered(lambda x: x.state == 'draft'))) + + @patch('odoo.fields.Date.today', return_value=today()) + @patch('odoo.fields.Date.context_today', context_today) + def test_asset_modify_value_00(self, today_mock): + """Test the values of the asset and value increase 'assets' after a + modification of residual and/or salvage values. + Increase the residual value, increase the salvage value""" + self.assertEqual(self.truck.value_residual, 3000) + self.assertEqual(self.truck.salvage_value, 2500) + + self.env['asset.modify'].create({ + 'name': 'New beautiful sticker :D', + 'asset_id': self.truck.id, + 'value_residual': 4000, + 'salvage_value': 3000, + "account_asset_counterpart_id": self.assert_counterpart_account_id, + }).modify() + self.assertEqual(self.truck.value_residual, 3000) + self.assertEqual(self.truck.salvage_value, 2500) + self.assertEqual(self.truck.children_ids.value_residual, 1000) + self.assertEqual(self.truck.children_ids.salvage_value, 500) + + @patch('odoo.fields.Date.today', return_value=today()) + def test_asset_modify_value_01(self, today_mock): + "Decrease the residual value, decrease the salvage value" + self.env['asset.modify'].create({ + 'name': "Accident :'(", + 'date': fields.Date.today(), + 'asset_id': self.truck.id, + 'value_residual': 1000, + 'salvage_value': 2000, + "account_asset_counterpart_id": self.assert_counterpart_account_id, + }).modify() + self.assertEqual(self.truck.value_residual, 1000) + self.assertEqual(self.truck.salvage_value, 2000) + self.assertEqual(self.truck.children_ids.value_residual, 0) + self.assertEqual(self.truck.children_ids.salvage_value, 0) + self.assertEqual(max(self.truck.depreciation_move_ids.filtered(lambda m: m.state == 'posted'), key=lambda m: m.date).amount_total, 2500) + + def test_asset_modify_value_02(self): + "Decrease the residual value, increase the salvage value; same book value" + self.env['asset.modify'].create({ + 'name': "Don't wanna depreciate all of it", + 'asset_id': self.truck.id, + 'value_residual': 1000, + 'salvage_value': 4500, + "account_asset_counterpart_id": self.assert_counterpart_account_id, + }).modify() + self.assertEqual(self.truck.value_residual, 1000) + self.assertEqual(self.truck.salvage_value, 4500) + self.assertEqual(self.truck.children_ids.value_residual, 0) + self.assertEqual(self.truck.children_ids.salvage_value, 0) + + def test_asset_modify_value_03(self): + "Decrease the residual value, increase the salvage value; increase of book value" + self.env['asset.modify'].create({ + 'name': "Some aliens did something to my truck", + 'asset_id': self.truck.id, + 'value_residual': 1000, + 'salvage_value': 6000, + "account_asset_counterpart_id": self.assert_counterpart_account_id, + }).modify() + self.assertEqual(self.truck.value_residual, 1000) + self.assertEqual(self.truck.salvage_value, 4500) + self.assertEqual(self.truck.children_ids.value_residual, 0) + self.assertEqual(self.truck.children_ids.salvage_value, 1500) + + @patch('odoo.fields.Date.today', return_value=today()) + @patch('odoo.fields.Date.context_today', context_today) + def test_asset_modify_value_04(self, today_mock): + "Increase the residual value, decrease the salvage value; increase of book value" + self.env['asset.modify'].create({ + 'name': 'GODZILA IS REAL!', + 'asset_id': self.truck.id, + 'value_residual': 4000, + 'salvage_value': 2000, + "account_asset_counterpart_id": self.assert_counterpart_account_id, + }).modify() + self.assertEqual(self.truck.value_residual, 3500) + self.assertEqual(self.truck.salvage_value, 2000) + self.assertEqual(self.truck.children_ids.value_residual, 500) + self.assertEqual(self.truck.children_ids.salvage_value, 0) + + @patch('odoo.fields.Date.today', return_value=today()) + @patch('odoo.fields.Date.context_today', context_today) + def test_asset_modify_report(self, today_mock): + """Test the asset value modification flows""" + # PY + - Final PY + - Final Bookvalue + # -6 0 10000 0 10000 0 750 0 750 9250 + # -5 10000 0 0 10000 750 750 0 1500 8500 + # -4 10000 0 0 10000 1500 750 0 2250 7750 + # -3 10000 0 0 10000 2250 750 0 3000 7000 + # -2 10000 0 0 10000 3000 750 0 3750 6250 + # -1 10000 0 0 10000 3750 750 0 4500 5500 + # 0 10000 0 0 10000 4500 750 0 5250 4750 <-- today + # 1 10000 0 0 10000 5250 750 0 6000 4000 + # 2 10000 0 0 10000 6000 750 0 6750 3250 + # 3 10000 0 0 10000 6750 750 0 7500 2500 + + today = fields.Date.today() + + report = self.env['account.assets.report'] + # TEST REPORT + # look at all period, with unposted entries + options = self._init_options(report, today + relativedelta(years=-6, month=1, day=1), today + relativedelta(years=+4, month=12, day=31)) + lines = report._get_lines({**options, **{'unfold_all': False, 'all_entries': True}}) + self.assertListEqual([ 0.0, 10000.0, 0.0, 10000.0, 0.0, 7500.0, 0.0, 7500.0, 2500.0], + [x['no_format_name'] for x in lines[0]['columns'][4:]]) + + # look at all period, without unposted entries + options = self._init_options(report, today + relativedelta(years=-6, month=1, day=1), today + relativedelta(years=+4, month=12, day=31)) + lines = report._get_lines({**options, **{'unfold_all': False, 'all_entries': False}}) + self.assertListEqual([ 0.0, 10000.0, 0.0, 10000.0, 0.0, 4500.0, 0.0, 4500.0, 5500.0], + [x['no_format_name'] for x in lines[0]['columns'][4:]]) + + # look only at this period + options = self._init_options(report, today + relativedelta(years=0, month=1, day=1), today + relativedelta(years=0, month=12, day=31)) + lines = report._get_lines({**options, **{'unfold_all': False, 'all_entries': True}}) + self.assertListEqual([10000.0, 0.0, 0.0, 10000.0, 4500.0, 750.0, 0.0, 5250.0, 4750.0], + [x['no_format_name'] for x in lines[0]['columns'][4:]]) + + # test value increase + # PY + - Final PY + - Final Bookvalue + # -6 0 10000 0 10000 750 0 750 9250 + # -5 10000 0 0 10000 750 750 0 1500 8500 + # -4 10000 0 0 10000 1500 750 0 2250 7750 + # -3 10000 0 0 10000 2250 750 0 3000 7000 + # -2 10000 0 0 10000 3000 750 0 3750 6250 + # -1 10000 0 0 10000 3750 750 0 4500 5500 + # 0 10000 1500 0 11500 4500 1000 0 5500 6000 <-- today + # 1 11500 0 0 11500 5500 1000 0 6500 5000 + # 2 11500 0 0 11500 6500 1000 0 7500 4000 + # 3 11500 0 0 11500 7500 1000 0 8500 3000 + self.assertEqual(self.truck.value_residual, 3000) + self.assertEqual(self.truck.salvage_value, 2500) + self.env['asset.modify'].create({ + 'name': 'New beautiful sticker :D', + 'asset_id': self.truck.id, + 'value_residual': 4000, + 'salvage_value': 3000, + "account_asset_counterpart_id": self.assert_counterpart_account_id, + }).modify() + self.assertEqual(self.truck.value_residual + sum(self.truck.children_ids.mapped('value_residual')), 4000) + self.assertEqual(self.truck.salvage_value + sum(self.truck.children_ids.mapped('salvage_value')), 3000) + + # look at all period, with unposted entries + options = self._init_options(report, today + relativedelta(years=-6, month=1, day=1), today + relativedelta(years=+4, month=12, day=31)) + lines = report._get_lines({**options, **{'unfold_all': False, 'all_entries': True}}) + self.assertListEqual([ 0.0, 11500.0, 0.0, 11500.0, 0.0, 8500.0, 0.0, 8500.0, 3000.0], + [x['no_format_name'] for x in lines[0]['columns'][4:]]) + self.assertEqual('10.00 %', lines[0]['columns'][3]['name'], 'Depreciation Rate = 10%') + + # look only at this period + options = self._init_options(report, today + relativedelta(years=0, month=1, day=1), today + relativedelta(years=0, month=12, day=31)) + lines = report._get_lines({**options, **{'unfold_all': False, 'all_entries': True}}) + self.assertListEqual([10000.0, 1500.0, 0.0, 11500.0, 4500.0, 1000.0, 0.0, 5500.0, 6000.0], + [x['no_format_name'] for x in lines[0]['columns'][4:]]) + + # test value decrease + self.env['asset.modify'].create({ + 'name': "Huge scratch on beautiful sticker :'( It is ruined", + 'date': fields.Date.today(), + 'asset_id': self.truck.children_ids.id, + 'value_residual': 0, + 'salvage_value': 500, + "account_asset_counterpart_id": self.assert_counterpart_account_id, + }).modify() + self.env['asset.modify'].create({ + 'name': "Huge scratch on beautiful sticker :'( It went through...", + 'date': fields.Date.today(), + 'asset_id': self.truck.id, + 'value_residual': 1000, + 'salvage_value': 2500, + "account_asset_counterpart_id": self.assert_counterpart_account_id, + }).modify() + self.assertEqual(self.truck.value_residual + sum(self.truck.children_ids.mapped('value_residual')), 1000) + self.assertEqual(self.truck.salvage_value + sum(self.truck.children_ids.mapped('salvage_value')), 3000) + + # look at all period, with unposted entries + options = self._init_options(report, today + relativedelta(years=-6, month=1, day=1), today + relativedelta(years=+4, month=12, day=31)) + lines = report._get_lines({**options, **{'unfold_all': False, 'all_entries': True}}) + self.assertListEqual([ 0.0, 11500.0, 0.0, 11500.0, 0.0, 8500.0, 0.0, 8500.0, 3000.0], + [x['no_format_name'] for x in lines[0]['columns'][4:]]) + + # look only at this period + options = self._init_options(report, today + relativedelta(years=0, month=1, day=1), today + relativedelta(years=0, month=12, day=31)) + lines = report._get_lines({**options, **{'unfold_all': False, 'all_entries': True}}) + self.assertListEqual([10000.0, 1500.0, 0.0, 11500.0, 4500.0, 3250.0, 0.0, 7750.0, 3750.0], + [x['no_format_name'] for x in lines[0]['columns'][4:]]) + + def test_asset_reverse_depreciation(self): + """Test the reversal of a depreciation move""" + + self.assertEqual(sum(self.truck.depreciation_move_ids.filtered(lambda m: m.state == 'posted').mapped('amount_total')), 4500) + self.assertEqual(sum(self.truck.depreciation_move_ids.filtered(lambda m: m.state == 'draft').mapped('amount_total')), 3000) + self.assertEqual(max(self.truck.depreciation_move_ids.filtered(lambda m: m.state == 'posted'), key=lambda m: m.date).asset_remaining_value, 3000) + + move_to_reverse = self.truck.depreciation_move_ids.filtered(lambda m: m.state == 'posted').sorted(lambda m: m.date)[-1] + move_to_reverse._reverse_moves() + + # Check that we removed the depreciation in the table for the reversed move + max_date_posted_before = max(self.truck.depreciation_move_ids.filtered(lambda m: m.state == 'posted' and m.date < move_to_reverse.date), key=lambda m: m.date) + self.assertEqual(move_to_reverse.asset_remaining_value, max_date_posted_before.asset_remaining_value) + self.assertEqual(move_to_reverse.asset_depreciated_value, max_date_posted_before.asset_depreciated_value) + + # Check that the depreciation has been reported on the next move + min_date_draft = min(self.truck.depreciation_move_ids.filtered(lambda m: m.state == 'draft' and m.date > move_to_reverse.date), key=lambda m: m.date) + self.assertEqual(move_to_reverse.asset_remaining_value - min_date_draft.amount_total, min_date_draft.asset_remaining_value) + self.assertEqual(move_to_reverse.asset_depreciated_value + min_date_draft.amount_total, min_date_draft.asset_depreciated_value) + + # The amount is still there, it only has been reversed. But it has been added on the next draft move to complete the depreciation table + self.assertEqual(sum(self.truck.depreciation_move_ids.filtered(lambda m: m.state == 'posted').mapped('amount_total')), 4500) + self.assertEqual(sum(self.truck.depreciation_move_ids.filtered(lambda m: m.state == 'draft').mapped('amount_total')), 3750) + + # Check that the table shows fully depreciated at the end + self.assertEqual(max(self.truck.depreciation_move_ids, key=lambda m: m.date).asset_remaining_value, 0) + self.assertEqual(max(self.truck.depreciation_move_ids, key=lambda m: m.date).asset_depreciated_value, 7500) + + def test_asset_reverse_original_move(self): + """Test the reversal of a move that generated an asset""" + + move_id = self.env['account.move'].create({ + 'ref': 'line1', + 'line_ids': [ + (0, 0, { + 'account_id': self.company_data['default_account_expense'].id, + 'debit': 300, + 'name': 'Furniture', + }), + (0, 0, { + 'account_id': self.company_data['default_account_assets'].id, + 'credit': 300, + }), + ] + }) + move_id.action_post() + move_line_id = move_id.mapped('line_ids').filtered(lambda x: x.debit) + + asset_form = Form(self.env['account.asset'].with_context(asset_type='purchase')) + asset_form._values['original_move_line_ids'] = [(6, 0, move_line_id.ids)] + asset_form._perform_onchange(['original_move_line_ids']) + asset_form.account_depreciation_expense_id = self.company_data['default_account_expense'] + + asset = asset_form.save() + + self.assertTrue(asset.name, 'An asset should have been created') + move_id._reverse_moves() + with self.assertRaises(MissingError, msg='The asset should have been deleted'): + asset.name + + def test_asset_multiple_assets_from_one_move_line_00(self): + """ Test the creation of a as many assets as the value of + the quantity property of a move line. """ + + account = self.env['account.account'].create({ + "name": "test account", + "code": "TEST", + "user_type_id": self.env.ref('account.data_account_type_non_current_assets').id, + "create_asset": "draft", + "asset_type": "purchase", + "multiple_assets_per_line": True, + }) + move = self.env['account.move'].create({ + "partner_id": self.env['res.partner'].create({'name': 'Johny'}).id, + "ref": "line1", + "move_type": "in_invoice", + "line_ids": [ + (0, 0, { + "account_id": account.id, + "debit": 800.0, + "name": "stuff", + "quantity": 2, + "product_uom_id": self.env.ref('uom.product_uom_unit').id, + }), + (0, 0, { + 'account_id': self.company_data['default_account_assets'].id, + 'credit': 800.0, + }), + ] + }) + move.action_post() + assets = move.asset_ids + assets = sorted(assets, key=lambda i: i['original_value'], reverse=True) + self.assertEqual(len(assets), 2, '3 assets should have been created') + self.assertEqual(assets[0].original_value, 400.0) + self.assertEqual(assets[1].original_value, 400.0) + + def test_asset_multiple_assets_from_one_move_line_01(self): + """ Test the creation of a as many assets as the value of + the quantity property of a move line. """ + + account = self.env['account.account'].create({ + "name": "test account", + "code": "TEST", + "user_type_id": self.env.ref('account.data_account_type_non_current_assets').id, + "create_asset": "draft", + "asset_type": "purchase", + "multiple_assets_per_line": True, + }) + move = self.env['account.move'].create({ + "partner_id": self.env['res.partner'].create({'name': 'Johny'}).id, + "ref": "line1", + "move_type": "in_invoice", + "line_ids": [ + (0, 0, { + "account_id": account.id, + "debit": 1000.0, + "name": "stuff", + "quantity": 3.0, + "product_uom_id": self.env.ref('uom.product_uom_categ_unit').id, + }), + (0, 0, { + 'account_id': self.company_data['default_account_assets'].id, + 'credit': 1000.0, + }), + ] + }) + move.action_post() + self.assertEqual(sum(asset.original_value for asset in move.asset_ids), move.line_ids[0].debit) + + def test_asset_credit_note(self): + """Test the generated entries created from an in_refund invoice with deferred expense.""" + account_asset_model_fixedassets_test0 = self.env['account.asset'].create({ + 'account_depreciation_id': self.company_data['default_account_assets'].id, + 'account_depreciation_expense_id': self.company_data['default_account_expense'].id, + 'account_asset_id': self.company_data['default_account_assets'].id, + 'journal_id': self.company_data['default_journal_purchase'].id, + 'name': 'Hardware - 3 Years', + 'method_number': 3, + 'method_period': '12', + 'state': 'model', + }) + + self.company_data['default_account_assets'].create_asset = "validate" + self.company_data['default_account_assets'].asset_model = account_asset_model_fixedassets_test0 + + invoice = self.env['account.move'].create({ + 'move_type': 'in_refund', + 'partner_id': self.ref("base.res_partner_12"), + 'invoice_line_ids': [(0, 0, { + 'name': 'Refund Insurance claim', + 'account_id': self.company_data['default_account_assets'].id, + 'price_unit': 450, + 'quantity': 1, + })], + }) + invoice.action_post() + depreciation_lines = self.env['account.move.line'].search([ + ('account_id', '=', account_asset_model_fixedassets_test0.account_depreciation_id.id), + ('move_id.asset_id', '=', invoice.asset_ids.id), + ('debit', '=', 150), + ]) + self.assertEqual( + len(depreciation_lines), 3, + 'Three entries with a debit of 150 must be created on the Deferred Expense Account' + ) diff --git a/odex25_accounting/odex25_account_asset/views/account_account_views.xml b/odex25_accounting/odex25_account_asset/views/account_account_views.xml new file mode 100644 index 000000000..8251b22bc --- /dev/null +++ b/odex25_accounting/odex25_account_asset/views/account_account_views.xml @@ -0,0 +1,57 @@ + + + + account.move.line.tree.grouped.inherit + account.move.line + + extension + + + + +
    + +
    +
    + +
    +
    +
    +
    + + + + + Set manually the original values or + + +
    + + + + + account.move.line.form + account.move.line + + + + + + + + + + Create Asset + + + + code + +if records: + action = records.turn_as_asset() + + + diff --git a/odex25_accounting/odex25_account_asset/wizard/__init__.py b/odex25_accounting/odex25_account_asset/wizard/__init__.py new file mode 100644 index 000000000..836778be8 --- /dev/null +++ b/odex25_accounting/odex25_account_asset/wizard/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + + +from . import asset_modify +from . import asset_pause +from . import asset_sell diff --git a/odex25_accounting/odex25_account_asset/wizard/asset_modify.py b/odex25_accounting/odex25_account_asset/wizard/asset_modify.py new file mode 100644 index 000000000..3ce61ab67 --- /dev/null +++ b/odex25_accounting/odex25_account_asset/wizard/asset_modify.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- + + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError + + +class AssetModify(models.TransientModel): + _name = 'asset.modify' + _description = 'Modify Asset' + + name = fields.Text(string='Reason') + asset_id = fields.Many2one(string="Asset", comodel_name='account.asset', required=True, help="The asset to be modified by this wizard", ondelete="cascade") + method_number = fields.Integer(string='Number of Depreciations', required=True) + method_period = fields.Selection([('1', 'Months'), ('12', 'Years')], string='Number of Months in a Period', help="The amount of time between two depreciations") + value_residual = fields.Monetary(string="Depreciable Amount", help="New residual amount for the asset") + salvage_value = fields.Monetary(string="Not Depreciable Amount", help="New salvage amount for the asset") + currency_id = fields.Many2one(related='asset_id.currency_id') + date = fields.Date(default=fields.Date.today(), string='Date') + need_date = fields.Boolean(compute="_compute_need_date") + gain_value = fields.Boolean(compute="_compute_gain_value", help="Technical field to know if we should display the fields for the creation of gross increase asset") + account_asset_id = fields.Many2one('account.account', string="Asset Gross Increase Account") + account_asset_counterpart_id = fields.Many2one('account.account') + account_depreciation_id = fields.Many2one('account.account') + account_depreciation_expense_id = fields.Many2one('account.account') + + @api.model + def create(self, vals): + if 'asset_id' in vals: + asset = self.env['account.asset'].browse(vals['asset_id']) + if asset.depreciation_move_ids.filtered(lambda m: m.state == 'posted' and not m.reversal_move_id and m.date > fields.Date.today()): + raise UserError(_('Reverse the depreciation entries posted in the future in order to modify the depreciation')) + if 'method_number' not in vals: + vals.update({'method_number': len(asset.depreciation_move_ids.filtered(lambda move: move.state != 'posted')) or 1}) + if 'method_period' not in vals: + vals.update({'method_period': asset.method_period}) + if 'salvage_value' not in vals: + vals.update({'salvage_value': asset.salvage_value}) + if 'value_residual' not in vals: + vals.update({'value_residual': asset.value_residual}) + if 'account_asset_id' not in vals: + vals.update({'account_asset_id': asset.account_asset_id.id}) + if 'account_depreciation_id' not in vals: + vals.update({'account_depreciation_id': asset.account_depreciation_id.id}) + if 'account_depreciation_expense_id' not in vals: + vals.update({'account_depreciation_expense_id': asset.account_depreciation_expense_id.id}) + return super(AssetModify, self).create(vals) + + def modify(self): + """ Modifies the duration of asset for calculating depreciation + and maintains the history of old values, in the chatter. + """ + old_values = { + 'method_number': self.asset_id.method_number, + 'method_period': self.asset_id.method_period, + 'value_residual': self.asset_id.value_residual, + 'salvage_value': self.asset_id.salvage_value, + } + + asset_vals = { + 'method_number': self.method_number, + 'method_period': self.method_period, + 'value_residual': self.value_residual, + 'salvage_value': self.salvage_value, + } + if self.need_date: + asset_vals.update({ + 'prorata_date': self.date, + }) + if self.env.context.get('resume_after_pause'): + asset_vals.update({'state': 'open'}) + self.asset_id.message_post(body=_("Asset unpaused")) + else: + self = self.with_context(ignore_prorata=True) + + current_asset_book = self.asset_id.value_residual + self.asset_id.salvage_value + after_asset_book = self.value_residual + self.salvage_value + increase = after_asset_book - current_asset_book + + new_residual = min(current_asset_book - min(self.salvage_value, self.asset_id.salvage_value), self.value_residual) + new_salvage = min(current_asset_book - new_residual, self.salvage_value) + residual_increase = max(0, self.value_residual - new_residual) + salvage_increase = max(0, self.salvage_value - new_salvage) + + if residual_increase or salvage_increase: + move = self.env['account.move'].create({ + 'journal_id': self.asset_id.journal_id.id, + 'date': fields.Date.today(), + 'line_ids': [ + (0, 0, { + 'account_id': self.account_asset_id.id, + 'debit': residual_increase + salvage_increase, + 'credit': 0, + 'name': _('Value increase for: %(asset)s', asset=self.asset_id.name), + }), + (0, 0, { + 'account_id': self.account_asset_counterpart_id.id, + 'debit': 0, + 'credit': residual_increase + salvage_increase, + 'name': _('Value increase for: %(asset)s', asset=self.asset_id.name), + }), + ], + }) + move._post() + asset_increase = self.env['account.asset'].create({ + 'name': self.asset_id.name + ': ' + self.name, + 'currency_id': self.asset_id.currency_id.id, + 'company_id': self.asset_id.company_id.id, + 'asset_type': self.asset_id.asset_type, + 'method': self.asset_id.method, + 'method_number': self.method_number, + 'method_period': self.method_period, + 'acquisition_date': self.date, + 'value_residual': residual_increase, + 'salvage_value': salvage_increase, + 'original_value': residual_increase + salvage_increase, + 'account_asset_id': self.account_asset_id.id, + 'account_depreciation_id': self.account_depreciation_id.id, + 'account_depreciation_expense_id': self.account_depreciation_expense_id.id, + 'journal_id': self.asset_id.journal_id.id, + 'parent_id': self.asset_id.id, + 'original_move_line_ids': [(6, 0, move.line_ids.filtered(lambda r: r.account_id == self.account_asset_id).ids)], + }) + asset_increase.validate() + + subject = _('A gross increase has been created') + ': %s' % (asset_increase.id, asset_increase.name) + self.asset_id.message_post(body=subject) + if increase < 0: + if self.env['account.move'].search([('asset_id', '=', self.asset_id.id), ('state', '=', 'draft'), ('date', '<=', self.date)]): + raise UserError('There are unposted depreciations prior to the selected operation date, please deal with them first.') + move = self.env['account.move'].create(self.env['account.move']._prepare_move_for_asset_depreciation({ + 'amount': -increase, + 'asset_id': self.asset_id, + 'move_ref': _('Value decrease for: %(asset)s', asset=self.asset_id.name), + 'date': self.date, + 'asset_remaining_value': 0, + 'asset_depreciated_value': 0, + 'asset_value_change': True, + }))._post() + + asset_vals.update({ + 'value_residual': new_residual, + 'salvage_value': new_salvage, + }) + self.asset_id.write(asset_vals) + self.asset_id.compute_depreciation_board() + self.asset_id.children_ids.write({ + 'method_number': asset_vals['method_number'], + 'method_period': asset_vals['method_period'], + }) + for child in self.asset_id.children_ids: + child.compute_depreciation_board() + tracked_fields = self.env['account.asset'].fields_get(old_values.keys()) + changes, tracking_value_ids = self.asset_id._message_track(tracked_fields, old_values) + if changes: + self.asset_id.message_post(body=_('Depreciation board modified') + '
    ' + self.name, tracking_value_ids=tracking_value_ids) + return {'type': 'ir.actions.act_window_close'} + + @api.depends('asset_id', 'value_residual', 'salvage_value') + def _compute_need_date(self): + for record in self: + value_changed = record.value_residual + record.salvage_value != record.asset_id.value_residual + record.asset_id.salvage_value + record.need_date = (self.env.context.get('resume_after_pause') and record.asset_id.prorata) or value_changed + + @api.depends('asset_id', 'value_residual', 'salvage_value') + def _compute_gain_value(self): + for record in self: + record.gain_value = record.value_residual + record.salvage_value > record.asset_id.value_residual + record.asset_id.salvage_value diff --git a/odex25_accounting/odex25_account_asset/wizard/asset_modify_views.xml b/odex25_accounting/odex25_account_asset/wizard/asset_modify_views.xml new file mode 100644 index 000000000..b6f4190c1 --- /dev/null +++ b/odex25_accounting/odex25_account_asset/wizard/asset_modify_views.xml @@ -0,0 +1,41 @@ + + + + + wizard.asset.modify.form + asset.modify + +
    + + + + + + + + + + + + + + + + + +
    +
    + +
    +
    + +
    diff --git a/odex25_accounting/odex25_account_asset/wizard/asset_pause.py b/odex25_accounting/odex25_account_asset/wizard/asset_pause.py new file mode 100644 index 000000000..489c9d1b9 --- /dev/null +++ b/odex25_accounting/odex25_account_asset/wizard/asset_pause.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- + + +from odoo import api, fields, models, _ + + +class AssetPause(models.TransientModel): + _name = 'account.asset.pause' + _description = 'Pause Asset' + + date = fields.Date(string='Pause date', required=True, default=fields.Date.today()) + asset_id = fields.Many2one('account.asset', required=True) + + def do_action(self): + for record in self: + record.asset_id.pause(pause_date=record.date) diff --git a/odex25_accounting/odex25_account_asset/wizard/asset_pause_views.xml b/odex25_accounting/odex25_account_asset/wizard/asset_pause_views.xml new file mode 100644 index 000000000..9d44f7818 --- /dev/null +++ b/odex25_accounting/odex25_account_asset/wizard/asset_pause_views.xml @@ -0,0 +1,22 @@ + + + + + wizard.asset.pause.form + account.asset.pause + +
    + + + + + +
    +
    +
    +
    +
    + +
    diff --git a/odex25_accounting/odex25_account_asset/wizard/asset_sell.py b/odex25_accounting/odex25_account_asset/wizard/asset_sell.py new file mode 100644 index 000000000..403fa164c --- /dev/null +++ b/odex25_accounting/odex25_account_asset/wizard/asset_sell.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- + + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError + + +class AssetSell(models.TransientModel): + _name = 'account.asset.sell' + _description = 'Sell Asset' + + asset_id = fields.Many2one('account.asset', required=True) + company_id = fields.Many2one('res.company', default=lambda self: self.env.company) + + action = fields.Selection([('sell', 'Sell'), ('dispose', 'Dispose')], required=True, default='sell') + invoice_id = fields.Many2one('account.move', string="Customer Invoice", help="The disposal invoice is needed in order to generate the closing journal entry.", domain="[('move_type', '=', 'out_invoice'), ('state', '=', 'posted')]") + invoice_line_id = fields.Many2one('account.move.line', help="There are multiple lines that could be the related to this asset", domain="[('move_id', '=', invoice_id), ('exclude_from_invoice_tab', '=', False)]") + select_invoice_line_id = fields.Boolean(compute="_compute_select_invoice_line_id") + gain_account_id = fields.Many2one('account.account', domain="[('deprecated', '=', False), ('company_id', '=', company_id)]", related='company_id.gain_account_id', help="Account used to write the journal item in case of gain", readonly=False) + loss_account_id = fields.Many2one('account.account', domain="[('deprecated', '=', False), ('company_id', '=', company_id)]", related='company_id.loss_account_id', help="Account used to write the journal item in case of loss", readonly=False) + + gain_or_loss = fields.Selection([('gain', 'Gain'), ('loss', 'Loss'), ('no', 'No')], compute='_compute_gain_or_loss', help="Technical field to know is there was a gain or a loss in the selling of the asset") + + @api.depends('invoice_id', 'action') + def _compute_select_invoice_line_id(self): + for record in self: + record.select_invoice_line_id = record.action == 'sell' and len(record.invoice_id.invoice_line_ids) > 1 + + @api.onchange('action') + def _onchange_action(self): + if self.action == 'sell' and self.asset_id.children_ids.filtered(lambda a: a.state in ('draft', 'open') or a.value_residual > 0): + raise UserError(_("You cannot automate the journal entry for an asset that has a running gross increase. Please use 'Dispose' on the increase(s).")) + + @api.depends('asset_id', 'invoice_id', 'invoice_line_id') + def _compute_gain_or_loss(self): + for record in self: + line = record.invoice_line_id or len(record.invoice_id.invoice_line_ids) == 1 and record.invoice_id.invoice_line_ids or self.env['account.move.line'] + if record.asset_id.value_residual < abs(line.balance): + record.gain_or_loss = 'gain' + elif record.asset_id.value_residual > abs(line.balance): + record.gain_or_loss = 'loss' + else: + record.gain_or_loss = 'no' + + def do_action(self): + self.ensure_one() + invoice_line = self.env['account.move.line'] if self.action == 'dispose' else self.invoice_line_id or self.invoice_id.invoice_line_ids + return self.asset_id.set_to_close(invoice_line_id=invoice_line, date=invoice_line.move_id.invoice_date) diff --git a/odex25_accounting/odex25_account_asset/wizard/asset_sell_views.xml b/odex25_accounting/odex25_account_asset/wizard/asset_sell_views.xml new file mode 100644 index 000000000..60bf9de84 --- /dev/null +++ b/odex25_accounting/odex25_account_asset/wizard/asset_sell_views.xml @@ -0,0 +1,32 @@ + + + + + wizard.asset.sell.form + account.asset.sell + +
    + + + + + + + + + + + + + + +
    +
    + +
    +
    + +
    diff --git a/odex25_accounting/odex25_account_auto_transfer/__init__.py b/odex25_accounting/odex25_account_auto_transfer/__init__.py new file mode 100644 index 000000000..cde864bae --- /dev/null +++ b/odex25_accounting/odex25_account_auto_transfer/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import models diff --git a/odex25_accounting/odex25_account_auto_transfer/__manifest__.py b/odex25_accounting/odex25_account_auto_transfer/__manifest__.py new file mode 100644 index 000000000..5ec6ca6b2 --- /dev/null +++ b/odex25_accounting/odex25_account_auto_transfer/__manifest__.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- + +{ + 'name': 'Account Automatic Transfers', + 'depends': ['odex25_account_accountant'], + 'description': """ +Account Automatic Transfers +=========================== +Manage automatic transfers between your accounts. + """, + 'category': 'Odex25-Accounting/Odex25-Accounting', + 'author': "Expert Co. Ltd.", + 'website': "http://www.exp-sa.com", + 'data': [ + 'security/ir.model.access.csv', + 'data/cron.xml', + 'views/transfer_model_views.xml', + ], + 'application': False, + 'auto_install': True +} diff --git a/odex25_accounting/odex25_account_auto_transfer/data/cron.xml b/odex25_accounting/odex25_account_auto_transfer/data/cron.xml new file mode 100644 index 000000000..09510a28a --- /dev/null +++ b/odex25_accounting/odex25_account_auto_transfer/data/cron.xml @@ -0,0 +1,11 @@ + + + Account automatic transfers : Perform transfers + + code + model.action_cron_auto_transfer() + 1 + days + -1 + + diff --git a/odex25_accounting/odex25_account_auto_transfer/i18n/ar.po b/odex25_accounting/odex25_account_auto_transfer/i18n/ar.po new file mode 100644 index 000000000..773b35a07 --- /dev/null +++ b/odex25_accounting/odex25_account_auto_transfer/i18n/ar.po @@ -0,0 +1,404 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * odex25_account_auto_transfer +# +# Translators: +# Sherif Abd Ekmoniem , 2020 +# Mustafa Rawi , 2020 +# amrnegm , 2020 +# Martin Trigaux, 2020 +# jahzar , 2020 +# Ali zuaby , 2020 +# Osoul , 2020 +# Osama Ahmaro , 2020 +# Yazeed Dandashi , 2020 +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server saas~13.5+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-09-01 07:39+0000\n" +"PO-Revision-Date: 2020-09-07 08:17+0000\n" +"Last-Translator: Yazeed Dandashi , 2020\n" +"Language-Team: Arabic (https://www.transifex.com/odoo/teams/41243/ar/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: ar\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" + +#. module: odex25_account_auto_transfer +#: model_terms:ir.ui.view,arch_db:odex25_account_auto_transfer.view_transfer_model_form +msgid " to " +msgstr "" + +#. module: odex25_account_auto_transfer +#: model:ir.model,name:odex25_account_auto_transfer.model_account_transfer_model +msgid "Account Transfer Model" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model:ir.model,name:odex25_account_auto_transfer.model_account_transfer_model_line +msgid "Account Transfer Model Line" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model:ir.actions.server,name:odex25_account_auto_transfer.ir_cron_auto_transfer_ir_actions_server +#: model:ir.cron,cron_name:odex25_account_auto_transfer.ir_cron_auto_transfer +#: model:ir.cron,name:odex25_account_auto_transfer.ir_cron_auto_transfer +msgid "Account automatic transfers : Perform transfers" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model_terms:ir.ui.view,arch_db:odex25_account_auto_transfer.view_transfer_model_form +msgid "Activate" +msgstr "تفعيل" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,help:odex25_account_auto_transfer.field_account_transfer_model_line__analytic_account_ids +msgid "" +"Adds a condition to only transfer the sum of the lines from the origin " +"accounts that match these analytic accounts to the destination account" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,help:odex25_account_auto_transfer.field_account_transfer_model_line__partner_ids +msgid "" +"Adds a condition to only transfer the sum of the lines from the origin " +"accounts that match these partners to the destination account" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model_line__analytic_account_ids +msgid "Analytic Filter" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model_terms:ir.ui.view,arch_db:odex25_account_auto_transfer.view_transfer_model_form +msgid "Automated Transfer" +msgstr "" + +#. module: odex25_account_auto_transfer +#: code:addons/odex25_account_auto_transfer/models/transfer_model.py:0 +#, python-format +msgid "Automatic Transfer (%s%% from account %s)" +msgstr "" + +#. module: odex25_account_auto_transfer +#: code:addons/odex25_account_auto_transfer/models/transfer_model.py:0 +#, python-format +msgid "Automatic Transfer (-%s%%)" +msgstr "" + +#. module: odex25_account_auto_transfer +#: code:addons/odex25_account_auto_transfer/models/transfer_model.py:0 +#, python-format +msgid "" +"Automatic Transfer (entries with analytic account(s): %s and partner(s): %s)" +msgstr "" + +#. module: odex25_account_auto_transfer +#: code:addons/odex25_account_auto_transfer/models/transfer_model.py:0 +#, python-format +msgid "Automatic Transfer (entries with analytic account(s): %s)" +msgstr "" + +#. module: odex25_account_auto_transfer +#: code:addons/odex25_account_auto_transfer/models/transfer_model.py:0 +#, python-format +msgid "Automatic Transfer (entries with partner(s): %s)" +msgstr "" + +#. module: odex25_account_auto_transfer +#: code:addons/odex25_account_auto_transfer/models/transfer_model.py:0 +#, python-format +msgid "" +"Automatic Transfer (from account %s with analytic account(s): %s and " +"partner(s): %s)" +msgstr "" + +#. module: odex25_account_auto_transfer +#: code:addons/odex25_account_auto_transfer/models/transfer_model.py:0 +#, python-format +msgid "Automatic Transfer (from account %s with analytic account(s): %s)" +msgstr "" + +#. module: odex25_account_auto_transfer +#: code:addons/odex25_account_auto_transfer/models/transfer_model.py:0 +#, python-format +msgid "Automatic Transfer (from account %s with partner(s): %s)" +msgstr "" + +#. module: odex25_account_auto_transfer +#: code:addons/odex25_account_auto_transfer/models/transfer_model.py:0 +#, python-format +msgid "Automatic Transfer (to account %s)" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model:ir.actions.act_window,name:odex25_account_auto_transfer.transfer_model_action +#: model:ir.ui.menu,name:odex25_account_auto_transfer.menu_auto_transfer +msgid "Automatic Transfers" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model__company_id +msgid "Company" +msgstr "شركة" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,help:odex25_account_auto_transfer.field_account_transfer_model__company_id +msgid "Company related to this journal" +msgstr "المؤسسة المرتبطة بدفتر اليومية هذا" + +#. module: odex25_account_auto_transfer +#: model_terms:ir.ui.view,arch_db:odex25_account_auto_transfer.view_transfer_model_form +msgid "Compute Transfer" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model__create_uid +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model_line__create_uid +msgid "Created by" +msgstr "أنشئ بواسطة" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model__create_date +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model_line__create_date +msgid "Created on" +msgstr "أنشئ في" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model_line__account_id +msgid "Destination Account" +msgstr "حساب الوجهة" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model__line_ids +msgid "Destination Accounts" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model__journal_id +msgid "Destination Journal" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model_terms:ir.ui.view,arch_db:odex25_account_auto_transfer.view_transfer_model_form +msgid "Disable" +msgstr "تعطيل" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields.selection,name:odex25_account_auto_transfer.selection__account_transfer_model__state__disabled +msgid "Disabled" +msgstr "معطل" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_move__display_name +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model__display_name +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model_line__display_name +msgid "Display Name" +msgstr "الاسم المعروض" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model__frequency +msgid "Frequency" +msgstr "معدل" + +#. module: odex25_account_auto_transfer +#: model:ir.actions.act_window,name:odex25_account_auto_transfer.generated_transfers_action +msgid "Generated Entries" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model__move_ids +msgid "Generated Moves" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_move__id +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model__id +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model_line__id +msgid "ID" +msgstr "المُعرف" + +#. module: odex25_account_auto_transfer +#: model_terms:ir.ui.view,arch_db:odex25_account_auto_transfer.view_transfer_model_form +msgid "Journal" +msgstr "دفتر اليومية" + +#. module: odex25_account_auto_transfer +#: model:ir.model,name:odex25_account_auto_transfer.model_account_move +msgid "Journal Entry" +msgstr "قيد اليومية" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_move____last_update +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model____last_update +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model_line____last_update +msgid "Last Modified on" +msgstr "آخر تعديل في" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model__write_uid +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model_line__write_uid +msgid "Last Updated by" +msgstr "آخر تحديث بواسطة" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model__write_date +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model_line__write_date +msgid "Last Updated on" +msgstr "آخر تحديث في" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields.selection,name:odex25_account_auto_transfer.selection__account_transfer_model__frequency__month +msgid "Monthly" +msgstr "شهرياً" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model__move_ids_count +msgid "Move Ids Count" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model_terms:ir.ui.view,arch_db:odex25_account_auto_transfer.view_transfer_model_form +msgid "Move Model" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model_terms:ir.ui.view,arch_db:odex25_account_auto_transfer.view_transfer_model_tree +msgid "Move Models" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model__name +#: model_terms:ir.ui.view,arch_db:odex25_account_auto_transfer.view_transfer_model_form +msgid "Name" +msgstr "الاسم" + +#. module: odex25_account_auto_transfer +#: model:ir.model.constraint,message:odex25_account_auto_transfer.constraint_account_transfer_model_line_unique_account_by_transfer_model +msgid "Only one account occurrence by transfer model" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model__account_ids +#: model_terms:ir.ui.view,arch_db:odex25_account_auto_transfer.view_transfer_model_form +msgid "Origin Accounts" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_bank_statement_line__transfer_model_id +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_move__transfer_model_id +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_payment__transfer_model_id +msgid "Originating Model" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model_line__partner_ids +msgid "Partner Filter" +msgstr "فلتر الشريك" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model_line__percent +msgid "Percent" +msgstr "في المئة" + +#. module: odex25_account_auto_transfer +#: model_terms:ir.ui.view,arch_db:odex25_account_auto_transfer.view_transfer_model_form +msgid "Percent (%)" +msgstr "نسبة (%)" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model_line__percent_is_readonly +msgid "Percent Is Readonly" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,help:odex25_account_auto_transfer.field_account_transfer_model_line__percent +msgid "" +"Percentage of the sum of lines from the origin accounts will be transferred " +"to the destination account" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model_terms:ir.ui.view,arch_db:odex25_account_auto_transfer.view_transfer_model_form +msgid "Period" +msgstr "الفترة" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields.selection,name:odex25_account_auto_transfer.selection__account_transfer_model__frequency__quarter +msgid "Quarterly" +msgstr "ربع سنوي" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields.selection,name:odex25_account_auto_transfer.selection__account_transfer_model__state__in_progress +msgid "Running" +msgstr "جاري" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model_line__sequence +msgid "Sequence" +msgstr "المسلسل" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model__date_start +msgid "Start Date" +msgstr "تاريخ البداية" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model__state +msgid "State" +msgstr "المحافظة" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model__date_stop +msgid "Stop Date" +msgstr "" + +#. module: odex25_account_auto_transfer +#: code:addons/odex25_account_auto_transfer/models/transfer_model.py:0 +#, python-format +msgid "The analytic filter %s is duplicated" +msgstr "" + +#. module: odex25_account_auto_transfer +#: code:addons/odex25_account_auto_transfer/models/transfer_model.py:0 +#, python-format +msgid "" +"The partner filter %s in combination with the analytic filter %s is " +"duplicated" +msgstr "" + +#. module: odex25_account_auto_transfer +#: code:addons/odex25_account_auto_transfer/models/transfer_model.py:0 +#, python-format +msgid "The partner filter %s is duplicated" +msgstr "" + +#. module: odex25_account_auto_transfer +#: code:addons/odex25_account_auto_transfer/models/transfer_model.py:0 +#, python-format +msgid "The total percentage (%s) should be less or equal to 100 !" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model__total_percent +msgid "Total Percent" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields,field_description:odex25_account_auto_transfer.field_account_transfer_model_line__transfer_model_id +msgid "Transfer Model" +msgstr "" + +#. module: odex25_account_auto_transfer +#: model_terms:ir.ui.view,arch_db:odex25_account_auto_transfer.view_transfer_model_form +msgid "Transfers" +msgstr "الشحنات" + +#. module: odex25_account_auto_transfer +#: model:ir.model.fields.selection,name:odex25_account_auto_transfer.selection__account_transfer_model__frequency__year +msgid "Yearly" +msgstr "سنويًا" diff --git a/odex25_accounting/odex25_account_auto_transfer/models/__init__.py b/odex25_accounting/odex25_account_auto_transfer/models/__init__.py new file mode 100644 index 000000000..88d5a838c --- /dev/null +++ b/odex25_accounting/odex25_account_auto_transfer/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + +from . import account_move +from . import transfer_model diff --git a/odex25_accounting/odex25_account_auto_transfer/models/account_move.py b/odex25_accounting/odex25_account_auto_transfer/models/account_move.py new file mode 100644 index 000000000..d4dd1e538 --- /dev/null +++ b/odex25_accounting/odex25_account_auto_transfer/models/account_move.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- + +from odoo import fields, models + + +class AccountMove(models.Model): + _inherit = 'account.move' + + transfer_model_id = fields.Many2one('account.transfer.model', string="Originating Model") diff --git a/odex25_accounting/odex25_account_auto_transfer/models/transfer_model.py b/odex25_accounting/odex25_account_auto_transfer/models/transfer_model.py new file mode 100644 index 000000000..60040266a --- /dev/null +++ b/odex25_accounting/odex25_account_auto_transfer/models/transfer_model.py @@ -0,0 +1,482 @@ +# -*- coding: utf-8 -*- + +from datetime import date + +from dateutil.relativedelta import relativedelta + +from odoo import fields, models, api, _ +from odoo.exceptions import ValidationError +from odoo.osv import expression +from odoo.tools.float_utils import float_compare, float_is_zero + + +class TransferModel(models.Model): + _name = "account.transfer.model" + _description = "Account Transfer Model" + + # DEFAULTS + def _get_default_date_start(self): + company = self.env.company + return company.compute_fiscalyear_dates(date.today())['date_from'] if company else None + + name = fields.Char(required=True) + journal_id = fields.Many2one('account.journal', required=True, string="Destination Journal") + company_id = fields.Many2one('res.company', readonly=True, related='journal_id.company_id') + date_start = fields.Date(string="Start Date", required=True, default=_get_default_date_start) + date_stop = fields.Date(string="Stop Date", required=False) + frequency = fields.Selection([('month', 'Monthly'), ('quarter', 'Quarterly'), ('year', 'Yearly')], + required=True, default='month') + account_ids = fields.Many2many('account.account', 'account_model_rel', string="Origin Accounts", domain="[('is_off_balance', '=', False)]") + line_ids = fields.One2many('account.transfer.model.line', 'transfer_model_id', string="Destination Accounts") + move_ids = fields.One2many('account.move', 'transfer_model_id', string="Generated Moves") + move_ids_count = fields.Integer(compute="_compute_move_ids_count") + total_percent = fields.Float(compute="_compute_total_percent", string="Total Percent", readonly=True) + state = fields.Selection([('disabled', 'Disabled'), ('in_progress', 'Running')], default='disabled', required=True) + + def copy(self, default=None): + default = default or {} + res = super(TransferModel, self).copy(default) + res.account_ids += self.account_ids + for line in self.line_ids: + line.copy({'transfer_model_id': res.id}) + return res + + + # COMPUTEDS / CONSTRAINS + @api.depends('move_ids') + def _compute_move_ids_count(self): + """ Compute the amount of move ids have been generated by this transfer model. """ + for record in self: + record.move_ids_count = len(record.move_ids) + + @api.constrains('line_ids') + def _check_line_ids_percent(self): + """ Check that the total percent is not bigger than 100.0 """ + for record in self: + if not (0 < record.total_percent <= 100.0): + raise ValidationError(_('The total percentage (%s) should be less or equal to 100 !', record.total_percent)) + + @api.constrains('line_ids') + def _check_line_ids_filters(self): + """ Check that the filters on the lines make sense """ + for record in self: + combinations = [] + for line in record.line_ids: + if line.partner_ids and line.analytic_account_ids: + for p in line.partner_ids: + for a in line.analytic_account_ids: + combination = (p.id, a.id) + if combination in combinations: + raise ValidationError(_("The partner filter %s in combination with the analytic filter %s is duplicated", p.display_name, a.display_name)) + combinations.append(combination) + elif line.partner_ids: + for p in line.partner_ids: + combination = (p.id, None) + if combination in combinations: + raise ValidationError(_("The partner filter %s is duplicated", p.display_name)) + combinations.append(combination) + elif line.analytic_account_ids: + for a in line.analytic_account_ids: + combination = (None, a.id) + if combination in combinations: + raise ValidationError(_("The analytic filter %s is duplicated", a.display_name)) + combinations.append(combination) + + @api.depends('line_ids') + def _compute_total_percent(self): + """ Compute the total percentage of all lines linked to this model. """ + for record in self: + non_filtered_lines = record.line_ids.filtered(lambda l: not l.partner_ids and not l.analytic_account_ids) + if record.line_ids and not non_filtered_lines: + # Lines are only composed of filtered ones thus percentage does not matter, make it 100 + record.total_percent = 100.0 + else: + total_percent = sum(non_filtered_lines.mapped('percent')) + if float_compare(total_percent, 100.0, precision_digits=6) == 0: + total_percent = 100.0 + record.total_percent = total_percent + + # ACTIONS + def action_activate(self): + """ Put this move model in "in progress" state. """ + return self.write({'state': 'in_progress'}) + + def action_disable(self): + """ Put this move model in "disabled" state. """ + return self.write({'state': 'disabled'}) + + @api.model + def action_cron_auto_transfer(self): + """ Perform the automatic transfer for the all active move models. """ + self.search([('state', '=', 'in_progress')]).action_perform_auto_transfer() + + def action_perform_auto_transfer(self): + """ Perform the automatic transfer for the current recordset of models """ + for record in self: + # If no account to ventilate or no account to ventilate into : nothing to do + if record.account_ids and record.line_ids: + today = date.today() + max_date = record.date_stop and min(today, record.date_stop) or today + start_date = record._determine_start_date() + next_move_date = record._get_next_move_date(start_date) + + # (Re)Generate moves in draft untill today + # Journal entries will be recomputed everyday untill posted. + while next_move_date <= max_date: + record._create_or_update_move_for_period(start_date, next_move_date) + start_date = next_move_date + next_move_date = record._get_next_move_date(start_date) + + # (Re)Generate move for one more period if needed + if not record.date_stop: + record._create_or_update_move_for_period(start_date, next_move_date) + elif today < record.date_stop: + record._create_or_update_move_for_period(start_date, min(next_move_date, record.date_stop)) + return False + + def _get_move_lines_base_domain(self, start_date, end_date): + """ + Determine the domain to get all account move lines posted in a given period, for an account in origin accounts + :param start_date: the start date of the period + :param end_date: the end date of the period + :return: the computed domain + :rtype: list + """ + self.ensure_one() + return [ + ('account_id', 'in', self.account_ids.ids), + ('date', '>=', start_date), + ('date', '<', end_date), + ('move_id.state', '=', 'posted') + ] + + # PROTECTEDS + + def _create_or_update_move_for_period(self, start_date, end_date): + """ + Create or update a move for a given period. This means (re)generates all the needed moves to execute the + transfers + :param start_date: the start date of the targeted period + :param end_date: the end date of the targeted period + :return: the created (or updated) move + """ + self.ensure_one() + current_move = self._get_move_for_period(end_date) + if current_move is None: + current_move = self.env['account.move'].create({ + 'ref': '%s: %s --> %s' % (self.name, str(start_date), str(end_date)), + 'date': end_date, + 'journal_id': self.journal_id.id, + 'transfer_model_id': self.id, + }) + + line_values = self._get_auto_transfer_move_line_values(start_date, end_date) + if line_values: + line_ids_values = [(0, 0, value) for value in line_values] + # unlink all old line ids + current_move.line_ids.unlink() + # recreate line ids + current_move.write({'line_ids': line_ids_values}) + return current_move + + def _get_move_for_period(self, end_date): + """ Get the generated move for a given period + :param end_date: the end date of the wished period, do not need the start date as the move will always be + generated with end date of a period as date + :return: a recordset containing the move found if any, else None + """ + self.ensure_one() + # Move will always be generated with end_date of a period as date + domain = [ + ('date', '=', end_date), + ('state', '=', 'draft'), + ('transfer_model_id', '=', self.id) + ] + current_moves = self.env['account.move'].search(domain, limit=1, order="date desc") + return current_moves[0] if current_moves else None + + def _determine_start_date(self): + """ Determine the automatic transfer start date which is the last created move if any or the start date of the model """ + self.ensure_one() + # Get last generated move date if any (to know when to start) + last_move_domain = [('transfer_model_id', '=', self.id), ('state', '=', 'posted'), ('company_id', '=', self.company_id.id)] + move_ids = self.env['account.move'].search(last_move_domain, order='date desc', limit=1) + return move_ids[0].date if move_ids else self.date_start + + def _get_next_move_date(self, date): + """ Compute the following date of automated transfer move, based on a date and the frequency """ + self.ensure_one() + if self.frequency == 'month': + delta = relativedelta(months=1) + elif self.frequency == 'quarter': + delta = relativedelta(months=3) + else: + delta = relativedelta(years=1) + return date + delta + + def _get_auto_transfer_move_line_values(self, start_date, end_date): + """ Get all the transfer move lines values for a given period + :param start_date: the start date of the period + :param end_date: the end date of the period + :return: a list of dict representing the values of lines to create + :rtype: list + """ + self.ensure_one() + values = [] + # Get the balance of all moves from all selected accounts, grouped by accounts + filtered_lines = self.line_ids.filtered(lambda x: x.analytic_account_ids or x.partner_ids) + if filtered_lines: + values += filtered_lines._get_transfer_move_lines_values(start_date, end_date) + + non_filtered_lines = self.line_ids - filtered_lines + if non_filtered_lines: + values += self._get_non_filtered_auto_transfer_move_line_values(non_filtered_lines, start_date, end_date) + + return values + + def _get_non_filtered_auto_transfer_move_line_values(self, lines, start_date, end_date): + """ + Get all values to create move lines corresponding to the transfers needed by all lines without analytic + account or partner for a given period. It contains the move lines concerning destination accounts and + the ones concerning the origin accounts. This process all the origin accounts one after one. + :param lines: the move model lines to handle + :param start_date: the start date of the period + :param end_date: the end date of the period + :return: a list of dict representing the values to use to create the needed move lines + :rtype: list + """ + self.ensure_one() + domain = self._get_move_lines_base_domain(start_date, end_date) + domain = expression.AND([domain, [ + ('analytic_account_id', 'not in', self.line_ids.analytic_account_ids.ids), + ('partner_id', 'not in', self.line_ids.partner_ids.ids), + ]]) + total_balance_by_accounts = self.env['account.move.line'].read_group(domain, ['balance', 'account_id'], + ['account_id']) + + # balance = debit - credit + # --> balance > 0 means a debit so it should be credited on the source account + # --> balance < 0 means a credit so it should be debited on the source account + values_list = [] + for total_balance_account in total_balance_by_accounts: + initial_amount = abs(total_balance_account['balance']) + source_account_is_debit = total_balance_account['balance'] >= 0 + account_id = total_balance_account['account_id'][0] + account = self.env['account.account'].browse(account_id) + if not float_is_zero(initial_amount, precision_digits=9): + move_lines_values, amount_left = self._get_non_analytic_transfer_values(account, lines, end_date, + initial_amount, + source_account_is_debit) + + # the line which credit/debit the source account + substracted_amount = initial_amount - amount_left + source_move_line = { + 'name': _('Automatic Transfer (-%s%%)', self.total_percent), + 'account_id': account_id, + 'date_maturity': end_date, + 'credit' if source_account_is_debit else 'debit': substracted_amount + } + values_list += move_lines_values + values_list.append(source_move_line) + return values_list + + def _get_non_analytic_transfer_values(self, account, lines, write_date, amount, is_debit): + """ + Get all values to create destination account move lines corresponding to the transfers needed by all lines + without analytic account for a given account. + :param account: the origin account to handle + :param write_date: the write date of the move lines + :param amount: the total amount to take care on the origin account + :type amount: float + :param is_debit: True if origin account has a debit balance, False if it's a credit + :type is_debit: bool + :return: a tuple containing the move lines values in a list and the amount left on the origin account after + processing as a float + :rtype: tuple + """ + # if total ventilated is 100% + # then the last line should not compute in % but take the rest + # else + # it should compute in % (as the rest will stay on the source account) + self.ensure_one() + amount_left = amount + + take_the_rest = self.total_percent == 100.0 + amount_of_lines = len(lines) + values_list = [] + + for i, line in enumerate(lines): + if take_the_rest and i == amount_of_lines - 1: + line_amount = amount_left + amount_left = 0 + else: + line_amount = (line.percent / 100.0) * amount + amount_left -= line_amount + + move_line = line._get_destination_account_transfer_move_line_values(account, line_amount, is_debit, + write_date) + values_list.append(move_line) + + return values_list, amount_left + + +class TransferModelLine(models.Model): + _name = "account.transfer.model.line" + _description = "Account Transfer Model Line" + _order = "sequence, id" + + transfer_model_id = fields.Many2one('account.transfer.model', string="Transfer Model", required=True) + account_id = fields.Many2one('account.account', string="Destination Account", required=True, + domain="[('is_off_balance', '=', False)]") + percent = fields.Float(string="Percent", required=True, default=100, help="Percentage of the sum of lines from the origin accounts will be transferred to the destination account") + analytic_account_ids = fields.Many2many('account.analytic.account', string='Analytic Filter', help="Adds a condition to only transfer the sum of the lines from the origin accounts that match these analytic accounts to the destination account") + partner_ids = fields.Many2many('res.partner', string='Partner Filter', help="Adds a condition to only transfer the sum of the lines from the origin accounts that match these partners to the destination account") + percent_is_readonly = fields.Boolean(compute="_compute_percent_is_readonly") + sequence = fields.Integer("Sequence") + + _sql_constraints = [ + ( + 'unique_account_by_transfer_model', 'UNIQUE(transfer_model_id, account_id)', + 'Only one account occurrence by transfer model') + ] + + @api.onchange('analytic_account_ids', 'partner_ids') + def set_percent_if_analytic_account_ids(self): + """ + Set percent to 100 if at least analytic account id is set. + """ + for record in self: + if record.analytic_account_ids or record.partner_ids: + record.percent = 100 + + def _get_transfer_move_lines_values(self, start_date, end_date): + """ + Get values to create the move lines to perform all needed transfers between accounts linked to current recordset + for a given period + :param start_date: the start date of the targeted period + :param end_date: the end date of the targeted period + :return: a list containing all the values needed to create the needed transfers + :rtype: list + """ + transfer_values = [] + # Avoid to transfer two times the same entry + already_handled_move_line_ids = [] + for transfer_model_line in self: + domain = transfer_model_line._get_move_lines_domain(start_date, end_date, already_handled_move_line_ids) + total_balances_by_account = self.env['account.move.line'].read_group(domain, ['ids:array_agg(id)', 'balance', 'account_id'], ['account_id']) + for total_balance_account in total_balances_by_account: + already_handled_move_line_ids += total_balance_account['ids'] + balance = total_balance_account['balance'] + if not float_is_zero(balance, precision_digits=9): + amount = abs(balance) + source_account_is_debit = balance > 0 + account_id = total_balance_account['account_id'][0] + account = self.env['account.account'].browse(account_id) + transfer_values += transfer_model_line._get_transfer_values(account, amount, source_account_is_debit, + end_date) + return transfer_values + + def _get_move_lines_domain(self, start_date, end_date, avoid_move_line_ids=None): + """ + Determine the domain to get all account move lines posted in a given period corresponding to self move model + line. + :param start_date: the start date of the targeted period + :param end_date: the end date of the targeted period + :param avoid_move_line_ids: the account.move.line ids that should be excluded from the domain + :return: the computed domain + :rtype: list + """ + self.ensure_one() + move_lines_domain = self.transfer_model_id._get_move_lines_base_domain(start_date, end_date) + if avoid_move_line_ids: + move_lines_domain.append(('id', 'not in', avoid_move_line_ids)) + if self.analytic_account_ids: + move_lines_domain.append(('analytic_account_id', 'in', self.analytic_account_ids.ids)) + if self.partner_ids: + move_lines_domain.append(('partner_id', 'in', self.partner_ids.ids)) + return move_lines_domain + + def _get_transfer_values(self, account, amount, is_debit, write_date): + """ + Get values to create the move lines to perform a transfer between self account and given account + :param account: the account + :param amount: the amount that is being transferred + :type amount: float + :param is_debit: True if the transferred amount is a debit, False if credit + :type is_debit: bool + :param write_date: the date to use for the move line writing + :return: a list containing the values to create the needed move lines + :rtype: list + """ + self.ensure_one() + return [ + self._get_destination_account_transfer_move_line_values(account, amount, is_debit, write_date), + self._get_origin_account_transfer_move_line_values(account, amount, is_debit, write_date) + ] + + def _get_origin_account_transfer_move_line_values(self, origin_account, amount, is_debit, + write_date): + """ + Get values to create the move line in the origin account side for a given transfer of a given amount from origin + account to a given destination account. + :param origin_account: the origin account + :param amount: the amount that is being transferred + :type amount: float + :param is_debit: True if the transferred amount is a debit, False if credit + :type is_debit: bool + :param write_date: the date to use for the move line writing + :return: a dict containing the values to create the move line + :rtype: dict + """ + anal_accounts = self.analytic_account_ids and ', '.join(self.analytic_account_ids.mapped('name')) + partners = self.partner_ids and ', '.join(self.partner_ids.mapped('name')) + if anal_accounts and partners: + name = _("Automatic Transfer (entries with analytic account(s): %s and partner(s): %s)") % (anal_accounts, partners) + elif anal_accounts: + name = _("Automatic Transfer (entries with analytic account(s): %s)") % (anal_accounts,) + elif partners: + name = _("Automatic Transfer (entries with partner(s): %s)") % (partners,) + else: + name = _("Automatic Transfer (to account %s)", self.account_id.code) + return { + 'name': name, + 'account_id': origin_account.id, + 'date_maturity': write_date, + 'credit' if is_debit else 'debit': amount + } + + def _get_destination_account_transfer_move_line_values(self, origin_account, amount, is_debit, + write_date): + """ + Get values to create the move line in the destination account side for a given transfer of a given amount from + given origin account to destination account. + :param origin_account: the origin account + :param amount: the amount that is being transferred + :type amount: float + :param is_debit: True if the transferred amount is a debit, False if credit + :type is_debit: bool + :param write_date: the date to use for the move line writing + :return: a dict containing the values to create the move line + :rtype dict: + """ + anal_accounts = self.analytic_account_ids and ', '.join(self.analytic_account_ids.mapped('name')) + partners = self.partner_ids and ', '.join(self.partner_ids.mapped('name')) + if anal_accounts and partners: + name = _("Automatic Transfer (from account %s with analytic account(s): %s and partner(s): %s)") % (origin_account.code, anal_accounts, partners) + elif anal_accounts: + name = _("Automatic Transfer (from account %s with analytic account(s): %s)") % (origin_account.code, anal_accounts) + elif partners: + name = _("Automatic Transfer (from account %s with partner(s): %s)") % (origin_account.code, partners,) + else: + name = _("Automatic Transfer (%s%% from account %s)") % (self.percent, origin_account.code) + return { + 'name': name, + 'account_id': self.account_id.id, + 'date_maturity': write_date, + 'debit' if is_debit else 'credit': amount + } + + @api.depends('analytic_account_ids', 'partner_ids') + def _compute_percent_is_readonly(self): + for record in self: + record.percent_is_readonly = record.analytic_account_ids or record.partner_ids diff --git a/odex25_accounting/odex25_account_auto_transfer/security/ir.model.access.csv b/odex25_accounting/odex25_account_auto_transfer/security/ir.model.access.csv new file mode 100644 index 000000000..1fc8a4f0a --- /dev/null +++ b/odex25_accounting/odex25_account_auto_transfer/security/ir.model.access.csv @@ -0,0 +1,7 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_account_transfer_model,access_account_transfer_model,odex25_account_auto_transfer.model_account_transfer_model,account.group_account_readonly,1,0,0,0 +access_account_transfer_model_manager,access_account_transfer_model_manager,odex25_account_auto_transfer.model_account_transfer_model,account.group_account_manager,1,1,1,1 +access_account_transfer_model_invoicing_payment,access_account_transfer_model_invoicing_payment,odex25_account_auto_transfer.model_account_transfer_model,account.group_account_invoice,1,0,1,0 +access_account_transfer_model_line,access_account_transfer_model_line,odex25_account_auto_transfer.model_account_transfer_model_line,account.group_account_readonly,1,0,0,0 +access_account_transfer_model_line_manager,access_account_transfer_model_line_manager,odex25_account_auto_transfer.model_account_transfer_model_line,account.group_account_manager,1,1,1,1 +access_account_transfer_model_line_invoicing_payment,access_account_transfer_model_line_invoicing_payment,odex25_account_auto_transfer.model_account_transfer_model_line,account.group_account_invoice,1,0,1,0 diff --git a/odex25_accounting/odex25_account_auto_transfer/static/description/icon.png b/odex25_accounting/odex25_account_auto_transfer/static/description/icon.png new file mode 100644 index 000000000..899c85343 Binary files /dev/null and b/odex25_accounting/odex25_account_auto_transfer/static/description/icon.png differ diff --git a/odex25_accounting/odex25_account_auto_transfer/static/description/icon.svg b/odex25_accounting/odex25_account_auto_transfer/static/description/icon.svg new file mode 100644 index 000000000..7d215c3ff --- /dev/null +++ b/odex25_accounting/odex25_account_auto_transfer/static/description/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/odex25_accounting/odex25_account_auto_transfer/tests/__init__.py b/odex25_accounting/odex25_account_auto_transfer/tests/__init__.py new file mode 100644 index 000000000..7bb76980e --- /dev/null +++ b/odex25_accounting/odex25_account_auto_transfer/tests/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- +from . import test_transfer_model +from . import test_transfer_model_line diff --git a/odex25_accounting/odex25_account_auto_transfer/tests/odex25_account_auto_transfer_test_classes.py b/odex25_accounting/odex25_account_auto_transfer/tests/odex25_account_auto_transfer_test_classes.py new file mode 100644 index 000000000..385f982c0 --- /dev/null +++ b/odex25_accounting/odex25_account_auto_transfer/tests/odex25_account_auto_transfer_test_classes.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +from datetime import datetime +from uuid import uuid4 + +from odoo.tests import common + +from odoo.addons.account.tests.common import AccountTestInvoicingCommon + + +class AccountAutoTransferTestCase(AccountTestInvoicingCommon): + + @classmethod + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) + cls.journal = cls.env['account.journal'].create({'type': 'bank', 'name': 'bank', 'code': 'BANK'}) + cls.transfer_model = cls.env['account.transfer.model'].create({ + 'name': 'Test Transfer', + 'date_start': '2019-06-01', + 'frequency': 'month', + 'journal_id': cls.journal.id + }) + cls.master_account_index = 0 + cls.slave_account_index = 1 + cls.origin_accounts, cls.destination_accounts = cls._create_accounts(cls) + + def _assign_origin_accounts(self): + self.transfer_model.write({ + 'account_ids': [(6, 0, self.origin_accounts.ids)] + }) + + def _create_accounts(self, amount_of_master_accounts=2, amount_of_slave_accounts=4): + account_type = self.env.ref('account.data_account_type_receivable') + + master_ids = self.env['account.account'] + for i in range(amount_of_master_accounts): + self.master_account_index += 1 + master_ids += self.env['account.account'].create({ + 'name': 'MASTER %s' % self.master_account_index, + 'code': 'MA00%s' % self.master_account_index, + 'user_type_id': account_type.id, + 'reconcile': True + }) + + slave_ids = self.env['account.account'] + for i in range(amount_of_slave_accounts): + self.slave_account_index += 1 + slave_ids += self.env['account.account'].create({ + 'name': 'SLAVE %s' % self.slave_account_index, + 'code': 'SL000%s' % self.slave_account_index, + 'user_type_id': account_type.id, + 'reconcile': True + }) + return master_ids, slave_ids + + def _create_analytic_account(self, code='ANAL01'): + return self.env['account.analytic.account'].create({'name': code, 'code': code}) + + def _create_partner(self, name="partner01"): + return self.env['res.partner'].create({'name': name}) + + def _create_basic_move(self, cred_account=None, deb_account=None, amount=0, date_str='2019-02-01', + partner_id=False, name=False, cred_analytic=False, deb_analytic=False, + transfer_model_id=False, journal_id=False, posted=True): + move_vals = { + 'date': date_str, + 'transfer_model_id': transfer_model_id, + 'line_ids': [ + (0, 0, { + 'account_id': cred_account or self.origin_accounts[0].id, + 'credit': amount, + 'analytic_account_id': cred_analytic, + 'partner_id': partner_id, + }), + (0, 0, { + 'account_id': deb_account or self.origin_accounts[1].id, + 'analytic_account_id': deb_analytic, + 'debit': amount, + 'partner_id': partner_id, + }), + ] + } + if journal_id: + move_vals['journal_id'] = journal_id + move = self.env['account.move'].create(move_vals) + if posted: + move.action_post() + return move + + def _add_transfer_model_line(self, account_id: int = False, percent: float = 100.0, analytic_account_ids: list = False, partner_ids: list = False): + account_id = account_id or self.destination_accounts[0].id + return self.env['account.transfer.model.line'].create({ + 'percent': percent, + 'account_id': account_id, + 'transfer_model_id': self.transfer_model.id, + 'analytic_account_ids': analytic_account_ids and [(4, aa) for aa in analytic_account_ids], + 'partner_ids': partner_ids and [(4, p) for p in partner_ids], + }) diff --git a/odex25_accounting/odex25_account_auto_transfer/tests/test_transfer_model.py b/odex25_accounting/odex25_account_auto_transfer/tests/test_transfer_model.py new file mode 100644 index 000000000..9504394a3 --- /dev/null +++ b/odex25_accounting/odex25_account_auto_transfer/tests/test_transfer_model.py @@ -0,0 +1,395 @@ +# -*- coding: utf-8 -*- +from datetime import datetime, timedelta +from unittest.mock import patch, call +from functools import reduce +from itertools import chain + +from dateutil.relativedelta import relativedelta +from odoo.addons.odex25_account_auto_transfer.tests.odex25_account_auto_transfer_test_classes import AccountAutoTransferTestCase + +from odoo import fields +from odoo.models import ValidationError +from odoo.tests import tagged + +# ############################################################################ # +# FUNCTIONAL TESTS # +# ############################################################################ # +@tagged('post_install', '-at_install') +class TransferModelTestFunctionalCase(AccountAutoTransferTestCase): + + @classmethod + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) + # Model with 4 lines of 20%, 20% is left in origin accounts + cls.functional_transfer = cls.env['account.transfer.model'].create({ + 'name': 'Test Functional Model', + 'date_start': '2019-01-01', + 'date_stop': datetime.today() + relativedelta(months=1), + 'journal_id': cls.journal.id, + 'account_ids': [(6, 0, cls.origin_accounts.ids)], + 'line_ids': [(0, 0, { + 'account_id': account.id, + 'percent': 20, + }) for account in cls.destination_accounts], + }) + neutral_account = cls.env['account.account'].create({ + 'name': 'Neutral Account', + 'code': 'NEUT', + 'user_type_id': cls.env.ref('account.data_account_type_revenue').id, + }) + cls.analytic_accounts = reduce(lambda x, y: x + y, (cls._create_analytic_account(cls, name) for name in ('ANA1', 'ANA2', 'ANA3'))) + cls.dates = ('2019-01-15', '2019-02-15') + # Create one line for each date... + for date in cls.dates: + # ...with each analytic account, and with no analytic account... + for an_account in chain(cls.analytic_accounts, [cls.env['account.analytic.account']]): + # ...in each origin account with a balance of 1000. + for account in cls.origin_accounts: + cls._create_basic_move( + cls, + deb_account=account.id, + deb_analytic=an_account.id, + cred_account=neutral_account.id, + amount=1000, + date_str=date, + ) + + def test_no_analytics(self): + # Balance is +8000 in each origin account + # 80% is transfered in 4 destination accounts in equal proprotions + self.functional_transfer.action_perform_auto_transfer() + # 1600 is left in each origin account + for account in self.origin_accounts: + self.assertEqual(sum(self.env['account.move.line'].search([('account_id', '=', account.id)]).mapped('balance')), 1600) + # 3200 has been transfered in each destination account + for account in self.destination_accounts: + self.assertEqual(sum(self.env['account.move.line'].search([('account_id', '=', account.id)]).mapped('balance')), 3200) + for date in self.dates: + # 2 move lines have been created in each account for each date + self.assertEqual(len(self.env['account.move.line'].search([('account_id', '=', account.id), ('date', '=', fields.Date.to_date(date) + relativedelta(day=1, months=1))])), 2) + + def test_analytics(self): + # Each line with analytic accounts is set to 100% + self.functional_transfer.line_ids[0].analytic_account_ids = self.analytic_accounts[0:2] + self.functional_transfer.line_ids[1].analytic_account_ids = self.analytic_accounts[2] + + self.functional_transfer.action_perform_auto_transfer() + # 1200 is left in each origin account (60% of 2 lines) + for account in self.origin_accounts: + self.assertEqual(sum(self.env['account.move.line'].search([('account_id', '=', account.id)]).mapped('balance')), 1200) + # 8000 has been transfered the first destination account (100% of 8 lines) + self.assertEqual(sum(self.env['account.move.line'].search([('account_id', '=', self.destination_accounts[0].id)]).mapped('balance')), 8000) + # 4000 has been transfered the first destination account (100% of 4 lines) + self.assertEqual(sum(self.env['account.move.line'].search([('account_id', '=', self.destination_accounts[1].id)]).mapped('balance')), 4000) + # 800 has been transfered in each of the last two destination account (20% of 4 lines) + self.assertEqual(sum(self.env['account.move.line'].search([('account_id', '=', self.destination_accounts[2].id)]).mapped('balance')), 800) + self.assertEqual(sum(self.env['account.move.line'].search([('account_id', '=', self.destination_accounts[3].id)]).mapped('balance')), 800) + + +# ############################################################################ # +# UNIT TESTS # +# ############################################################################ # +@tagged('post_install', '-at_install') +class TransferModelTestCase(AccountAutoTransferTestCase): + @patch('odoo.addons.odex25_account_auto_transfer.models.transfer_model.TransferModel.action_perform_auto_transfer') + def test_action_cron_auto_transfer(self, patched): + TransferModel = self.env['account.transfer.model'] + TransferModel.create({ + 'name': 'Test Cron Model', + 'date_start': '2019-01-01', + 'date_stop': datetime.today() + relativedelta(months=1), + 'journal_id': self.journal.id + }) + TransferModel.action_cron_auto_transfer() + patched.assert_called_once() + + @patch('odoo.addons.odex25_account_auto_transfer.models.transfer_model.TransferModel._create_or_update_move_for_period') + def test_action_perform_auto_transfer(self, patched): + self.transfer_model.date_start = datetime.strftime(datetime.today() + relativedelta(day=1), "%Y-%m-%d") + # - CASE 1 : normal case, acting on current period + self.transfer_model.action_perform_auto_transfer() + patched.assert_not_called() # create_or_update method should not be called for self.transfer_model as no account_ids and no line_ids + + master_ids, slave_ids = self._create_accounts(1, 2) + self.transfer_model.write({'account_ids': [(6, 0, [master_ids.id])]}) + + self.transfer_model.action_perform_auto_transfer() + patched.assert_not_called() # create_or_update method should not be called for self.transfer_model as no line_ids + + self.transfer_model.write({'line_ids': [ + (0, 0, { + 'percent': 50.0, + 'account_id': slave_ids[0].id + }), + (0, 0, { + 'percent': 50.0, + 'account_id': slave_ids[1].id + }) + ]}) + + self.transfer_model.action_perform_auto_transfer() + patched.assert_called_once() # create_or_update method should be called for self.transfer_model + + # - CASE 2 : "old" case, acting on everything before now as nothing has been done yet + transfer_model = self.transfer_model.copy() + transfer_model.write({ + 'date_start': transfer_model.date_start + relativedelta(months=-12) + }) + initial_call_count = patched.call_count + transfer_model.action_perform_auto_transfer() + self.assertEqual(initial_call_count + 13, patched.call_count, '13 more calls should have been done') + + + @patch('odoo.addons.odex25_account_auto_transfer.models.transfer_model.TransferModel._get_auto_transfer_move_line_values') + def test__create_or_update_move_for_period(self, patched_get_auto_transfer_move_line_values): + # PREPARATION + master_ids, slave_ids = self._create_accounts(2, 0) + next_move_date = self.transfer_model._get_next_move_date(self.transfer_model.date_start) + patched_get_auto_transfer_move_line_values.return_value = [ + { + 'account_id': master_ids[0].id, + 'date_maturity': next_move_date, + 'credit': 250.0, + }, + { + 'account_id': master_ids[1].id, + 'date_maturity': next_move_date, + 'debit': 250.0, + } + ] + + # There is no existing move, this is a brand new one + created_move = self.transfer_model._create_or_update_move_for_period(self.transfer_model.date_start, next_move_date) + self.assertEqual(len(created_move.line_ids), 2) + self.assertRecordValues(created_move, [{ + 'date': next_move_date, + 'journal_id': self.transfer_model.journal_id.id, + 'transfer_model_id': self.transfer_model.id, + }]) + self.assertRecordValues(created_move.line_ids.filtered(lambda l: l.credit), [{ + 'account_id': master_ids[0].id, + 'date_maturity': next_move_date, + 'credit': 250.0, + }]) + self.assertRecordValues(created_move.line_ids.filtered(lambda l: l.debit), [{ + 'account_id': master_ids[1].id, + 'date_maturity': next_move_date, + 'debit': 250.0, + }]) + + patched_get_auto_transfer_move_line_values.return_value = [ + { + 'account_id': master_ids[0].id, + 'date_maturity': next_move_date, + 'credit': 78520.0, + }, + { + 'account_id': master_ids[1].id, + 'date_maturity': next_move_date, + 'debit': 78520.0, + } + ] + + # Update the existing move but don't create a new one + amount_of_moves = self.env['account.move'].search_count([]) + amount_of_move_lines = self.env['account.move.line'].search_count([]) + updated_move = self.transfer_model._create_or_update_move_for_period(self.transfer_model.date_start, next_move_date) + self.assertEqual(amount_of_moves, self.env['account.move'].search_count([]), 'No move have been created') + self.assertEqual(amount_of_move_lines, self.env['account.move.line'].search_count([]), + 'No move line have been created (in fact yes but the old ones have been deleted)') + self.assertEqual(updated_move, created_move, 'Existing move has been updated') + self.assertRecordValues(updated_move.line_ids.filtered(lambda l: l.credit), [{ + 'account_id': master_ids[0].id, + 'date_maturity': next_move_date, + 'credit': 78520.0, + }]) + self.assertRecordValues(updated_move.line_ids.filtered(lambda l: l.debit), [{ + 'account_id': master_ids[1].id, + 'date_maturity': next_move_date, + 'debit': 78520.0, + }]) + + def test__get_move_for_period(self): + # 2019-06-30 --> None as no move generated + date_to_test = datetime.strptime('2019-06-30', '%Y-%m-%d').date() + move_for_period = self.transfer_model._get_move_for_period(date_to_test) + self.assertIsNone(move_for_period, 'No move is generated yet') + + # Generate a move + move_date = self.transfer_model._get_next_move_date(self.transfer_model.date_start) + already_generated_move = self.env['account.move'].create({ + 'date': move_date, + 'journal_id': self.journal.id, + 'transfer_model_id': self.transfer_model.id + }) + # 2019-06-30 --> None as generated move is generated for 01/07 + move_for_period = self.transfer_model._get_move_for_period(date_to_test) + self.assertIsNone(move_for_period, 'The generated move is for the next period') + + # 2019-07-01 --> The generated move + date_to_test += relativedelta(days=1) + move_for_period = self.transfer_model._get_move_for_period(date_to_test) + self.assertEqual(move_for_period, already_generated_move, 'Should be equal to the already generated move') + + # 2019-07-02 --> None as generated move is generated for 01/07 + date_to_test += relativedelta(days=1) + move_for_period = self.transfer_model._get_move_for_period(date_to_test) + self.assertIsNone(move_for_period, 'No move is generated yet for the next period') + + def test__determine_start_date(self): + start_date = self.transfer_model._determine_start_date() + self.assertEqual(start_date, self.transfer_model.date_start, 'No moves generated yet, start date should be the start date of the transfer model') + + move = self._create_basic_move(date_str='2019-07-01', journal_id=self.journal.id, transfer_model_id=self.transfer_model.id, posted=False) + start_date = self.transfer_model._determine_start_date() + self.assertEqual(start_date, self.transfer_model.date_start, 'A move generated but not posted, start date should be the start date of the transfer model') + + move.action_post() + start_date = self.transfer_model._determine_start_date() + self.assertEqual(start_date, move.date, 'A move posted, start date should be the date of that move') + + second_move = self._create_basic_move(date_str='2019-08-01', journal_id=self.journal.id, transfer_model_id=self.transfer_model.id, posted=False) + start_date = self.transfer_model._determine_start_date() + self.assertEqual(start_date, move.date, 'Two moves generated, start date should be the date of the last posted one') + + second_move.action_post() + random_move = self._create_basic_move(date_str='2019-08-01', journal_id=self.journal.id) + start_date = self.transfer_model._determine_start_date() + self.assertEqual(start_date, second_move.date, 'Random move generated not linked to transfer model, start date should be the date of the last one linked to it') + + def test__get_next_move_date(self): + experimentations = { + 'month': [ + # date, expected date + (self.transfer_model.date_start, '2019-07-01'), + (fields.Date.to_date('2019-01-29'), '2019-02-28'), + (fields.Date.to_date('2019-01-30'), '2019-02-28'), + (fields.Date.to_date('2019-01-31'), '2019-02-28'), + (fields.Date.to_date('2019-02-28'), '2019-03-28'), + (fields.Date.to_date('2019-12-31'), '2020-01-31'), + ], + 'quarter': [ + (self.transfer_model.date_start, '2019-09-01'), + (fields.Date.to_date('2019-01-31'), '2019-04-30'), + (fields.Date.to_date('2019-02-28'), '2019-05-28'), + (fields.Date.to_date('2019-12-31'), '2020-03-31'), + ], + 'year': [ + (self.transfer_model.date_start, '2020-06-01'), + (fields.Date.to_date('2019-01-31'), '2020-01-31'), + (fields.Date.to_date('2019-02-28'), '2020-02-28'), + (fields.Date.to_date('2019-12-31'), '2020-12-31'), + ] + } + + for frequency in experimentations: + self.transfer_model.write({'frequency': frequency}) + for start_date, expected_date_str in experimentations[frequency]: + next_date = self.transfer_model._get_next_move_date(start_date) + self.assertEqual(next_date, fields.Date.to_date(expected_date_str), + 'Next date from %s should be %s' % (str(next_date), expected_date_str)) + + @patch('odoo.addons.odex25_account_auto_transfer.models.transfer_model.TransferModel._get_non_analytic_transfer_values') + @patch('odoo.models.BaseModel.read_group') + def test__get_non_filtered_auto_transfer_move_line_values(self, patched_read_group, patched_get_values): + start_date = fields.Date.to_date('2019-01-01') + end_date = fields.Date.to_date('2019-12-31') + patched_read_group.return_value = [ + {'balance': 4242.42, 'account_id': (self.origin_accounts[0].id,)}, + {'balance': 0, 'account_id': (self.destination_accounts[0].id,)}, + {'balance': -12585.0, 'account_id': (self.origin_accounts[1].id,)} + ] + amount_left = 10.0 + patched_get_values.return_value = [{ + 'name': "YO", + 'account_id': 1, + 'date_maturity': start_date, + 'debit': 123.45 + }], amount_left + + exp = [{ + 'name': 'YO', + 'account_id': 1, + 'date_maturity': start_date, + 'debit': 123.45 + }, { + 'name': 'Automatic Transfer (-%s%%)' % self.transfer_model.total_percent, + 'account_id': self.origin_accounts[0].id, + 'date_maturity': end_date, + 'credit': 4242.42 - amount_left + }, { + 'name': 'YO', + 'account_id': 1, + 'date_maturity': start_date, + 'debit': 123.45 + }, { + 'name': 'Automatic Transfer (-%s%%)' % self.transfer_model.total_percent, + 'account_id': self.origin_accounts[1].id, + 'date_maturity': end_date, + 'debit': 12585.0 - amount_left + }] + exp_res_len = len([x for x in patched_read_group.return_value if x['balance'] != 0.0]) * 2 + res = self.transfer_model._get_non_filtered_auto_transfer_move_line_values([], start_date, end_date) + self.assertEqual(len(res), exp_res_len) + self.assertListEqual(exp, res) + + @patch( + 'odoo.addons.odex25_account_auto_transfer.models.transfer_model.TransferModelLine._get_destination_account_transfer_move_line_values') + def test__get_non_analytic_transfer_values(self, patched): + # Just need a transfer model line + percents = [45, 45] + self.transfer_model.write({ + 'account_ids': [(6, 0, [ma.id for ma in self.origin_accounts])], + 'line_ids': [ + (0, 0, { + 'percent': percents[0], + 'account_id': self.destination_accounts[0].id + }), + (0, 0, { + 'percent': percents[1], + 'account_id': self.destination_accounts[1].id + }) + ] + }) + account = self.origin_accounts[0] + write_date = fields.Date.to_date('2019-01-01') + lines = self.transfer_model.line_ids + amount_of_line = len(lines) + amount = 4242.0 + is_debit = False + patched.return_value = { + 'name': "YO", + 'account_id': account.id, + 'date_maturity': write_date, + 'debit' if is_debit else 'credit': amount + } + expected_result_list = [patched.return_value] * 2 + expected_result_amount = amount * ((100.0 - sum(percents)) / 100.0) + + res = self.transfer_model._get_non_analytic_transfer_values(account, lines, write_date, amount, is_debit) + self.assertListEqual(res[0], expected_result_list) + self.assertAlmostEqual(res[1], expected_result_amount) + self.assertEqual(patched.call_count, amount_of_line) + + # need to round amount to avoid failing float comparison (as magic mock uses "==" to compare args) + exp_calls = [call(account, round(amount * (line.percent / 100.0), 1), is_debit, write_date) for line in lines] + patched.assert_has_calls(exp_calls) + + # Try now with 100% repartition + lines[0].write({'percent': 55.0}) + res = self.transfer_model._get_non_analytic_transfer_values(account, lines, write_date, amount, is_debit) + self.assertAlmostEqual(res[1], 0.0) + + # TEST CONSTRAINTS + def test__check_line_ids_percents(self): + with self.assertRaises(ValidationError): + transfer_model_lines = [] + for i, percent in enumerate((50.0, 50.01)): + transfer_model_lines.append((0, 0, { + 'percent': percent, + 'account_id': self.destination_accounts[i].id + })) + self.transfer_model.write({ + 'account_ids': [(6, 0, [ma.id for ma in self.origin_accounts])], + 'line_ids': transfer_model_lines + }) diff --git a/odex25_accounting/odex25_account_auto_transfer/tests/test_transfer_model_line.py b/odex25_accounting/odex25_account_auto_transfer/tests/test_transfer_model_line.py new file mode 100644 index 000000000..7fb012656 --- /dev/null +++ b/odex25_accounting/odex25_account_auto_transfer/tests/test_transfer_model_line.py @@ -0,0 +1,288 @@ +# -*- coding: utf-8 -*- + +from unittest.mock import patch + +from odoo.addons.odex25_account_auto_transfer.tests.odex25_account_auto_transfer_test_classes import AccountAutoTransferTestCase + +from odoo import fields +from odoo.tests import tagged + +# ############################################################################ # +# UNIT TESTS # +# ############################################################################ # +@tagged('post_install', '-at_install') +class MoveModelLineTestCase(AccountAutoTransferTestCase): + + @classmethod + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) + cls._assign_origin_accounts(cls) + + def test__get_transfer_move_lines_values_same_aaccounts(self): + amounts = [4242.42, 1234.56] + aaccounts = [self._create_analytic_account('ANAL0' + str(i)) for i in range(2)] + self._create_basic_move( + cred_account=self.destination_accounts[0].id, + deb_account=self.origin_accounts[0].id, + amount=amounts[0], + deb_analytic=aaccounts[0].id + ) + self._create_basic_move( + cred_account=self.destination_accounts[1].id, + deb_account=self.origin_accounts[0].id, + amount=amounts[1], + deb_analytic=aaccounts[1].id + ) + transfer_model_line_1 = self._add_transfer_model_line(self.destination_accounts[0].id, + analytic_account_ids=[aaccounts[0].id, aaccounts[1].id]) + transfer_model_line_2 = self._add_transfer_model_line(self.destination_accounts[1].id, + analytic_account_ids=[aaccounts[0].id]) + + transfer_models_lines = transfer_model_line_1 + transfer_model_line_2 + args = [fields.Date.to_date('2019-01-01'), fields.Date.to_date('2019-12-19')] + res = transfer_models_lines._get_transfer_move_lines_values(*args) + exp = [{ + 'name': 'Automatic Transfer (from account MA001 with analytic account(s): ANAL00, ANAL01)', + 'account_id': self.destination_accounts[0].id, + 'date_maturity': args[1], + 'debit': sum(amounts), + }, { + 'name': 'Automatic Transfer (entries with analytic account(s): ANAL00, ANAL01)', + 'account_id': self.origin_accounts[0].id, + 'date_maturity': args[1], + 'credit': sum(amounts), + }] + self.assertListEqual(exp, res, + 'Only first transfer model line should be handled, second should get 0 and thus not be added') + + def test__get_transfer_move_lines_values(self): + amounts = [4242.0, 1234.56] + aaccounts = [self._create_analytic_account('ANAL0' + str(i)) for i in range(3)] + self._create_basic_move( + cred_account=self.destination_accounts[0].id, + deb_account=self.origin_accounts[0].id, + amount=amounts[0], + deb_analytic=aaccounts[0].id + ) + self._create_basic_move( + cred_account=self.destination_accounts[1].id, + deb_account=self.origin_accounts[0].id, + amount=amounts[1], + deb_analytic=aaccounts[2].id + ) + transfer_model_line_1 = self._add_transfer_model_line(self.destination_accounts[0].id, + analytic_account_ids=[aaccounts[0].id, aaccounts[1].id]) + transfer_model_line_2 = self._add_transfer_model_line(self.destination_accounts[1].id, + analytic_account_ids=[aaccounts[2].id]) + + transfer_models_lines = transfer_model_line_1 + transfer_model_line_2 + args = [fields.Date.to_date('2019-01-01'), fields.Date.to_date('2019-12-19')] + res = transfer_models_lines._get_transfer_move_lines_values(*args) + exp = [ + { + 'name': 'Automatic Transfer (from account MA001 with analytic account(s): ANAL00, ANAL01)', + 'account_id': self.destination_accounts[0].id, + 'date_maturity': args[1], + 'debit': amounts[0], + }, + { + 'name': 'Automatic Transfer (entries with analytic account(s): ANAL00, ANAL01)', + 'account_id': self.origin_accounts[0].id, + 'date_maturity': args[1], + 'credit': amounts[0], + }, + { + 'name': 'Automatic Transfer (from account MA001 with analytic account(s): ANAL02)', + 'account_id': self.destination_accounts[1].id, + 'date_maturity': args[1], + 'debit': amounts[1], + }, + { + 'name': 'Automatic Transfer (entries with analytic account(s): ANAL02)', + 'account_id': self.origin_accounts[0].id, + 'date_maturity': args[1], + 'credit': amounts[1], + } + ] + self.assertListEqual(exp, res) + + @patch('odoo.addons.odex25_account_auto_transfer.models.transfer_model.TransferModel._get_move_lines_base_domain') + def test__get_move_lines_domain(self, patched): + return_val = [('bla', '=', 42)] + # we need to copy return val as there are edge effects due to mocking + # return_value is modified by the function call) + patched.return_value = return_val[:] + args = [fields.Date.to_date('2019-01-01'), fields.Date.to_date('2019-12-19')] + aaccount_1 = self._create_analytic_account('ANAL01') + aaccount_2 = self._create_analytic_account('ANAL02') + percent = 42.42 + analytic_transfer_model_line = self._add_transfer_model_line(self.destination_accounts[0].id, + analytic_account_ids=[aaccount_1.id, aaccount_2.id]) + percent_transfer_model_line = self._add_transfer_model_line(self.destination_accounts[1].id, percent=percent) + + anal_res = analytic_transfer_model_line._get_move_lines_domain(*args) + anal_expected = return_val + [('analytic_account_id', 'in', [aaccount_1.id, aaccount_2.id])] + patched.assert_called_once_with(*args) + self.assertListEqual(anal_res, anal_expected) + patched.reset_mock() + + perc_res = percent_transfer_model_line._get_move_lines_domain(*args) + patched.assert_called_once_with(*args) + self.assertListEqual(perc_res, patched.return_value) + + def test__get_origin_account_transfer_move_line_values(self): + percent = 92.42 + transfer_model_line = self._add_transfer_model_line(self.destination_accounts[0].id, percent=percent) + origin_account = self.origin_accounts[0] + amount = 4200.42 + is_debit = True + write_date = fields.Date.to_date('2019-12-19') + params = [origin_account, amount, is_debit, write_date] + result = transfer_model_line._get_origin_account_transfer_move_line_values(*params) + expected = { + 'name': 'Automatic Transfer (to account %s)' % self.destination_accounts[0].code, + 'account_id': origin_account.id, + 'date_maturity': write_date, + 'credit' if is_debit else 'debit': amount + } + self.assertDictEqual(result, expected) + + def test__get_destination_account_transfer_move_line_values(self): + aaccount_1 = self._create_analytic_account('ANAL01') + aaccount_2 = self._create_analytic_account('ANAL02') + percent = 42.42 + analytic_transfer_model_line = self._add_transfer_model_line(self.destination_accounts[0].id, + analytic_account_ids=[aaccount_1.id, aaccount_2.id]) + percent_transfer_model_line = self._add_transfer_model_line(self.destination_accounts[1].id, percent=percent) + origin_account = self.origin_accounts[0] + amount = 4200 + is_debit = True + write_date = fields.Date.to_date('2019-12-19') + params = [origin_account, amount, is_debit, write_date] + anal_result = analytic_transfer_model_line._get_destination_account_transfer_move_line_values(*params) + aaccount_names = ', '.join([aac.name for aac in [aaccount_1, aaccount_2]]) + anal_expected_result = { + 'name': 'Automatic Transfer (from account %s with analytic account(s): %s)' % ( + origin_account.code, aaccount_names), + 'account_id': self.destination_accounts[0].id, + 'date_maturity': write_date, + 'debit' if is_debit else 'credit': amount + } + self.assertDictEqual(anal_result, anal_expected_result) + percent_result = percent_transfer_model_line._get_destination_account_transfer_move_line_values(*params) + percent_expected_result = { + 'name': 'Automatic Transfer (%s%% from account %s)' % (percent, self.origin_accounts[0].code), + 'account_id': self.destination_accounts[1].id, + 'date_maturity': write_date, + 'debit' if is_debit else 'credit': amount + } + self.assertDictEqual(percent_result, percent_expected_result) + + def test__get_transfer_move_lines_values_same_partner_ids(self): + """ + Make sure we only process the account moves once. + Here the second line references a partner already handled in the first one. + The second transfer should thus not be apply on the account lines already handled by the first transfer. + """ + amounts = [4242.42, 1234.56] + partner_ids = [self._create_partner('partner' + str(i))for i in range(2)] + self._create_basic_move( + cred_account=self.destination_accounts[0].id, + deb_account=self.origin_accounts[0].id, + amount=amounts[0], + partner_id=partner_ids[0].id, + date_str='2019-02-01' + ) + self._create_basic_move( + cred_account=self.destination_accounts[1].id, + deb_account=self.origin_accounts[0].id, + amount=amounts[1], + partner_id=partner_ids[1].id, + date_str='2019-02-01' + ) + self._create_basic_move( + cred_account=self.destination_accounts[0].id, + deb_account=self.origin_accounts[0].id, + amount=amounts[0], + date_str='2019-02-01' + ) + transfer_model_line_1 = self._add_transfer_model_line(self.destination_accounts[0].id, + partner_ids=[partner_ids[0].id, partner_ids[1].id]) + transfer_model_line_2 = self._add_transfer_model_line(self.destination_accounts[1].id, + partner_ids=[partner_ids[0].id]) + + transfer_models_lines = transfer_model_line_1 + transfer_model_line_2 + args = [fields.Date.to_date('2019-01-01'), fields.Date.to_date('2019-12-19')] + res = transfer_models_lines._get_transfer_move_lines_values(*args) + exp = [{ + 'name': 'Automatic Transfer (from account MA001 with partner(s): partner0, partner1)', + 'account_id': self.destination_accounts[0].id, + 'date_maturity': args[1], + 'debit': sum(amounts), + }, { + 'name': 'Automatic Transfer (entries with partner(s): partner0, partner1)', + 'account_id': self.origin_accounts[0].id, + 'date_maturity': args[1], + 'credit': sum(amounts), + }] + self.assertListEqual(exp, res, + 'Only first transfer model line should be handled, second should get 0 and thus not be added') + + def test__get_transfer_move_lines_values_partner(self): + """ + Create account moves and transfer, verify that the result of the auto transfer is correct. + """ + amounts = [4242.0, 1234.56] + aaccounts = [self._create_analytic_account('ANAL00')] + partner_ids = [self._create_partner('partner' + str(i))for i in range(2)] + self._create_basic_move( + cred_account=self.destination_accounts[2].id, + deb_account=self.origin_accounts[0].id, + amount=amounts[0], + partner_id=partner_ids[0].id, + date_str='2019-02-01' + ) + self._create_basic_move( + cred_account=self.destination_accounts[3].id, + deb_account=self.origin_accounts[0].id, + amount=amounts[1], + deb_analytic=aaccounts[0].id, + partner_id=partner_ids[1].id, + date_str='2019-02-01' + ) + transfer_model_line_1 = self._add_transfer_model_line(self.destination_accounts[3].id, + analytic_account_ids=[aaccounts[0].id], + partner_ids=[partner_ids[1].id]) + transfer_model_line_2 = self._add_transfer_model_line(self.destination_accounts[2].id, + partner_ids=[partner_ids[0].id]) + + transfer_models_lines = transfer_model_line_1 + transfer_model_line_2 + args = [fields.Date.to_date('2019-01-01'), fields.Date.to_date('2019-12-19')] + res = transfer_models_lines._get_transfer_move_lines_values(*args) + exp = [ + { + 'name': 'Automatic Transfer (from account MA001 with analytic account(s): ANAL00 and partner(s): partner1)', + 'account_id': self.destination_accounts[3].id, + 'date_maturity': args[1], + 'debit': amounts[1], + }, + { + 'name': 'Automatic Transfer (entries with analytic account(s): ANAL00 and partner(s): partner1)', + 'account_id': self.origin_accounts[0].id, + 'date_maturity': args[1], + 'credit': amounts[1], + }, + { + 'name': 'Automatic Transfer (from account MA001 with partner(s): partner0)', + 'account_id': self.destination_accounts[2].id, + 'date_maturity': args[1], + 'debit': amounts[0], + }, + { + 'name': 'Automatic Transfer (entries with partner(s): partner0)', + 'account_id': self.origin_accounts[0].id, + 'date_maturity': args[1], + 'credit': amounts[0], + }, + ] + self.assertListEqual(exp, res) diff --git a/odex25_accounting/odex25_account_auto_transfer/views/transfer_model_views.xml b/odex25_accounting/odex25_account_auto_transfer/views/transfer_model_views.xml new file mode 100644 index 000000000..48396f05a --- /dev/null +++ b/odex25_accounting/odex25_account_auto_transfer/views/transfer_model_views.xml @@ -0,0 +1,128 @@ + + + + + account.auto.transfer.search + account.move + + + + + + + + + + + + Automatic Transfers + account.transfer.model + tree,form + + + + + Generated Entries + ir.actions.act_window + account.move + tree,form + + + + + + + + + + + account.auto.transfer.model.tree + account.transfer.model + + + + + + + + + + + + + account.auto.transfer.model.form + account.transfer.model + +
    +
    +
    + +
    + +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    +
    diff --git a/odex25_accounting/odex25_account_bank_statement_import/__init__.py b/odex25_accounting/odex25_account_bank_statement_import/__init__.py new file mode 100644 index 000000000..8c0c3372d --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import/__init__.py @@ -0,0 +1,5 @@ +# -*- encoding: utf-8 -*- + +from . import odex25_account_bank_statement_import +from . import account_journal +from . import wizard diff --git a/odex25_accounting/odex25_account_bank_statement_import/__manifest__.py b/odex25_accounting/odex25_account_bank_statement_import/__manifest__.py new file mode 100644 index 000000000..425e8576b --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import/__manifest__.py @@ -0,0 +1,26 @@ +# -*- encoding: utf-8 -*- +{ + 'name': 'Account Bank Statement Import', + 'category': 'Odex25-Accounting/Odex25-Accounting', + 'version': '1.0', + 'depends': ['odex25_account_accountant'], + 'description': """Generic Wizard to Import Bank Statements. + +(This module does not include any type of import format.) + +OFX and QIF imports are available in Enterprise version.""", + 'author': "Expert Co. Ltd.", + 'website': "http://www.exp-sa.com", + 'data': [ + 'security/ir.model.access.csv', + 'odex25_account_bank_statement_import_view.xml', + 'account_import_tip_data.xml', + 'wizard/journal_creation.xml', + 'views/odex25_account_bank_statement_import_templates.xml', + ], + 'demo': [ + 'demo/partner_bank.xml', + ], + 'installable': True, + #'auto_install': True, +} diff --git a/odex25_accounting/odex25_account_bank_statement_import/account_import_tip_data.xml b/odex25_accounting/odex25_account_bank_statement_import/account_import_tip_data.xml new file mode 100644 index 000000000..8a71be777 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import/account_import_tip_data.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/odex25_accounting/odex25_account_bank_statement_import/account_journal.py b/odex25_accounting/odex25_account_bank_statement_import/account_journal.py new file mode 100644 index 000000000..c450ed6fc --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import/account_journal.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- + +from odoo import models, api, _ + + +class AccountJournal(models.Model): + _inherit = "account.journal" + + def _get_bank_statements_available_import_formats(self): + """ Returns a list of strings representing the supported import formats. + """ + return [] + + def __get_bank_statements_available_sources(self): + rslt = super(AccountJournal, self).__get_bank_statements_available_sources() + formats_list = self._get_bank_statements_available_import_formats() + if formats_list: + formats_list.sort() + import_formats_str = ', '.join(formats_list) + rslt.append(("file_import", _("Import") + "(" + import_formats_str + ")")) + return rslt + + def import_statement(self): + """return action to import bank/cash statements. This button should be called only on journals with type =='bank'""" + action = self.env['ir.actions.act_window']._for_xml_id( + 'odex25_account_bank_statement_import.action_odex25_account_bank_statement_import') + # Note: this drops action['context'], which is a dict stored as a string, which is not easy to update + action.update({'context': (u"{'journal_id': " + str(self.id) + u"}")}) + return action diff --git a/odex25_accounting/odex25_account_bank_statement_import/demo/partner_bank.xml b/odex25_accounting/odex25_account_bank_statement_import/demo/partner_bank.xml new file mode 100644 index 000000000..ab15c7933 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import/demo/partner_bank.xml @@ -0,0 +1,30 @@ + + + + + + BE68539007547034 + + + + + + 00987654322 + + + + + + 10987654320 + + + + + + 10987654322 + + + + + + diff --git a/odex25_accounting/odex25_account_bank_statement_import/i18n/ar.po b/odex25_accounting/odex25_account_bank_statement_import/i18n/ar.po new file mode 100644 index 000000000..0bb3dd360 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import/i18n/ar.po @@ -0,0 +1,1060 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * odex25_account_bank_statement_import +# +# Translators: +# Sherif Abd Ekmoniem , 2020 +# Sadig Adam , 2020 +# amrnegm , 2020 +# Martin Trigaux, 2020 +# jahzar , 2020 +# Osoul , 2020 +# Mohammed Albasha , 2020 +# Ghaith Gammar , 2020 +# Osama Ahmaro , 2020 +# amal ahmed , 2020 +# Abd El-Rahman Ali , 2020 +# Mahmood Al Halwachi , 2020 +# Zuhair Hammadi , 2020 +# Shaima Safar , 2020 +# Mostafa Hanafy , 2020 +# Nisrine Tagri , 2020 +# Yazeed Dandashi , 2020 +# Tasneem Sarhan , 2020 +# Talal Albahra , 2020 +# Mustafa Rawi , 2020 +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-11-27 13:47+0000\n" +"PO-Revision-Date: 2020-09-07 08:17+0000\n" +"Last-Translator: Mustafa Rawi , 2020\n" +"Language-Team: Arabic (https://www.transifex.com/odoo/teams/41243/ar/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: ar\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" + +#. module: odex25_account_bank_statement_import +#. openerp-web +#: code:addons/odex25_account_bank_statement_import/static/src/js/odex25_account_bank_statement_import.js:0 +#, python-format +msgid " Import Template for Bank Statements" +msgstr "قالب استيراد كشوفات الحسابات البنكية" + +#. module: odex25_account_bank_statement_import +#: code:addons/odex25_account_bank_statement_import/odex25_account_bank_statement_import.py:0 +#, python-format +msgid "%d transactions had already been imported and were ignored." +msgstr "تم تجاهل %d معاملة سبق استيرادها بالفعل." + +#. module: odex25_account_bank_statement_import +#: code:addons/odex25_account_bank_statement_import/odex25_account_bank_statement_import.py:0 +#, python-format +msgid "1 transaction had already been imported and was ignored." +msgstr "تم تجاهل 1 معاملة سبق استيرادها بالفعل." + +#. module: odex25_account_bank_statement_import +#: model:ir.model.constraint,message:odex25_account_bank_statement_import.constraint_account_bank_statement_line_unique_import_id +msgid "A bank account transactions can be imported only once !" +msgstr "يمكن استيراد معاملات الحساب البنكي مرة واحدة فقط!" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__company_partner_id +msgid "Account Holder" +msgstr "مالك الحساب" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__bank_acc_number +msgid "Account Number" +msgstr "رقم الحساب" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__account_online_account_id +msgid "Account Online Account" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__account_online_journal_id +msgid "Account Online Journal" +msgstr "دفتر يومية الحساب" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__account_online_link_id +msgid "Account Online Link" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__account_online_provider_id +msgid "Account Online Provider" +msgstr "مزود الحساب" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__message_needaction +msgid "Action Needed" +msgstr "إجراء مطلوب" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__active +msgid "Active" +msgstr "نشط" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__activity_ids +msgid "Activities" +msgstr "الأنشطة" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__activity_exception_decoration +msgid "Activity Exception Decoration" +msgstr "زخرفة استثناء النشاط" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__activity_state +msgid "Activity State" +msgstr "حالة النشاط" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__sale_activity_note +msgid "Activity Summary" +msgstr "مخلص النشاطات" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__activity_type_icon +msgid "Activity Type Icon" +msgstr "أيقونة نوع النشاط" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__sale_activity_user_id +msgid "Activity User" +msgstr "مسؤول النشاط" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__sale_activity_type_id +msgid "" +"Activity will be automatically scheduled on payment due date, improving " +"collection process." +msgstr "" +"النشاط ستتم جدولته تلقائياً بحسب تاريخ استحقاق الدفعة، لتحسين عملية التحصيل." + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__alias_name +msgid "Alias Name" +msgstr "اسم اللقب" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__alias_domain +msgid "Alias domain" +msgstr "نطاق اللقب" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__type_control_ids +msgid "Allowed account types" +msgstr "أنواع الحسابات المسموحة" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__account_control_ids +msgid "Allowed accounts" +msgstr "الحسابات المسموحة" + +#. module: odex25_account_bank_statement_import +#: code:addons/odex25_account_bank_statement_import/odex25_account_bank_statement_import.py:0 +#, python-format +msgid "Already imported items" +msgstr "عناصر تم استيرادها بالفعل" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__at_least_one_inbound +msgid "At Least One Inbound" +msgstr "وارد واحد على الأقل" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__at_least_one_outbound +msgid "At Least One Outbound" +msgstr "صادر واحد على الاقل" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__message_attachment_count +msgid "Attachment Count" +msgstr "عدد المرفقات" + +#. module: odex25_account_bank_statement_import +#: code:addons/odex25_account_bank_statement_import/odex25_account_bank_statement_import.py:0 +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__bank_id +#, python-format +msgid "Bank" +msgstr "البنك" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__bank_account_id +msgid "Bank Account" +msgstr "حساب بنكي" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__bank_statements_source +msgid "Bank Feeds" +msgstr "التغذية البنكية" + +#. module: odex25_account_bank_statement_import +#: model_terms:ir.ui.view,arch_db:odex25_account_bank_statement_import.odex25_account_bank_statement_import_journal_creation_view +msgid "Bank Journal Name" +msgstr "اسم دفتر اليومية" + +#. module: odex25_account_bank_statement_import +#: model:ir.model,name:odex25_account_bank_statement_import.model_account_bank_statement_line +msgid "Bank Statement Line" +msgstr "بند كشف الحساب البنكي" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__bank_statement_creation_groupby +msgid "Bank Statements Group By" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model,name:odex25_account_bank_statement_import.model_account_setup_bank_manual_config +msgid "Bank setup manual config" +msgstr "الضبط اليدوي لإعدادات البنك" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__suspense_account_id +msgid "" +"Bank statements transactions will be posted on the suspense account until " +"the final reconciliation allowing finding the right account." +msgstr "" +"معاملات كشف البنك سيتم ترحيلها إلى حساب المتعلقات إلى أن يتم إجراء المطابقة " +"النهائية لإتاحة إيجاد الحساب الصحيح." + +#. module: odex25_account_bank_statement_import +#: model_terms:ir.ui.view,arch_db:odex25_account_bank_statement_import.odex25_account_bank_statement_import_journal_creation_view +#: model_terms:ir.ui.view,arch_db:odex25_account_bank_statement_import.odex25_account_bank_statement_import_view +msgid "Cancel" +msgstr "الغاء" + +#. module: odex25_account_bank_statement_import +#: code:addons/odex25_account_bank_statement_import/odex25_account_bank_statement_import.py:0 +#, python-format +msgid "" +"Cannot find in which journal import this statement. Please manually select a" +" journal." +msgstr "" +"لم نتمكن من اكتشاف لأي دفتر يومية يتم استيراد كشف الحساب المحدد. نرجو منكم " +"اختيار دفتر اليومية يدوياً." + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__check_printing_payment_method_selected +msgid "Check Printing Payment Method Selected" +msgstr "تم اختيار السداد بطباعة شيك" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__check_sequence_id +msgid "Check Sequence" +msgstr "مسلسل الشيك" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__refund_sequence +msgid "" +"Check this box if you don't want to share the same sequence for invoices and" +" credit notes made from this journal" +msgstr "" +"حدد هذا المربع إذا كنت لا تريد أن تتشارك الفواتير وإشعارات الخصم المستخرجة " +"من دفتر اليومية هذا نفس التسلسل" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__check_manual_sequencing +msgid "Check this option if your pre-printed checks are not numbered." +msgstr "حدد هذا الاختيار إذا كانت شيكاتك المطبوعة مسبقًا غير مُرقمة." + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__check_sequence_id +msgid "Checks numbering sequence." +msgstr "تسلسل أرقام الشيكات." + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__color +msgid "Color Index" +msgstr "معرف اللون" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__invoice_reference_model +msgid "Communication Standard" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__invoice_reference_type +msgid "Communication Type" +msgstr "نوع التواصل" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__company_id +msgid "Company" +msgstr "شركة" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__company_id +msgid "Company related to this journal" +msgstr "المؤسسة المرتبطة بدفتر اليومية هذا" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__compatible_edi_ids +msgid "Compatible Edi" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: code:addons/odex25_account_bank_statement_import/odex25_account_bank_statement_import.py:0 +#, python-format +msgid "" +"Could not make sense of the given file.\n" +"Did you install the module to support this type of file ?" +msgstr "" +"لم يمكن فهم طبيعة الملف المحدد.\n" +"هل قمت بتثبيت الموديول لدعم هذا النوع من الملفات؟" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__country_code +msgid "Country Code" +msgstr "رمز الدولة" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import__create_uid +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__create_uid +msgid "Created by" +msgstr "أنشئ بواسطة" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import__create_date +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__create_date +msgid "Created on" +msgstr "أنشئ في" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__bank_statement_creation +msgid "Creation of Bank Statements" +msgstr "إنشاء كشوف حسابات بنكية" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__currency_id +msgid "Currency" +msgstr "العملة" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__refund_sequence +msgid "Dedicated Credit Note Sequence" +msgstr "مسلسل إشعارات الخصم المخصصة" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__default_account_id +msgid "Default Account" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__default_account_type +msgid "Default Account Type" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__bank_statements_source +msgid "Defines how the bank statements will be registered" +msgstr "يحدد كيفية تسجيل كشوفات الحساب البنكية" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__bank_statement_creation +msgid "" +"Defines when a new bank statement\n" +" will be created when fetching new transactions\n" +" from your bank account." +msgstr "" +"يحدد متى سيتم إنشاء كشف حساب بنكي جديد\n" +" \n" +"عند إرسال معاملات جديدة\n" +" من حسابك البنكي." + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__bank_statement_creation_groupby +msgid "" +"Defines when a new bank statement will be created when fetching new " +"transactions from your bank account." +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import__display_name +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__display_name +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_account_bank_statement_line__display_name +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_account_journal__display_name +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_account_setup_bank_manual_config__display_name +msgid "Display Name" +msgstr "الاسم المعروض" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__compatible_edi_ids +msgid "EDI format that support moves in this journal" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__edi_format_ids +msgid "Electronic invoicing" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__alias_id +msgid "Email Alias" +msgstr "لقب البريد الإلكتروني" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import__attachment_ids +msgid "Files" +msgstr "الملفات" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__message_follower_ids +msgid "Followers" +msgstr "المتابعون" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__message_channel_ids +msgid "Followers (Channels)" +msgstr "المتابعون (القنوات)" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__message_partner_ids +msgid "Followers (Partners)" +msgstr "المتابعون (الشركاء)" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__activity_type_icon +msgid "Font awesome icon e.g. fa-tasks" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import__attachment_ids +msgid "" +"Get you bank statements in electronic format from your bank and select them " +"here." +msgstr "احصل على كشوفات حسابك بصيغة إلكترونية واخترها من هنا." + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import__id +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__id +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_account_bank_statement_line__id +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_account_journal__id +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_account_setup_bank_manual_config__id +msgid "ID" +msgstr "المُعرف" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__activity_exception_icon +msgid "Icon" +msgstr "الأيقونة" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__activity_exception_icon +msgid "Icon to indicate an exception activity." +msgstr "الأيقونة للإشارة إلى استثناء النشاط" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__message_needaction +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__message_unread +msgid "If checked, new messages require your attention." +msgstr "إذا كان محددًا، فهناك رسائل جديدة تحتاج لرؤيتها." + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__message_has_error +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__message_has_sms_error +msgid "If checked, some messages have a delivery error." +msgstr "إذا كان محددًا، فقد حدث خطأ في تسليم بعض الرسائل." + +#. module: odex25_account_bank_statement_import +#: code:addons/odex25_account_bank_statement_import/odex25_account_bank_statement_import.py:0 +#, python-format +msgid "" +"If it contains transactions for more than one account, it must be imported " +"on each of them." +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__restrict_mode_hash_table +msgid "" +"If ticked, the accounting entry or invoice receives a hash as soon as it is " +"posted and cannot be modified anymore." +msgstr "" + +#. module: odex25_account_bank_statement_import +#: code:addons/odex25_account_bank_statement_import/account_journal.py:0 +#: model_terms:ir.ui.view,arch_db:odex25_account_bank_statement_import.journal_dashboard_view_inherit +#, python-format +msgid "Import" +msgstr "استيراد" + +#. module: odex25_account_bank_statement_import +#: model:ir.model,name:odex25_account_bank_statement_import.model_odex25_account_bank_statement_import +msgid "Import Bank Statement" +msgstr "استيراد كشف حساب بنكي" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_account_bank_statement_line__unique_import_id +msgid "Import ID" +msgstr "معرف الاستيراد" + +#. module: odex25_account_bank_statement_import +#: model_terms:ir.ui.view,arch_db:odex25_account_bank_statement_import.journal_dashboard_view_inherit +msgid "Import Statement" +msgstr "استيراد كشف حساب" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__inbound_payment_method_ids +msgid "Inbound Payment Methods" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__payment_debit_account_id +msgid "" +"Incoming payments entries triggered by invoices/refunds will be posted on " +"the Outstanding Receipts Account and displayed as blue lines in the bank " +"reconciliation widget. During the reconciliation process, concerned " +"transactions will be reconciled with entries on the Outstanding Receipts " +"Account instead of the receivable account." +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.actions.act_window,name:odex25_account_bank_statement_import.install_more_import_formats_action +msgid "Install Import Format" +msgstr "تثبيت موديول صيغة الاستيراد" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__message_is_follower +msgid "Is Follower" +msgstr "متابع" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__alias_name +msgid "It creates draft invoices and bills by sending an email." +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model,name:odex25_account_bank_statement_import.model_account_journal +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__journal_id +msgid "Journal" +msgstr "دفتر اليومية" + +#. module: odex25_account_bank_statement_import +#: code:addons/odex25_account_bank_statement_import/odex25_account_bank_statement_import.py:0 +#: model_terms:ir.ui.view,arch_db:odex25_account_bank_statement_import.odex25_account_bank_statement_import_journal_creation_view +#, python-format +msgid "Journal Creation" +msgstr "إنشاء دفتر يومية" + +#. module: odex25_account_bank_statement_import +#: model:ir.model,name:odex25_account_bank_statement_import.model_odex25_account_bank_statement_import_journal_creation +msgid "Journal Creation on Bank Statement Import" +msgstr "إنشاء دفتر يومية عند استيراد كشف الحساب البنكي" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__journal_group_ids +msgid "Journal Groups" +msgstr "مجموعات الدفاتر اليومية" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__name +msgid "Journal Name" +msgstr "اسم دفتر اليومية" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__json_activity_data +msgid "Json Activity Data" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model_terms:ir.ui.view,arch_db:odex25_account_bank_statement_import.odex25_account_bank_statement_import_journal_creation_view +msgid "" +"Just click OK to create the account/journal and finish the upload. If this " +"was a mistake, hit cancel to abort the upload." +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__kanban_dashboard +msgid "Kanban Dashboard" +msgstr "لوحة معلومات كانبان" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__kanban_dashboard_graph +msgid "Kanban Dashboard Graph" +msgstr "الرسم البياني للوحة معلومات كانبان" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import____last_update +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation____last_update +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_account_bank_statement_line____last_update +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_account_journal____last_update +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_account_setup_bank_manual_config____last_update +msgid "Last Modified on" +msgstr "آخر تعديل في" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import__write_uid +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__write_uid +msgid "Last Updated by" +msgstr "آخر تحديث بواسطة" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import__write_date +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__write_date +msgid "Last Updated on" +msgstr "آخر تحديث في" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__sale_activity_user_id +msgid "Leave empty to assign the Salesperson of the invoice." +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__restrict_mode_hash_table +msgid "Lock Posted Entries with Hash" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__loss_account_id +msgid "Loss Account" +msgstr "حساب الخسارة" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__message_main_attachment_id +msgid "Main Attachment" +msgstr "المرفق الرئيسي" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__check_manual_sequencing +msgid "Manual Numbering" +msgstr "ترقيم يدوي" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__inbound_payment_method_ids +msgid "" +"Manual: Get paid by cash, check or any other method outside of Odoo.\n" +"Electronic: Get paid automatically through a payment acquirer by requesting a transaction on a card saved by the customer when buying or subscribing online (payment token).\n" +"Batch Deposit: Encase several customer checks at once by generating a batch deposit to submit to your bank. When encoding the bank statement in Odoo,you are suggested to reconcile the transaction with the batch deposit. Enable this option from the settings." +msgstr "" +"يدويًا: تتلقى أموالك نقدًا أو بشيكات أو بأي طريقة أخرى خارج أودو.\n" +"إلكترونيًا: تتلقى أموالك تلقائيًا باستخدام معالج سداد من خلال طلب معاملة مالية على بطاقة مخزنة للعميل عند الشراء أو الاشتراك عبر الإنترنت (من خلال رمز السداد السري).\n" +"إيداع دفعات: تغطي تكلفة عدة شيكات في نفس الوقت من خلال إيداع عدة دفعات. عند تشفير كشف الحساب على أودو، ننصح بأن تقوم بتسوية المعاملة بنظام إيداع الدفعات. فعل هذا الاختيار من الإعدادات." + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__outbound_payment_method_ids +msgid "" +"Manual:Pay bill by cash or any other method outside of Odoo.\n" +"Check:Pay bill by check and print it from Odoo.\n" +"SEPA Credit Transfer: Pay bill from a SEPA Credit Transfer file you submit to your bank. Enable this option from the settings." +msgstr "" +"يدويًا: تتلقى أموالك نقدًا أو بشيكات أو بأي طريقة أخرى خارج أودو.\n" +"شيك: تسدد قيمة فواتيرك بالشيكات وتطبعها من أودو. \n" +"النقل الائتماني بنظام SEPA: ادفع الفاتورة من خلال ملف نقل ائتماني تقوم بتسليمه للبنك، قم بتفعيل هذا الخيار من الإعدادات." + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__message_has_error +msgid "Message Delivery error" +msgstr "خطأ في تسليم الرسائل" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__message_ids +msgid "Messages" +msgstr "الرسائل" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__activity_date_deadline +msgid "Next Activity Deadline" +msgstr "الموعد النهائي للنشاط التالي" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__activity_summary +msgid "Next Activity Summary" +msgstr "ملخص النشاط التالي" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__activity_type_id +msgid "Next Activity Type" +msgstr "نوع النشاط التالي" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__check_next_number +msgid "Next Check Number" +msgstr "رقم الشيك التالي" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__next_synchronization +msgid "Next synchronization" +msgstr "المزامنة التالية" + +#. module: odex25_account_bank_statement_import +#: code:addons/odex25_account_bank_statement_import/odex25_account_bank_statement_import.py:0 +#, python-format +msgid "No currency found matching '%s'." +msgstr "لم يمكن العثور على أي عملة تطابق '%s'." + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__message_needaction_counter +msgid "Number of Actions" +msgstr "عدد الإجراءات" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__message_has_error_counter +msgid "Number of errors" +msgstr "عدد الاخطاء" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__message_needaction_counter +msgid "Number of messages which requires an action" +msgstr "عدد الرسائل التي تتطلب إجراء" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "عدد الرسائل الحادث بها خطأ في التسليم" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__message_unread_counter +msgid "Number of unread messages" +msgstr "عدد الرسائل الجديدة" + +#. module: odex25_account_bank_statement_import +#: model_terms:ir.ui.view,arch_db:odex25_account_bank_statement_import.odex25_account_bank_statement_import_journal_creation_view +msgid "OK" +msgstr "موافق" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__next_link_synchronization +msgid "Online Link Next synchronization" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__outbound_payment_method_ids +msgid "Outbound Payment Methods" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__payment_credit_account_id +msgid "" +"Outgoing payments entries triggered by bills/credit notes will be posted on " +"the Outstanding Payments Account and displayed as blue lines in the bank " +"reconciliation widget. During the reconciliation process, concerned " +"transactions will be reconciled with entries on the Outstanding Payments " +"Account instead of the payable account." +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__payment_credit_account_id +msgid "Outstanding Payments Account" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__payment_debit_account_id +msgid "Outstanding Receipts Account" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__profit_account_id +msgid "Profit Account" +msgstr "حساب الربح" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__activity_user_id +msgid "Responsible User" +msgstr "المستخدم المسؤول" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__message_has_sms_error +msgid "SMS Delivery error" +msgstr "خطأ في تسليم الرسائل القصيرة" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__sale_activity_type_id +msgid "Schedule Activity" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__secure_sequence_id +msgid "Secure Sequence" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__type +msgid "" +"Select 'Sale' for customer invoices journals.\n" +"Select 'Purchase' for vendor bills journals.\n" +"Select 'Cash' or 'Bank' for journals that are used in customer or vendor payments.\n" +"Select 'General' for miscellaneous operations journals." +msgstr "" +"اختر 'بيع' لعرض دفاتر اليومية الخاصة بفواتير العملاء. \n" +"اختر 'شراء' لعرض دفاتر اليومية الخاصة بفواتير الموردين. \n" +"اختر 'نقدي' أو 'بنك' لعرض دفاتر اليومية الخاصة بمدفوعات العميل أو المورد.\n" +" اختر 'عام' لعرض دفاتر اليومية الخاصة بالعمليات المتنوعة." + +#. module: odex25_account_bank_statement_import +#: model_terms:ir.ui.view,arch_db:odex25_account_bank_statement_import.odex25_account_bank_statement_import_view +msgid "Select Files" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__edi_format_ids +msgid "Send XML/EDI invoices" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__alias_id +msgid "" +"Send one separate email for each invoice.\n" +"\n" +"Any file extension will be accepted.\n" +"\n" +"Only PDF and XML files will be interpreted by Odoo" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__sequence +msgid "Sequence" +msgstr "المسلسل" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__sequence_override_regex +msgid "Sequence Override Regex" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__check_next_number +msgid "Sequence number of the next printed check." +msgstr "الرقم المسلسل للشيك المطبوع التالي." + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__secure_sequence_id +msgid "Sequence to use to ensure the securisation of data" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__active +msgid "Set active to false to hide the Journal without removing it." +msgstr "قم بإزالة العلامة من الحقل نشط لإخفاء دفتر اليومية دون إزالته." + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__code +msgid "Short Code" +msgstr "الكود المختصر" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__code +msgid "" +"Shorter name used for display. The journal entries of this journal will also" +" be named using this prefix by default." +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__show_on_dashboard +msgid "Show journal on dashboard" +msgstr "إظهار دفتر اليومية في لوحة المعلومات" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__account_online_link_state +msgid "State" +msgstr "المحافظة" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__activity_state +msgid "" +"Status based on activities\n" +"Overdue: Due date is already passed\n" +"Today: Activity date is today\n" +"Planned: Future activities." +msgstr "" +"الحالة على أساس الأنشطة\n" +"المتأخرة: تاريخ الاستحقاق مر\n" +"اليوم: تاريخ النشاط هو اليوم\n" +"المخطط: الأنشطة المستقبلية." + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__suspense_account_id +msgid "Suspense Account" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__synchronization_status +msgid "Synchronization status" +msgstr "حالة المزامنة" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__check_printing_payment_method_selected +msgid "" +"Technical feature used to know whether check printing was enabled as payment" +" method." +msgstr "حقل تقني يُستخدم لتحديد ما إن كان خيار طباعة شيك مفعلًا كطريقة للدفع." + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__sequence_override_regex +msgid "" +"Technical field used to enforce complex sequence composition that the system would normally misunderstand.\n" +"This is a regex that can include all the following capture groups: prefix1, year, prefix2, month, prefix3, seq, suffix.\n" +"The prefix* groups are the separators between the year, month and the actual increasing sequence number (seq).\n" +"e.g: ^(?P.*?)(?P\\d{4})(?P\\D*?)(?P\\d{2})(?P\\D+?)(?P\\d+)(?P\\D*?)$" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__country_code +msgid "" +"The ISO country code in two chars. \n" +"You can use this field for quick search." +msgstr "" +"كود الدولة حسب المعيار الدولي أيزو المكون من حرفين.\n" +"يمكنك استخدام هذا الحقل لإجراء بحث سريع." + +#. module: odex25_account_bank_statement_import +#: model_terms:ir.ui.view,arch_db:odex25_account_bank_statement_import.odex25_account_bank_statement_import_journal_creation_view +msgid "" +"The account of the statement you are uploading is not yet recorded in Odoo. " +"In order to proceed with the upload, you need to create a bank journal for " +"this account." +msgstr "" + +#. module: odex25_account_bank_statement_import +#: code:addons/odex25_account_bank_statement_import/odex25_account_bank_statement_import.py:0 +#, python-format +msgid "" +"The account of this statement (%s) is not the same as the journal (%s)." +msgstr "الحساب في كشف الحساب البنكي (%s) مختلف عن حساب دفتر اليومية (%s)." + +#. module: odex25_account_bank_statement_import +#: code:addons/odex25_account_bank_statement_import/odex25_account_bank_statement_import.py:0 +#, python-format +msgid "" +"The currency of the bank statement (%s) is not the same as the currency of " +"the journal (%s)." +msgstr "" +"العملة في كشف الحساب البنكي (%s) مختلفة عن العملة في دفتر اليومية (%s)." + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__currency_id +msgid "The currency used to enter statement" +msgstr "العملة المستخدمة في إدخال كشف الحساب البنكي" + +#. module: odex25_account_bank_statement_import +#: code:addons/odex25_account_bank_statement_import/odex25_account_bank_statement_import.py:0 +#, python-format +msgid "This file doesn't contain any statement for account %s." +msgstr "" + +#. module: odex25_account_bank_statement_import +#: code:addons/odex25_account_bank_statement_import/odex25_account_bank_statement_import.py:0 +#, python-format +msgid "This file doesn't contain any transaction for account %s." +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__type +msgid "Type" +msgstr "النوع" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__activity_exception_decoration +msgid "Type of the exception activity on record." +msgstr "نوع النشاط الاستثنائي المسجل." + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__message_unread +msgid "Unread Messages" +msgstr "الرسائل الجديدة" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__message_unread_counter +msgid "Unread Messages Counter" +msgstr "عدد الرسائل الجديدة" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__synchronization_status +msgid "Update status of provider account" +msgstr "تحديث حالة حساب المزود" + +#. module: odex25_account_bank_statement_import +#: model:ir.actions.act_window,name:odex25_account_bank_statement_import.action_odex25_account_bank_statement_import +#: model_terms:ir.ui.view,arch_db:odex25_account_bank_statement_import.odex25_account_bank_statement_import_view +msgid "Upload" +msgstr "رفع" + +#. module: odex25_account_bank_statement_import +#: model_terms:ir.ui.view,arch_db:odex25_account_bank_statement_import.odex25_account_bank_statement_import_view +msgid "Upload Bank Statements" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__sequence +msgid "Used to order Journals in the dashboard view" +msgstr "يُستخدم لترتيب دفاتر اليومية في واجهة لوحة المعلومات" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__loss_account_id +msgid "" +"Used to register a loss when the ending balance of a cash register differs " +"from what the system computes" +msgstr "" +"يُستخدم لتسجيل خسارة عندما يكون الرصيد الختامي لصندوق نقدية مختلف عما يحسبه " +"النظام" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__profit_account_id +msgid "" +"Used to register a profit when the ending balance of a cash register differs" +" from what the system computes" +msgstr "" +"يُستخدم لتسجيل ربح عندما يكون الرصيد الختامي لصندوق نقدية مختلف عما يحسبه " +"النظام" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__website_message_ids +msgid "Website Messages" +msgstr "رسائل الموقع" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__website_message_ids +msgid "Website communication history" +msgstr "سجل تواصل الموقع" + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__show_on_dashboard +msgid "Whether this journal should be displayed on the dashboard or not" +msgstr "ما إذا كان ينبغي عرض دفتر اليومية هذا في لوحة المعلومات أم لا" + +#. module: odex25_account_bank_statement_import +#: code:addons/odex25_account_bank_statement_import/odex25_account_bank_statement_import.py:0 +#, python-format +msgid "You already have imported that file." +msgstr "لقد قمت باستيراد هذا الملف بالفعل." + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__invoice_reference_model +msgid "" +"You can choose different models for each type of reference. The default one " +"is the Odoo reference." +msgstr "تستطيع اختيار نماذج مختلفة لكل مرجع. المرجع الإفتراضي هو مرجع أودو." + +#. module: odex25_account_bank_statement_import +#: model:ir.model.fields,help:odex25_account_bank_statement_import.field_odex25_account_bank_statement_import_journal_creation__invoice_reference_type +msgid "" +"You can set here the default communication that will appear on customer " +"invoices, once validated, to help the customer to refer to that particular " +"invoice when making the payment." +msgstr "" +"يمكنك من هنا تعيين وسيلة التواصل الافتراضية التي ستظهر على فواتير العميل " +"بمجرد اعتمادها، لمساعدة العميل على العودة لتلك الفاتورة تحديدًا عند القيام " +"بعملية السداد." + +#. module: odex25_account_bank_statement_import +#: model_terms:ir.ui.view,arch_db:odex25_account_bank_statement_import.odex25_account_bank_statement_import_view +msgid "You can upload your bank statement using:" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: code:addons/odex25_account_bank_statement_import/odex25_account_bank_statement_import.py:0 +#, python-format +msgid "You have to set a Default Account for the journal: %s" +msgstr "" + +#. module: odex25_account_bank_statement_import +#: model_terms:ir.ui.view,arch_db:odex25_account_bank_statement_import.journal_dashboard_view_inherit +msgid "or" +msgstr "أو" diff --git a/odex25_accounting/odex25_account_bank_statement_import/odex25_account_bank_statement_import.py b/odex25_accounting/odex25_account_bank_statement_import/odex25_account_bank_statement_import.py new file mode 100644 index 000000000..e9c0c4654 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import/odex25_account_bank_statement_import.py @@ -0,0 +1,299 @@ +# -*- coding: utf-8 -*- + +import base64 + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError +from odoo.addons.base.models.res_bank import sanitize_account_number + +import logging +_logger = logging.getLogger(__name__) + + +class AccountBankStatementLine(models.Model): + _inherit = "account.bank.statement.line" + + # Ensure transactions can be imported only once (if the import format provides unique transaction ids) + unique_import_id = fields.Char(string='Import ID', readonly=True, copy=False) + + _sql_constraints = [ + ('unique_import_id', 'unique (unique_import_id)', 'A bank account transactions can be imported only once !') + ] + + +class AccountBankStatementImport(models.TransientModel): + _name = 'account.bank.statement.import' + _description = 'Import Bank Statement' + + attachment_ids = fields.Many2many('ir.attachment', string='Files', required=True, help='Get you bank statements in electronic format from your bank and select them here.') + + def import_file(self): + """ Process the file chosen in the wizard, create bank statement(s) and go to reconciliation. """ + self.ensure_one() + statement_ids_all = [] + statement_line_ids_all = [] + notifications_all = [] + # Let the appropriate implementation module parse the file and return the required data + # The active_id is passed in context in case an implementation module requires information about the wizard state (see QIF) + for data_file in self.attachment_ids: + currency_code, account_number, stmts_vals = self.with_context(active_id=self.ids[0])._parse_file(base64.b64decode(data_file.datas)) + # Check raw data + self._check_parsed_data(stmts_vals, account_number) + # Try to find the currency and journal in odoo + currency, journal = self._find_additional_data(currency_code, account_number) + # If no journal found, ask the user about creating one + if not journal: + # The active_id is passed in context so the wizard can call import_file again once the journal is created + return self.with_context(active_id=self.ids[0])._journal_creation_wizard(currency, account_number) + if not journal.default_account_id: + raise UserError(_('You have to set a Default Account for the journal: %s') % (journal.name,)) + # Prepare statement data to be used for bank statements creation + stmts_vals = self._complete_stmts_vals(stmts_vals, journal, account_number) + # Create the bank statements + statement_ids, statement_line_ids, notifications = self._create_bank_statements(stmts_vals) + statement_ids_all.extend(statement_ids) + statement_line_ids_all.extend(statement_line_ids) + notifications_all.extend(notifications) + + # Now that the import worked out, set it as the bank_statements_source of the journal + if journal.bank_statements_source != 'file_import': + # Use sudo() because only 'account.group_account_manager' + # has write access on 'account.journal', but 'account.group_account_user' + # must be able to import bank statement files + journal.sudo().bank_statements_source = 'file_import' + + # Post the warnings on the statements + msg = "" + for notif in notifications: + msg += ( + f"{notif['message']}

    " + f"{notif['details']['name']}
    " + f"{notif['details']['model']}
    " + f"{notif['details']['ids']}

    " + ) + if msg: + statements = self.env['account.bank.statement'].browse(statement_ids) + for statement in statements: + statement.message_post(body=msg) + + statements = self.env['account.bank.statement'].browse(statement_ids_all) + # Dispatch to reconciliation interface if all statements are posted. + if all(s.state == 'posted' for s in statements): + return { + 'type': 'ir.actions.client', + 'tag': 'bank_statement_reconciliation_view', + 'context': {'statement_line_ids': statement_line_ids_all, + 'company_ids': self.env.user.company_ids.ids, + 'notifications': notifications_all, + }, + } + + # Dispatch to the statemtent list/form view instead. + result = self.env['ir.actions.act_window']._for_xml_id('account.action_bank_statement_tree') + if len(statements) > 1: + result['domain'] = [('id', 'in', statements.ids)] + elif len(statements) == 1: + form = self.env.ref('account.view_bank_statement_form', False) + form_view = [(form.id if form else False, 'form')] + if 'views' in result: + result['views'] = form_view + [(state, view) for state, view in result['views'] if view != 'form'] + else: + result['views'] = form_view + result['res_id'] = statements.id + else: + result = {'type': 'ir.actions.act_window_close'} + return result + + def _journal_creation_wizard(self, currency, account_number): + """ Calls a wizard that allows the user to carry on with journal creation """ + return { + 'name': _('Journal Creation'), + 'type': 'ir.actions.act_window', + 'res_model': 'account.bank.statement.import.journal.creation', + 'view_mode': 'form', + 'target': 'new', + 'context': { + 'statement_import_transient_id': self.env.context['active_id'], + 'default_bank_acc_number': account_number, + 'default_name': _('Bank') + ' ' + account_number, + 'default_currency_id': currency and currency.id or False, + 'default_type': 'bank', + } + } + + def _parse_file(self, data_file): + """ Each module adding a file support must extends this method. It processes the file if it can, returns super otherwise, resulting in a chain of responsability. + This method parses the given file and returns the data required by the bank statement import process, as specified below. + rtype: triplet (if a value can't be retrieved, use None) + - currency code: string (e.g: 'EUR') + The ISO 4217 currency code, case insensitive + - account number: string (e.g: 'BE1234567890') + The number of the bank account which the statement belongs to + - bank statements data: list of dict containing (optional items marked by o) : + - 'name': string (e.g: '000000123') + - 'date': date (e.g: 2013-06-26) + -o 'balance_start': float (e.g: 8368.56) + -o 'balance_end_real': float (e.g: 8888.88) + - 'transactions': list of dict containing : + - 'name': string (e.g: 'KBC-INVESTERINGSKREDIET 787-5562831-01') + - 'date': date + - 'amount': float + - 'unique_import_id': string + -o 'account_number': string + Will be used to find/create the res.partner.bank in odoo + -o 'note': string + -o 'partner_name': string + -o 'ref': string + """ + raise UserError(_('Could not make sense of the given file.\nDid you install the module to support this type of file ?')) + + def _check_parsed_data(self, stmts_vals, account_number): + """ Basic and structural verifications """ + extra_msg = _('If it contains transactions for more than one account, it must be imported on each of them.') + if len(stmts_vals) == 0: + raise UserError( + _('This file doesn\'t contain any statement for account %s.') % (account_number,) + + '\n' + extra_msg + ) + + no_st_line = True + for vals in stmts_vals: + if vals['transactions'] and len(vals['transactions']) > 0: + no_st_line = False + break + if no_st_line: + raise UserError( + _('This file doesn\'t contain any transaction for account %s.') % (account_number,) + + '\n' + extra_msg + ) + + def _check_journal_bank_account(self, journal, account_number): + # Needed for CH to accommodate for non-unique account numbers + sanitized_acc_number = journal.bank_account_id.sanitized_acc_number.split(" ")[0] + return sanitized_acc_number == account_number + + def _find_additional_data(self, currency_code, account_number): + """ Look for a res.currency and account.journal using values extracted from the + statement and make sure it's consistent. + """ + company_currency = self.env.company.currency_id + journal_obj = self.env['account.journal'] + currency = None + sanitized_account_number = sanitize_account_number(account_number) + + if currency_code: + currency = self.env['res.currency'].search([('name', '=ilike', currency_code)], limit=1) + if not currency: + raise UserError(_("No currency found matching '%s'.", currency_code)) + if currency == company_currency: + currency = False + + journal = journal_obj.browse(self.env.context.get('journal_id', [])) + if account_number: + # No bank account on the journal : create one from the account number of the statement + if journal and not journal.bank_account_id: + journal.set_bank_account(account_number) + # No journal passed to the wizard : try to find one using the account number of the statement + elif not journal: + journal = journal_obj.search([('bank_account_id.sanitized_acc_number', '=', sanitized_account_number)]) + # Already a bank account on the journal : check it's the same as on the statement + else: + if not self._check_journal_bank_account(journal, sanitized_account_number): + raise UserError(_('The account of this statement (%s) is not the same as the journal (%s).') % (account_number, journal.bank_account_id.acc_number)) + + # If importing into an existing journal, its currency must be the same as the bank statement + if journal: + journal_currency = journal.currency_id + if currency is None: + currency = journal_currency + if currency and currency != journal_currency: + statement_cur_code = not currency and company_currency.name or currency.name + journal_cur_code = not journal_currency and company_currency.name or journal_currency.name + raise UserError(_('The currency of the bank statement (%s) is not the same as the currency of the journal (%s).') % (statement_cur_code, journal_cur_code)) + + # If we couldn't find / can't create a journal, everything is lost + if not journal and not account_number: + raise UserError(_('Cannot find in which journal import this statement. Please manually select a journal.')) + + return currency, journal + + def _complete_stmts_vals(self, stmts_vals, journal, account_number): + for st_vals in stmts_vals: + st_vals['journal_id'] = journal.id + if not st_vals.get('reference'): + st_vals['reference'] = " ".join(self.attachment_ids.mapped('name')) + for line_vals in st_vals['transactions']: + unique_import_id = line_vals.get('unique_import_id') + if unique_import_id: + sanitized_account_number = sanitize_account_number(account_number) + line_vals['unique_import_id'] = (sanitized_account_number and sanitized_account_number + '-' or '') + str(journal.id) + '-' + unique_import_id + + if not line_vals.get('partner_bank_id'): + # Find the partner and his bank account or create the bank account. The partner selected during the + # reconciliation process will be linked to the bank when the statement is closed. + identifying_string = line_vals.get('account_number') + if identifying_string: + partner_bank = self.env['res.partner.bank'].search([('acc_number', '=', identifying_string)], limit=1) + if partner_bank: + line_vals['partner_bank_id'] = partner_bank.id + line_vals['partner_id'] = partner_bank.partner_id.id + return stmts_vals + + def _create_bank_statements(self, stmts_vals): + """ Create new bank statements from imported values, filtering out already imported transactions, and returns data used by the reconciliation widget """ + BankStatement = self.env['account.bank.statement'] + BankStatementLine = self.env['account.bank.statement.line'] + + # Filter out already imported transactions and create statements + statement_ids = [] + statement_line_ids = [] + ignored_statement_lines_import_ids = [] + for st_vals in stmts_vals: + filtered_st_lines = [] + for line_vals in st_vals['transactions']: + if (line_vals['amount'] != 0 + and ('unique_import_id' not in line_vals + or not line_vals['unique_import_id'] + or not bool(BankStatementLine.sudo().search([('unique_import_id', '=', line_vals['unique_import_id'])], limit=1)))): + filtered_st_lines.append(line_vals) + else: + ignored_statement_lines_import_ids.append(line_vals['unique_import_id']) + if 'balance_start' in st_vals: + st_vals['balance_start'] += float(line_vals['amount']) + + if len(filtered_st_lines) > 0: + # Remove values that won't be used to create records + st_vals.pop('transactions', None) + number = st_vals.pop('number', None) + # Create the statement + st_vals['line_ids'] = [[0, False, line] for line in filtered_st_lines] + statement = BankStatement.create(st_vals) + statement_ids.append(statement.id) + if number and number.isdecimal(): + statement._set_next_sequence() + format, format_values = statement._get_sequence_format_param(statement.name) + format_values['seq'] = int(number) + #build the full name like BNK/2016/00135 by just giving the number '135' + statement.name = format.format(**format_values) + if statement.balance_end == statement.balance_end_real: + statement.button_post() + statement_line_ids.extend(statement.line_ids.ids) + if len(statement_line_ids) == 0: + raise UserError(_('You already have imported that file.')) + + # Prepare import feedback + notifications = [] + num_ignored = len(ignored_statement_lines_import_ids) + if num_ignored > 0: + notifications += [{ + 'type': 'warning', + 'message': _("%d transactions had already been imported and were ignored.", num_ignored) + if num_ignored > 1 + else _("1 transaction had already been imported and was ignored."), + 'details': { + 'name': _('Already imported items'), + 'model': 'account.bank.statement.line', + 'ids': BankStatementLine.search([('unique_import_id', 'in', ignored_statement_lines_import_ids)]).ids + } + }] + return statement_ids, statement_line_ids, notifications diff --git a/odex25_accounting/odex25_account_bank_statement_import/odex25_account_bank_statement_import_view.xml b/odex25_accounting/odex25_account_bank_statement_import/odex25_account_bank_statement_import_view.xml new file mode 100644 index 000000000..d410bb15d --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import/odex25_account_bank_statement_import_view.xml @@ -0,0 +1,55 @@ + + + + + Upload Bank Statements + account.bank.statement.import + 1 + +
    +

    You can upload your bank statement using:

    +
      + +
    + +
    +
    + +
    +
    + + + Install Import Format + ir.module.module + kanban,tree,form + + + + + + Upload + ir.actions.act_window + account.bank.statement.import + form + new + + + + + account.journal.dashboard.kanban.inherit + account.journal + + + + or Import + + + + + + +
    diff --git a/odex25_accounting/odex25_account_bank_statement_import/security/ir.model.access.csv b/odex25_accounting/odex25_account_bank_statement_import/security/ir.model.access.csv new file mode 100644 index 000000000..fcb23383f --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import/security/ir.model.access.csv @@ -0,0 +1,3 @@ +"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" +"access_odex25_account_bank_statement_import","access.account.bank.statement.import","model_account_bank_statement_import","account.group_account_user",1,1,1,0 +"access_odex25_account_bank_statement_import_journal_creation","access.account.bank.statement.import.journal.creation","model_account_bank_statement_import_journal_creation","account.group_account_user",1,1,1,0 diff --git a/odex25_accounting/odex25_account_bank_statement_import/static/csv/account.bank.statement.csv b/odex25_accounting/odex25_account_bank_statement_import/static/csv/account.bank.statement.csv new file mode 100644 index 000000000..7be40fd0a --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import/static/csv/account.bank.statement.csv @@ -0,0 +1,6 @@ +Journal,Name,Date,Starting Balance,Ending Balance,Statement lines / Date,Statement lines / Label,Statement lines / Partner,Statement lines / Reference,Statement lines / Amount,Statement lines / Amount Currency,Statement lines / Currency +Bank,Statement May 01,2017-05-15,100,5124.5,2017-05-10,INV/2017/0001,,#01,4610,, +,,,,,2017-05-11,Payment bill 20170521,,#02,-100,, +,,,,,2017-05-15,INV/2017/0003 discount 2% early payment,,#03,514.5,, +Bank,Statement May 02,2017-05-30,5124.5,9847.35,2017-05-30,INV/2017/0002 + INV/2017/0004,,#01,5260,, +,,,,,2017-05-31,Payment bill EUR 001234565,,#02,-537.15,-500,EUR diff --git a/odex25_accounting/odex25_account_bank_statement_import/static/description/icon.png b/odex25_accounting/odex25_account_bank_statement_import/static/description/icon.png new file mode 100644 index 000000000..4141f52da Binary files /dev/null and b/odex25_accounting/odex25_account_bank_statement_import/static/description/icon.png differ diff --git a/odex25_accounting/odex25_account_bank_statement_import/static/description/icon_src.svg b/odex25_accounting/odex25_account_bank_statement_import/static/description/icon_src.svg new file mode 100644 index 000000000..664381e08 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import/static/description/icon_src.svg @@ -0,0 +1,178 @@ + +image/svg+xml08/12/13 1000.00 Delta PC08/15/13 75.46 Walts Drugs03/03/13 379.00 Epic Technologies03/04/13 20.28 YOUR LOCAL SU03/03/13 421.35 SPRINGFIELD WA03/03/13 379.00 Epic Technologies03/04/13 20.28 YOUR LOCAL SUP08/15/13 75.46 Walts Drugs08/12/13 1000.00 Delta PC03/03/13 421.35 SPRINGFIELD WA03/04/13 20.28 YOUR LOCAL SU03/03/13 379.00 Epic Technologies08/12/13 1000.00 De a PC03/03/13 379.00 E Technologies08/15/13 75.46 Walts Drugs03/04/13 20.28 YOUR LOCAL SU03/03/13 379.00 Epic Technologies08/12/13 1000.00 Delta PC08/15/13 75.46 Walts Drugs + + \ No newline at end of file diff --git a/odex25_accounting/odex25_account_bank_statement_import/static/src/js/odex25_account_bank_statement_import.js b/odex25_accounting/odex25_account_bank_statement_import/static/src/js/odex25_account_bank_statement_import.js new file mode 100644 index 000000000..e87e3ae5b --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import/static/src/js/odex25_account_bank_statement_import.js @@ -0,0 +1,19 @@ +odoo.define('odex25_account_bank_statement_import.import', function (require) { +"use strict"; + +var core = require('web.core'); +var BaseImport = require('base_import.import'); + +var _t = core._t; + +BaseImport.DataImport.include({ + renderImportLink: function() { + this._super(); + if (this.res_model == 'account.bank.statement') { + this.$(".import-link").prop({"text": _t(" Import Template for Bank Statements"), "href": "/odex25_account_bank_statement_import/static/csv/account.bank.statement.csv"}); + this.$(".template-import").removeClass('d-none'); + } + }, +}); + +}); diff --git a/odex25_accounting/odex25_account_bank_statement_import/views/odex25_account_bank_statement_import_templates.xml b/odex25_accounting/odex25_account_bank_statement_import/views/odex25_account_bank_statement_import_templates.xml new file mode 100644 index 000000000..7b3727b91 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import/views/odex25_account_bank_statement_import_templates.xml @@ -0,0 +1,8 @@ + + + + diff --git a/odex25_accounting/odex25_account_bank_statement_import/wizard/__init__.py b/odex25_accounting/odex25_account_bank_statement_import/wizard/__init__.py new file mode 100644 index 000000000..aabb7ec17 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import/wizard/__init__.py @@ -0,0 +1,2 @@ +from . import journal_creation +from . import setup_wizards \ No newline at end of file diff --git a/odex25_accounting/odex25_account_bank_statement_import/wizard/journal_creation.py b/odex25_accounting/odex25_account_bank_statement_import/wizard/journal_creation.py new file mode 100644 index 000000000..28654a46c --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import/wizard/journal_creation.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- + +from odoo import api, fields, models + + +class AccountBankStatementImportJounalCreation(models.TransientModel): + _name = 'account.bank.statement.import.journal.creation' + _description = 'Journal Creation on Bank Statement Import' + + journal_id = fields.Many2one('account.journal', delegate=True, required=True, ondelete='cascade') + + def create_journal(self): + """ Create the journal (the record is automatically created in the process of calling this method) and reprocess the statement """ + statement_import_transient = self.env['account.bank.statement.import'].browse(self.env.context['statement_import_transient_id']) + return statement_import_transient.with_context(journal_id=self.journal_id.id).import_file() diff --git a/odex25_accounting/odex25_account_bank_statement_import/wizard/journal_creation.xml b/odex25_accounting/odex25_account_bank_statement_import/wizard/journal_creation.xml new file mode 100644 index 000000000..d84ddf4e6 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import/wizard/journal_creation.xml @@ -0,0 +1,32 @@ + + + + + + Journal Creation + account.bank.statement.import.journal.creation + +
    +

    The account of the statement you are uploading is not yet recorded in Odoo. In order to proceed with the upload, you need to create a bank journal for this account.

    +

    Just click OK to create the account/journal and finish the upload. If this was a mistake, hit cancel to abort the upload.

    + + + + + + + + + + + +
    +
    +
    +
    +
    + +
    +
    diff --git a/odex25_accounting/odex25_account_bank_statement_import/wizard/setup_wizards.py b/odex25_accounting/odex25_account_bank_statement_import/wizard/setup_wizards.py new file mode 100644 index 000000000..754679b6b --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import/wizard/setup_wizards.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- + +from odoo import models, fields, api + + +class SetupBarBankConfigWizard(models.TransientModel): + _inherit = 'account.setup.bank.manual.config' + + def validate(self): + """ Default the bank statement source of new bank journals as 'file_import' + """ + super(SetupBarBankConfigWizard, self).validate() + if (self.num_journals_without_account == 0 or self.linked_journal_id.bank_statements_source == 'undefined') \ + and self.env['account.journal']._get_bank_statements_available_import_formats(): + self.linked_journal_id.bank_statements_source = 'file_import' diff --git a/odex25_accounting/odex25_account_bank_statement_import_camt/__init__.py b/odex25_accounting/odex25_account_bank_statement_import_camt/__init__.py new file mode 100644 index 000000000..f17d5cfc4 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_camt/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + + +from . import models +from . import wizard diff --git a/odex25_accounting/odex25_account_bank_statement_import_camt/__manifest__.py b/odex25_accounting/odex25_account_bank_statement_import_camt/__manifest__.py new file mode 100644 index 000000000..87c45365f --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_camt/__manifest__.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- + + +{ + 'name': 'Import CAMT Bank Statement', + 'category': 'Odex25-Accounting/Odex25-Accounting', + 'author': "Expert Co. Ltd.", + 'website': "http://www.exp-sa.com", + 'depends': ['odex25_account_bank_statement_import'], + 'description': """ +Module to import CAMT bank statements. +====================================== + +Improve the import of bank statement feature to support the SEPA recommended Cash Management format (CAMT.053). + """, + 'data': [ + 'data/odex25_account_bank_statement_import_data.xml' + ], + + 'auto_install': True, +} diff --git a/odex25_accounting/odex25_account_bank_statement_import_camt/data/odex25_account_bank_statement_import_data.xml b/odex25_accounting/odex25_account_bank_statement_import_camt/data/odex25_account_bank_statement_import_data.xml new file mode 100644 index 000000000..b5b72c276 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_camt/data/odex25_account_bank_statement_import_data.xml @@ -0,0 +1,13 @@ + + + + Import Bank Statements CAMT + account.bank.statement.import + + + +
  • SEPA recommended Cash Management format (CAMT.053)
  • +
    +
    +
    +
    diff --git a/odex25_accounting/odex25_account_bank_statement_import_camt/doc/standard-camt053-statement-v2-en_1.pdf b/odex25_accounting/odex25_account_bank_statement_import_camt/doc/standard-camt053-statement-v2-en_1.pdf new file mode 100644 index 000000000..36420b4f6 Binary files /dev/null and b/odex25_accounting/odex25_account_bank_statement_import_camt/doc/standard-camt053-statement-v2-en_1.pdf differ diff --git a/odex25_accounting/odex25_account_bank_statement_import_camt/i18n/ar.po b/odex25_accounting/odex25_account_bank_statement_import_camt/i18n/ar.po new file mode 100644 index 000000000..0bbf433ee --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_camt/i18n/ar.po @@ -0,0 +1,2051 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * odex25_account_bank_statement_import_camt +# +# Translators: +# Mustafa J. Kadhem , 2020 +# Osoul , 2020 +# Osama Ahmaro , 2020 +# Shaima Safar , 2020 +# Mohamed Alansari , 2020 +# Talal Kamal , 2020 +# Mustafa Rawi , 2020 +# Martin Trigaux, 2020 +# hoxhe Aits , 2020 +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server saas~13.5+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-09-01 07:39+0000\n" +"PO-Revision-Date: 2020-09-07 08:17+0000\n" +"Last-Translator: hoxhe Aits , 2020\n" +"Language-Team: Arabic (https://www.transifex.com/odoo/teams/41243/ar/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: ar\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "ACH Concentration" +msgstr "تركيز تسوية الحساب أوتوماتيكيا" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "ACH Corporate Trade" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "ACH Credit" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "ACH Debit" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "ACH Pre-Authorised" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "ACH Return" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "ACH Reversal" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "ACH Settlement" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "ACH Transaction" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "ARP Debit" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Account Balancing" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Account Closing" +msgstr "إغلاق الحساب" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Account Management" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Account Opening" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Account Transfer" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Additional Miscellaneous Credit Operations" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Additional Miscellaneous Debit Operations" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Address:\n" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Adjustments" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Automatic Transfer" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Back Value" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Bank Cheque" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Bank Fees" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Blocked Transactions" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Bonus Issue/Capitalisation Issue" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Borrowing fee" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Branch Account Transfer" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Branch Deposit" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Branch Withdrawal" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Brokerage fee" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Buy Sell Back" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "CSD Blocked Transactions" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Call on intermediate securities" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Capital Gains Distribution" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Cash Deposit" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Cash Dividend" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Cash Letter" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Cash Letter Adjustment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Cash Management" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Cash Pooling" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Cash Withdrawal" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Cash in lieu" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Certified Customer Cheque" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Charge/fees" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Charges" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Cheque" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Cheque Deposit" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Cheque Reversal" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Cheque Under Reserve" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Circular Cheque" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Clean Collection" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Client Owned Collateral" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Collateral Management" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Commission" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Commission excluding taxes" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Commission including taxes" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Commodities" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Compensation/Claims" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Consumer Loans" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Controlled Disbursement" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Conversion" +msgstr "تحويل" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Corporate Action" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Corporate Own Account Transfer" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Corporate Rebate" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Corporate mark broker owned" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Corporate mark client owned" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Counter Party: %(partner)s" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Counter Transactions" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Credit Adjustment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Credit Adjustments" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Credit Card Payment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Credit Transfer with agreed Commercial Information" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Cross Trade" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Cross-Border" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Cross-Border Cash Withdrawal" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Cross-Border Credit Card Payment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Cross-Border Credit Transfer" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Cross-Border Direct Debit" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Cross-Border Intra Company Transfer" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Cross-Border Payroll/Salary Payment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Cross-Border Standing Order" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Crossed Cheque" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Custody" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Custody Collection" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Customer Card Transactions" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Debit" +msgstr "المدين" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Debit Adjustments" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Decrease in Value" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Delivery" +msgstr "التسليم" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Deposit" +msgstr "الدفعة المقدّمة" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Deposit/Contribution" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Depositary Receipt Issue" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Derivatives" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Direct Debit" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Direct Debit Payment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Direct Debit under reserve" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Discounted Draft" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Dishonoured/Unpaid Draft" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_camt.field_odex25_account_bank_statement_import__display_name +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_camt.field_account_journal__display_name +msgid "Display Name" +msgstr "الاسم المعروض" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Dividend Option" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Dividend Reinvestment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Documentary Collection" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Documentary Credit" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Domestic Credit Transfer" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Draft Maturity Change" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Drafts/BillOfOrders" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Drawdown" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Drawing" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Dutch Auction" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Equity Premium Reserve" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Equity mark broker owned" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Equity mark client owned" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Exchange" +msgstr "تبادل" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Exchange Rate Adjustment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Exchange Traded" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Exchange Traded CCP" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Exchange Traded Non-CCP" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Extended Domain" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "External Account Transfer" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Factor Update" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Fees" +msgstr "رسوم" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Final Maturity" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Final Payment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Financial Institution Credit Transfer" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Financial Institution Direct Debit Payment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Financial Institution Own Account Transfer" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Fixed Deposit Interest Amount" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Fixed Term Deposits" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Fixed Term Loans" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Float adjustment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Foreign Cheque" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Foreign Cheque Under Reserve" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Foreign Currency Deposit" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Foreign Currency Withdrawal" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Foreign Exchange" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Forwards" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Forwards broker owned collateral" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Forwards client owned collateral" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Freeze of funds" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Full Call / Early Redemption" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Future Variation Margin" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Futures" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Futures Commission" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Futures Residual Amount" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Guarantees" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_camt.field_odex25_account_bank_statement_import__id +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_camt.field_account_journal__id +msgid "ID" +msgstr "المُعرف" + +#. module: odex25_account_bank_statement_import_camt +#: model:ir.model,name:odex25_account_bank_statement_import_camt.model_odex25_account_bank_statement_import +msgid "Import Bank Statement" +msgstr "استيراد كشف حساب بنكي" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Inspeci/Share Exchange" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Interest" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Interest Payment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Interest Payment with Principle" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Internal Account Transfer" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Internal Book Transfer" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Intra Company Transfer" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Invoice Accepted with Differed Due Date" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Issued Cash Concentration Transactions" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Issued Cheques" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Issued Credit Transfers" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Issued Direct Debits" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Issued Real Time Credit Transfer" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: model:ir.model,name:odex25_account_bank_statement_import_camt.model_account_journal +msgid "Journal" +msgstr "دفتر اليومية" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Lack" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_camt.field_odex25_account_bank_statement_import____last_update +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_camt.field_account_journal____last_update +msgid "Last Modified on" +msgstr "آخر تعديل في" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Lending Broker Owned Cash Collateral" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Lending Client Owned Cash Collateral" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Lending income" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Liquidation Dividend / Liquidation Payment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Listed Derivatives – Futures" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Listed Derivatives – Options" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Loans, Deposits & Syndications" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Lockbox Transactions" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Management Fees" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Margin Payments" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Margin client owned cash collateral" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Merchant Card Transactions" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Merger" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Miscellaneous Credit Operations" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Miscellaneous Debit Operations" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Miscellaneous Deposit" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Miscellaneous Securities Operations" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Mixed Deposit" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Mortgage Loans" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Netting" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Non Deliverable" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Non Settled" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Non Syndicated" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Non Taxable commissions" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Non-Presented Circular Cheque" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Not available" +msgstr "غير متاح" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Notice Deposits" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Notice Loans" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "OTC" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "OTC CCP" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "OTC Derivatives – Bonds" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "OTC Derivatives – Credit Derivatives" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "OTC Derivatives – Equity" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "OTC Derivatives – Interest Rates" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "OTC Derivatives – Structured Exotic Derivatives" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "OTC Derivatives – Swaps" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "OTC Non-CCP" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Odd Lot Sale/Purchase" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "One-Off Direct Debit" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Open Cheque" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Opening & Closing" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Option broker owned collateral" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Option client owned collateral" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Options" +msgstr "خيارات" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Order Cheque" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Other" +msgstr "غير ذلك" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Overdraft" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Overdraft Charge" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Pair-Off" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Partial Payment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Partial Redemption Without Reduction of Nominal Value" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Partial Redemption with reduction of nominal value" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Payments" +msgstr "المدفوعات" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Payroll/Salary Payment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Placement" +msgstr "تحديد مستوى" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "" +"Please set the IBAN account on your bank journal.\n" +"\n" +"This CAMT file is targeting several IBAN accounts but none match the current journal." +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Point-of-Sale (POS) Payment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Point-of-Sale (POS) Payment - Debit Card" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Portfolio Move" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Posting Error" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Pre-Authorised Direct Debit" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Precious Metal" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Principal Pay-down/pay-up" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Principal Payment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Priority Credit Transfer" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Priority Issue" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Put Redemption" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Received Cash Concentration Transactions" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Received Cheques" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Received Credit Transfers" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Received Direct Debits" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Received Real Time Credit Transfer" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Redemption" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Redemption Asset Allocation" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Redemption Withdrawing Plan" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Reimbursements" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Renewal" +msgstr "تجديد" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Repayment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Repo" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Repurchase offer/Issuer Bid/Reverse Rights." +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Reset Payment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Reversal due to Payment Cancellation Request" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Reversal due to Payment Return/reimbursement of a Credit Transfer" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Reversal due to Payment Reversal" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Reversal due to Return/Unpaid Direct Debit" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Reversal due to a Payment Cancellation Request" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Reverse Repo" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Rights Issue/Subscription Rights/Rights Offer" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "SEPA B2B Direct Debit" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "SEPA Core Direct Debit" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "SEPA Credit Transfer" +msgstr "نقل رصيد من خلال SEPA" + +#. module: odex25_account_bank_statement_import_camt +#: model_terms:ir.ui.view,arch_db:odex25_account_bank_statement_import_camt.odex25_account_bank_statement_import_camt +msgid "" +"SEPA recommended Cash Management format (CAMT.053) " +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Same Day Value Credit Transfer" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Securities" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Securities Borrowing" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Securities Lending" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Sell Buy Back" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Settlement" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Settlement after collection" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Settlement against bank guarantee" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Settlement at Maturity" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Settlement of Sight Export document" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Settlement of Sight Import document" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Settlement under reserve" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Smart-Card Payment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Spots" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Stamp duty" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Stand-By Letter Of Credit" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Standing Order" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Subscription" +msgstr "الاشتراك" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Subscription Asset Allocation" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Subscription Savings Plan" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Swap Payment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Swap broker owned collateral" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Swaps" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Sweep" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Sweeping" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Switch" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Syndicated" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Syndications" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "TBA closing" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Tax Reclaim" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Taxes" +msgstr "الضرائب" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Tender" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Topping" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Trade" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Trade Services" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Trade, Clearing and Settlement" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Transaction Fees" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Transfer In" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Transfer Out" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Travellers Cheques Deposit" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Travellers Cheques Withdrawal" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Treasury Tax And Loan Service" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Triparty Repo" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Triparty Reverse Repo" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Turnaround" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Underwriting Commission" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Unpaid Card Transaction" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Unpaid Cheque" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Unpaid Foreign Cheque" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Upfront Payment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Value Date" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Warrant Exercise/Warrant Conversion" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Withdrawal/distribution" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Withholding Tax" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "YTD Adjustment" +msgstr "" + +#. module: odex25_account_bank_statement_import_camt +#: code:addons/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py:0 +#, python-format +msgid "Zero Balancing" +msgstr "" diff --git a/odex25_accounting/odex25_account_bank_statement_import_camt/models/__init__.py b/odex25_accounting/odex25_account_bank_statement_import_camt/models/__init__.py new file mode 100644 index 000000000..0c5073d1a --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_camt/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + + +from . import account_journal \ No newline at end of file diff --git a/odex25_accounting/odex25_account_bank_statement_import_camt/models/account_journal.py b/odex25_accounting/odex25_account_bank_statement_import_camt/models/account_journal.py new file mode 100644 index 000000000..ef0d72a78 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_camt/models/account_journal.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- + + +from odoo import models + + +class AccountJournal(models.Model): + _inherit = 'account.journal' + + def _get_bank_statements_available_import_formats(self): + rslt = super(AccountJournal, self)._get_bank_statements_available_import_formats() + rslt.append('CAMT') + return rslt \ No newline at end of file diff --git a/odex25_accounting/odex25_account_bank_statement_import_camt/static/description/icon.png b/odex25_accounting/odex25_account_bank_statement_import_camt/static/description/icon.png new file mode 100644 index 000000000..4141f52da Binary files /dev/null and b/odex25_accounting/odex25_account_bank_statement_import_camt/static/description/icon.png differ diff --git a/odex25_accounting/odex25_account_bank_statement_import_camt/test_camt_file/camt_053_minimal.xml b/odex25_accounting/odex25_account_bank_statement_import_camt/test_camt_file/camt_053_minimal.xml new file mode 100644 index 000000000..7e4a51cdc --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_camt/test_camt_file/camt_053_minimal.xml @@ -0,0 +1,55 @@ + + + + + 2514988305.2019-02-13 + 2019-02-13T15:27:15.66+02:00 + + + 2514988305.2019-02-13 + 2019-02-13T15:27:15.66+02:00 + + + + + 112233 + + + + + + + OPBD + + + 1000.00 + CRDT +
    +
    2019-02-12
    + +
    + + + + CLBD + + + 1500.00 + CRDT +
    +
    2019-02-13
    + +
    + + 500.00 + CRDT + BOOK + + + ABCD + + + +
    +
    +
    \ No newline at end of file diff --git a/odex25_accounting/odex25_account_bank_statement_import_camt/test_camt_file/camt_053_sample.xml b/odex25_accounting/odex25_account_bank_statement_import_camt/test_camt_file/camt_053_sample.xml new file mode 100644 index 000000000..4bff9a4ed --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_camt/test_camt_file/camt_053_sample.xml @@ -0,0 +1,948 @@ + + + + + + + BANKFILEID00001 + 2009-10-30T03:30:47+02:00 + + + + + BANKSTMTID0972009 + + 120 + + + + 97 + 2009-10-30T02:00:00+02:00 + + + + + 2009-10-29T02:00:00+02:00 + 2009-10-29T21:00:00+02:00 + + + + + + + + FI7433010001222090 + + + + CACC + + + EUR + + + BANK ACCOUNT OWNER + + HELSINGINKATU + 31 + 00100 + HELSINKI + FI + + + + + + 12345678901 + + + BANK + + + + + + + + + ESSEFIHX + + + + + + + + FI1533010001911270 + + EUR + + + + + + + INDY + + + + Business agreement + + + + + + 0.00 + true + + + 1000000.00 + true + + + + CRDT + EUR + + + + + + + + + + + OPBD + + + + + false + 10000.00 + + 10000.00 + CRDT + +
    +
    2009-10-29
    + +
    + + + + + PRCD + + + + false + 10000.00 + + 10000.00 + CRDT + +
    +
    2009-10-28
    + +
    + + + + + CLBD + + + + + false + 10000.00 + + 23644.83 + CRDT + +
    +
    2009-10-29
    + +
    + + + + + + CLAV + + + 33644.83 + CRDT +
    +
    2009-10-29
    + +
    + + + + + 10 + + + + 6 + 23075.00 + + + + 4 + 9430.17 + + + + + + + + + 1000.12 + DBIT + BOOK + +
    2009-10-29
    +
    + +
    2009-10-29
    +
    + + 091029ACCTSTMTARCH01 + + + + PMNT + + ICDT + SALA + + + + + NTRF+701TransactionCodeText + + + + + + + MSGSALA0001 + + CustRefForSalaBatch + + 4 + + + + + SALA + + + +
    + + + + 4000.00 + DBIT + BOOK + +
    2009-10-29
    +
    + +
    2009-10-29
    +
    + + 091029ACCTSTMTARCH02 + + + + PMNT + + ICDT + DMCT + + + + + NTRF+702TransactionCodeText + + + + + + + MSGSCT0099 + CustRefForPmtBatch + + 3 + + +
    + + + 4230.05 + DBIT + BOOK + + +
    2009-10-29
    +
    + + +
    2009-10-29
    +
    + 091029ACCTSTMTARCH03 + + + PMNT + + ICDT + DMCT + + + + + NTRF+702TransactionCodeText + + + + + MSGSCT0100 + CustRefForPmtBatch9 + 3 + + + + + + + + 091029ARCH03001 + + TITOT1106ID01 + + + + 2000.02 + + + + + Creditor Company + + + FI + Mannerheimintie 123 + 00100 Helsinki + + FI + + + + + + 29501800020582 + + BBAN + + + + + + + + + + + SCOR + + + 3900 + + + + + + + + 091029ARCH03002 + TITOT1106ID02 + + + + 1000.01 + + + + + Creditor Company + + FI + Mannerheimintie 123 + 00100 Helsinki + + FI + + + + + 29501800020582 + + BBAN + + + + + + ACWC + + + + + Invoices 123 and 321 + + + + + + + 091029ARCH03003 + TITOT1106ID03 + + + + 1230.02 + + + + + Creditor Company + + FI + Mannerheimintie 123 + 00100 Helsinki + + FI + + + + + 29501800020574 + + BBAN + + + + + + + + + + + CINV + + + 217827182718 + + + + + + 9102910 + + + + + + + + +
    + + + + 2000.00 + CRDT + BOOK + +
    2009-10-29
    +
    + +
    2009-10-29
    +
    + + 091029ACCTSTMTARCH04 + + + PMNT + + RCDT + DMCT + + + + NTRF+705TransactionCodeText + + + + + BANKFILEID998765 + + 2 + + + + + 2000.00 + + + + +
    + + + 500.00 + CRDT + BOOK + +
    2009-10-29
    +
    + +
    2009-10-29
    +
    + + 091029ACCTSTMTARCH21 + + + PMNT + + RDDT + PMDD + + + + NTRF+705TransactionCodeText + + + + + BANKFILEID998799 + + 2 + + + + + 500.00 + + + + +
    + + + 3000.00 + CRDT + BOOK + +
    2009-10-29
    +
    + +
    2009-10-29
    +
    + 091029ACCTSTMTARCH05 + + + PMNT + + RCDT + ESCT + + + + + + BANKFILEID998765 + + 2 + + + + + 3000.00 + + + + +
    + + + 2120.00 + CRDT + BOOK + +
    2009-10-29
    +
    + + +
    2009-10-30
    +
    + 091029ACCTSTMTARCH06 + + + PMNT + + RCDT + XBCT + + + + + + + + ISSRBKREF12345678 + ISSRBKREF12345678 + + + + + + 3200.00 + + EUR + EUR + + EUR + 0.666667 + FX12345 + 2009-10-29T10:00:00+02:00 + + + + 2120.00 + + + + 2120.00 + + EUR + EUR + EUR + 0.666667 + FX12345 + 2009-10-29T10:00:00+02:00 + + + + + + 20.00 + + COMM + + + + + DEBTOR NAME + + + + + 123456789 + + DUNS + + + + + + + + + + BOFAUS6H + + + + + INVOICE US20291092 + + + +
    + + + + 5455.00 + CRDT + BOOK + +
    2009-10-29
    +
    + +
    2009-10-29
    +
    + 091029ACCTSTMTARCH07 + + + PMNT + + RCDT + + PRCT + + + + + + + + BKREFDBT0101010 + BKREFDBT0101010 + + + + + 5500.00 + + + 5455.00 + + + + 45.00 + + COMM + + + + + PAYERS NAME2 + + GOVERN STREET + 22 + 291092 + LONDON + UK + + + + + 123456789 + + EANG + + + + + + + + + + BOFSGB22 + + + + + + + 5500.00 + + + + + SCOR + + ISO + + RF98123456789012 + + + + + +
    + + + 10000.00 + CRDT + BOOK + +
    2009-10-29
    +
    + +
    2009-10-29
    +
    + 091029ACCTSTMTARCH08 + + + PMNT + + RCDT + ESCT + + + + + + + EndToEndIdSCT01 + + + + + 10000.00 + + + + + DEBTOR + + + ULTIMATE DEBTOR + + + + 987654321 + + TXID + + + + + + + + + + NDEAFIHH + + + + + TREA + + + + + + + SCOR + + ISO + + RF98123456789012 + + + + + 2009-10-28T03:00:00+02:00 + + + +
    + + + + 200.00 + DBIT + BOOK + +
    2009-10-29
    +
    + +
    2009-10-29
    +
    + 091029ACCTSTMTARCH09 + + + + PMNT + + RCDT + CHRG + + + + + + + + + 091029ARCH09001 + + + + 100.00 + + + + + PMNT + + RCDT + DMCT + + + + + + SEB Merchant Banking Finland + + + + + 10000 + + + + + + + 091029ARCH09001 + + + + 100.00 + + + + + PMNT + + RCDT + ESCT + + + + + + SEB Merchant Banking Finland + + + + + 150000 + + + + +
    +
    +
    +
    diff --git a/odex25_accounting/odex25_account_bank_statement_import_camt/test_camt_file/camt_053_several_ibans.xml b/odex25_accounting/odex25_account_bank_statement_import_camt/test_camt_file/camt_053_several_ibans.xml new file mode 100644 index 000000000..a2ce288e9 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_camt/test_camt_file/camt_053_several_ibans.xml @@ -0,0 +1,96 @@ + + + + + 2514988305.2019-05-23 + 2019-05-23T15:27:15.66+02:00 + + + 2514988305.2019-05-23 + 2019-05-23T15:27:15.66+02:00 + + + BE86 6635 9439 7150 + + + + + + OPBD + + + 1000.00 + CRDT +
    +
    2019-05-22
    + +
    + + + + CLBD + + + 1600.00 + CRDT +
    +
    2019-05-23
    + +
    + + 600.00 + CRDT + BOOK + + + ABCD + + + +
    + + + 2514988305.2019-05-23 + 2019-05-23T15:27:15.66+02:00 + + + BE79 5390 0754 6933 + + + + + + OPBD + + + 100.00 + CRDT +
    +
    2019-05-22
    + +
    + + + + CLBD + + + 150.00 + CRDT +
    +
    2019-05-23
    + +
    + + 50.00 + CRDT + BOOK + + + ABCD + + + +
    +
    +
    \ No newline at end of file diff --git a/odex25_accounting/odex25_account_bank_statement_import_camt/test_camt_file/test_camt.xml b/odex25_accounting/odex25_account_bank_statement_import_camt/test_camt_file/test_camt.xml new file mode 100644 index 000000000..fe767d282 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_camt/test_camt_file/test_camt.xml @@ -0,0 +1,249 @@ + + + + + 0574908765.2015-12-05 + 2015-12-05T10:55:08.66+02:00 + + 1 + true + + + + 0574908765.2015-12-05 + 0070 + 2015-12-05T10:55:08.66+02:00 + + + + + 123456 + + + Norbert Brant + + + ABNANL2A + + + + + + + OPBD + + + 8998.20 + CRDT +
    +
    2015-12-05
    + +
    + + + + CLAV + + + 2661.49 + CRDT +
    +
    2015-12-05
    + +
    + + 7379.54 + DBIT + BOOK + +
    2015-12-01
    +
    + +
    2015-12-01
    +
    + + + PMNT + + RDDT + ESDD + + + + EI + + + + + + INNDNL2U20141231000142300002844 + 435005714488-ABNO33052620 + 1880000341866 + + + + 7379.54 + + + + + ASUSTeK + + TEST STREET 20 + 1234 AB TESTCITY + NL + + + + + NL46ABNA0499998748 + + + + + + + ABNANL2A + + + + + BILL 2015 0002 + + MKB 859239PERIOD 31.12.2015 + + +
    + + 594.05 + DBIT + true + BOOK + +
    2015-11-29
    +
    + +
    2015-11-29
    +
    + + + PMNT + + IDDT + UPDD + + + + EIST + + + + + + TESTBANK/NL/20151129/01206408 + TESTBANK/NL/20151129/01206408 + NL22ZZZ524885430000-C0125.1 + + + + 564.05 + + + + + China Export + + NL + + + + + + 10987654322 + > + + + + + + + ABNANL2A + + + + + Direct Debit S14 0410 + + + + AC06 + + + Direct debit S14 0410 AC07 Rek.nummer blokkade TESTBANK/NL/20141229/01206408 + + +
    + + 1636.88 + CRDT + BOOK + +
    2015-01-05
    +
    + +
    2015-01-05
    +
    + + + PMNT + + RCDT + ESCT + + + + ET + + + + + + INNDNL2U20150105000217200000708 + 115 + + + + 1636.88 + + + + + Norbert Brant + + SOMESTREET 570-A + 1276 ML HOUSCITY + NL + + + + + + BE93999574162167 + + + + + + + + ABNANL2A + + + + #RD INV/2015/0002 INV/2015/0003 + + +
    +
    +
    +
    diff --git a/odex25_accounting/odex25_account_bank_statement_import_camt/tests/__init__.py b/odex25_accounting/odex25_account_bank_statement_import_camt/tests/__init__.py new file mode 100644 index 000000000..2403680e7 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_camt/tests/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + + +from . import test_odex25_account_bank_statement_import_camt diff --git a/odex25_accounting/odex25_account_bank_statement_import_camt/tests/test_odex25_account_bank_statement_import_camt.py b/odex25_accounting/odex25_account_bank_statement_import_camt/tests/test_odex25_account_bank_statement_import_camt.py new file mode 100644 index 000000000..ff40b6c05 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_camt/tests/test_odex25_account_bank_statement_import_camt.py @@ -0,0 +1,189 @@ +# -*- coding: utf-8 -*- + +from odoo.addons.account.tests.common import AccountTestInvoicingCommon +from odoo.tests import tagged +from odoo.exceptions import UserError +from odoo.modules.module import get_module_resource +from odoo.addons.odex25_account_bank_statement_import_camt.wizard.odex25_account_bank_statement_import_camt import _logger as camt_wizard_logger + +import base64 + + +@tagged('post_install', '-at_install') +class TestAccountBankStatementImportCamt(AccountTestInvoicingCommon): + + def test_camt_file_import(self): + bank_journal = self.env['account.journal'].create({ + 'name': 'Bank 123456', + 'code': 'BNK67', + 'type': 'bank', + 'bank_acc_number': '123456', + 'currency_id': self.env.ref('base.USD').id, + }) + + partner_norbert = self.env['res.partner'].create({ + 'name': 'Norbert Brant', + 'is_company': True, + }) + bank_norbert = self.env['res.bank'].create({'name': 'test'}) + + self.env['res.partner.bank'].create({ + 'acc_number': 'BE93999574162167', + 'partner_id': partner_norbert.id, + 'bank_id': bank_norbert.id, + }) + + # Get CAMT file content + camt_file_path = get_module_resource( + 'odex25_account_bank_statement_import_camt', + 'test_camt_file', + 'test_camt.xml', + ) + camt_file = base64.b64encode(open(camt_file_path, 'rb').read()) + + # Use an import wizard to process the file + self.env['account.bank.statement.import']\ + .with_context(journal_id=bank_journal.id)\ + .create({'attachment_ids': [(0, 0, {'name': 'test file', 'datas': camt_file})]})\ + .import_file() + + # Check the imported bank statement + imported_statement = self.env['account.bank.statement'].search([('company_id', '=', self.env.company.id)]) + self.assertRecordValues(imported_statement, [{ + 'name': '0574908765.2015-12-05', + 'balance_start': 8998.20, + 'balance_end_real': 2661.49, + }]) + self.assertRecordValues(imported_statement.line_ids.sorted('ref'), [ + { + 'ref': 'INNDNL2U20141231000142300002844', + 'partner_name': 'ASUSTeK', + 'amount': -7379.54, + 'partner_id': False, + }, + { + 'ref': 'INNDNL2U20150105000217200000708', + 'partner_name': partner_norbert.name, + 'amount': 1636.88, + 'partner_id': partner_norbert.id, + }, + { + 'ref': 'TESTBANK/NL/20151129/01206408', + 'partner_name': 'China Export', + 'amount': -564.05, + 'partner_id': False, + }, + ]) + + def test_minimal_camt_file_import(self): + # Create a bank account and journal corresponding to the CAMT + # file (same currency and account number) + bank_journal = self.env['account.journal'].create({ + 'name': "Bank 112233", + 'code': 'BNK68', + 'type': 'bank', + 'bank_acc_number': '112233', + 'currency_id': self.env.ref('base.USD').id, + }) + + # Use an import wizard to process the file + camt_file_path = get_module_resource( + 'odex25_account_bank_statement_import_camt', + 'test_camt_file', + 'camt_053_minimal.xml', + ) + camt_file = base64.b64encode(open(camt_file_path, 'rb').read()) + + self.env['account.bank.statement.import']\ + .with_context(journal_id=bank_journal.id)\ + .create({'attachment_ids': [(0, 0, {'name': 'test file', 'datas': camt_file})]})\ + .import_file() + + # Check the imported bank statement + imported_statement = self.env['account.bank.statement'].search([('company_id', '=', self.env.company.id)]) + self.assertRecordValues(imported_statement, [{ + 'name': '2514988305.2019-02-13', + 'balance_start': 1000.00, + 'balance_end_real': 1500.00, + }]) + self.assertRecordValues(imported_statement.line_ids.sorted('ref'), [{'amount': 500.00}]) + + def test_several_ibans_match_journal_camt_file_import(self): + # Create a bank account and journal corresponding to the CAMT + # file (same currency and account number) + bank_journal = self.env['account.journal'].create({ + 'name': "Bank BE86 6635 9439 7150", + 'code': 'BNK69', + 'type': 'bank', + 'bank_acc_number': 'BE86 6635 9439 7150', + 'currency_id': self.env.ref('base.USD').id, + }) + + # Use an import wizard to process the file + camt_file_path = get_module_resource( + 'odex25_account_bank_statement_import_camt', + 'test_camt_file', + 'camt_053_several_ibans.xml', + ) + camt_file = base64.b64encode(open(camt_file_path, 'rb').read()) + + wizard = self.env['account.bank.statement.import']\ + .with_context(journal_id=bank_journal.id)\ + .create({'attachment_ids': [(0, 0, {'name': 'test file', 'datas': camt_file})]}) + + with self.assertLogs(level="WARNING") as log_catcher: + wizard.import_file() + self.assertEqual(len(log_catcher.output), 1, "Exactly one warning should be logged") + self.assertIn( + "The following statements will not be imported", + log_catcher.output[0], + "The logged warning warns about non-imported statements", + ) + + # Check the imported bank statement + imported_statement = self.env['account.bank.statement'].search([('company_id', '=', self.env.company.id)]) + self.assertRecordValues(imported_statement, [{ + 'name': '2514988305.2019-05-23', + 'balance_start': 1000.00, + 'balance_end_real': 1600.00, + }]) + self.assertRecordValues(imported_statement.line_ids.sorted('ref'), [{'amount': 600.00}]) + + def test_several_ibans_missing_journal_id_camt_file_import(self): + # Create a bank account and journal corresponding to the CAMT + # file (same currency and account number) + bank_journal = self.env['account.journal'].create({ + 'name': "Bank BE43 9787 8497 9701", + 'code': 'BNK69', + 'type': 'bank', + 'currency_id': self.env.ref('base.USD').id, + # missing bank account number + }) + + # Use an import wizard to process the file + camt_file_path = get_module_resource( + 'odex25_account_bank_statement_import_camt', + 'test_camt_file', + 'camt_053_several_ibans.xml', + ) + camt_file = base64.b64encode(open(camt_file_path, 'rb').read()) + + wizard = self.env['account.bank.statement.import']\ + .with_context(journal_id=bank_journal.id)\ + .create({'attachment_ids': [(0, 0, {'name': 'test file', 'datas': camt_file})]}) + + with self.assertLogs(camt_wizard_logger, level="WARNING") as log_catcher: + with self.assertRaises(UserError) as error_catcher: + wizard.import_file() + + self.assertEqual(len(log_catcher.output), 1, "Exactly one warning should be logged") + self.assertIn( + "The following statements will not be imported", + log_catcher.output[0], + "The logged warning warns about non-imported statements", + ) + + self.assertEqual(error_catcher.exception.args[0], ( + "Please set the IBAN account on your bank journal.\n\n" + "This CAMT file is targeting several IBAN accounts but none match the current journal." + )) diff --git a/odex25_accounting/odex25_account_bank_statement_import_camt/wizard/__init__.py b/odex25_accounting/odex25_account_bank_statement_import_camt/wizard/__init__.py new file mode 100644 index 000000000..77e6a8855 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_camt/wizard/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + + + +from . import odex25_account_bank_statement_import_camt diff --git a/odex25_accounting/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py b/odex25_accounting/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py new file mode 100644 index 000000000..f988a8723 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_camt/wizard/odex25_account_bank_statement_import_camt.py @@ -0,0 +1,743 @@ +# -*- coding: utf-8 -*- + + +import io +import logging +import math +import re +from functools import partial + +from lxml import etree + +from odoo import models, _ +from odoo.exceptions import UserError + +_logger = logging.getLogger(__name__) + +# Codes from the updated document of 30 june 2017 +codes = { + # ExternalBankTransactionDomain1Code ####################################### + 'PMNT': _('Payments'), + 'CAMT': _('Cash Management'), + 'DERV': _('Derivatives'), + 'LDAS': _('Loans, Deposits & Syndications'), + 'FORX': _('Foreign Exchange'), + 'PMET': _('Precious Metal'), + 'CMDT': _('Commodities'), + 'TRAD': _('Trade Services'), + 'SECU': _('Securities'), + 'ACMT': _('Account Management'), + 'XTND': _('Extended Domain'), + # ExternalBankTransactionFamily1Code ####################################### + 'RCDT': _('Received Credit Transfers'), # Payments + 'ICDT': _('Issued Credit Transfers'), + 'RCCN': _('Received Cash Concentration Transactions'), + 'ICCN': _('Issued Cash Concentration Transactions'), + 'RDDT': _('Received Direct Debits'), + 'IDDT': _('Issued Direct Debits'), + 'RCHQ': _('Received Cheques'), + 'ICHQ': _('Issued Cheques'), + 'CCRD': _('Customer Card Transactions'), + 'MCRD': _('Merchant Card Transactions'), + 'LBOX': _('Lockbox Transactions'), + 'CNTR': _('Counter Transactions'), + 'DRFT': _('Drafts/BillOfOrders'), + 'RRCT': _('Received Real Time Credit Transfer'), + 'IRCT': _('Issued Real Time Credit Transfer'), + 'CAPL': _('Cash Pooling'), # Cash Management + 'ACCB': _('Account Balancing'), + 'OCRD': _('OTC Derivatives – Credit Derivatives'), # Derivatives + 'OIRT': _('OTC Derivatives – Interest Rates'), + 'OEQT': _('OTC Derivatives – Equity'), + 'OBND': _('OTC Derivatives – Bonds'), + 'OSED': _('OTC Derivatives – Structured Exotic Derivatives'), + 'OSWP': _('OTC Derivatives – Swaps'), + 'LFUT': _('Listed Derivatives – Futures'), + 'LOPT': _('Listed Derivatives – Options'), + 'FTLN': _('Fixed Term Loans'), # Loans, Deposits & Syndications + 'NTLN': _('Notice Loans'), + 'FTDP': _('Fixed Term Deposits'), + 'NTDP': _('Notice Deposits'), + 'MGLN': _('Mortgage Loans'), + 'CSLN': _('Consumer Loans'), + 'SYDN': _('Syndications'), + 'SPOT': _('Spots'), # Foreign Exchange + 'FWRD': _('Forwards'), + 'SWAP': _('Swaps'), + 'FTUR': _('Futures'), + 'NDFX': _('Non Deliverable'), + 'SPOT': _('Spots'), # Precious Metal + 'FTUR': _('Futures'), + 'OPTN': _('Options'), + 'DLVR': _('Delivery'), + 'SPOT': _('Spots'), # Commodities + 'FTUR': _('Futures'), + 'OPTN': _('Options'), + 'DLVR': _('Delivery'), + 'LOCT': _('Stand-By Letter Of Credit'), # Trade Services + 'DCCT': _('Documentary Credit'), + 'CLNC': _('Clean Collection'), + 'DOCC': _('Documentary Collection'), + 'GUAR': _('Guarantees'), + 'SETT': _('Trade, Clearing and Settlement'), # Securities + 'NSET': _('Non Settled'), + 'BLOC': _('Blocked Transactions'), + 'OTHB': _('CSD Blocked Transactions'), + 'COLL': _('Collateral Management'), + 'CORP': _('Corporate Action'), + 'CUST': _('Custody'), + 'COLC': _('Custody Collection'), + 'LACK': _('Lack'), + 'CASH': _('Miscellaneous Securities Operations'), + 'OPCL': _('Opening & Closing'), # Account Management + 'ACOP': _('Additional Miscellaneous Credit Operations'), + 'ADOP': _('Additional Miscellaneous Debit Operations'), + # ExternalBankTransactionSubFamily1Code #################################### + # Generic Sub-Families + 'FEES': _('Fees'), # Miscellaneous Credit Operations + 'COMM': _('Commission'), + 'COME': _('Commission excluding taxes'), + 'COMI': _('Commission including taxes'), + 'COMT': _('Non Taxable commissions'), + 'TAXE': _('Taxes'), + 'CHRG': _('Charges'), + 'INTR': _('Interest'), + 'RIMB': _('Reimbursements'), + 'ADJT': _('Adjustments'), + 'FEES': _('Fees'), # Miscellaneous Debit Operations + 'COMM': _('Commission'), + 'COME': _('Commission excluding taxes'), + 'COMI': _('Commission including taxes'), + 'COMT': _('Non Taxable commissions'), + 'TAXE': _('Taxes'), + 'CHRG': _('Charges'), + 'INTR': _('Interest'), + 'RIMB': _('Reimbursements'), + 'ADJT': _('Adjustments'), + 'IADD': _('Invoice Accepted with Differed Due Date'), + 'FEES': _('Fees'), # Generic Sub-Families + 'COMM': _('Commission'), + 'COME': _('Commission excluding taxes'), + 'COMI': _('Commission including taxes'), + 'COMT': _('Non Taxable commissions'), + 'TAXE': _('Taxes'), + 'CHRG': _('Charges'), + 'INTR': _('Interest'), + 'RIMB': _('Reimbursements'), + 'DAJT': _('Credit Adjustments'), + 'CAJT': _('Debit Adjustments'), + # Payments Sub-Families + 'BOOK': _('Internal Book Transfer'), # Received Credit Transfer + 'STDO': _('Standing Order'), + 'XBST': _('Cross-Border Standing Order'), + 'ESCT': _('SEPA Credit Transfer'), + 'DMCT': _('Domestic Credit Transfer'), + 'XBCT': _('Cross-Border Credit Transfer'), + 'VCOM': _('Credit Transfer with agreed Commercial Information'), + 'FICT': _('Financial Institution Credit Transfer'), + 'PRCT': _('Priority Credit Transfer'), + 'SALA': _('Payroll/Salary Payment'), + 'XBSA': _('Cross-Border Payroll/Salary Payment'), + 'SDVA': _('Same Day Value Credit Transfer'), + 'RPCR': _('Reversal due to Payment Cancellation Request'), + 'RRTN': _('Reversal due to Payment Return/reimbursement of a Credit Transfer'), + 'AUTT': _('Automatic Transfer'), + 'ATXN': _('ACH Transaction'), + 'ACOR': _('ACH Corporate Trade'), + 'APAC': _('ACH Pre-Authorised'), + 'ASET': _('ACH Settlement'), + 'ARET': _('ACH Return'), + 'AREV': _('ACH Reversal'), + 'ACDT': _('ACH Credit'), + 'ADBT': _('ACH Debit'), + 'TTLS': _('Treasury Tax And Loan Service'), + 'BOOK': _('Internal Book Transfer'), # Issued Credit Transfer + 'STDO': _('Standing Order'), + 'XBST': _('Cross-Border Standing Order'), + 'ESCT': _('SEPA Credit Transfer'), + 'DMCT': _('Domestic Credit Transfer'), + 'XBCT': _('Cross-Border Credit Transfer'), + 'FICT': _('Financial Institution Credit Transfer'), + 'PRCT': _('Priority Credit Transfer'), + 'VCOM': _('Credit Transfer with agreed Commercial Information'), + 'SALA': _('Payroll/Salary Payment'), + 'XBSA': _('Cross-Border Payroll/Salary Payment'), + 'RPCR': _('Reversal due to Payment Cancellation Request'), + 'RRTN': _('Reversal due to Payment Return/reimbursement of a Credit Transfer'), + 'SDVA': _('Same Day Value Credit Transfer'), + 'AUTT': _('Automatic Transfer'), + 'ATXN': _('ACH Transaction'), + 'ACOR': _('ACH Corporate Trade'), + 'APAC': _('ACH Pre-Authorised'), + 'ASET': _('ACH Settlement'), + 'ARET': _('ACH Return'), + 'AREV': _('ACH Reversal'), + 'ACDT': _('ACH Credit'), + 'ADBT': _('ACH Debit'), + 'TTLS': _('Treasury Tax And Loan Service'), + 'COAT': _('Corporate Own Account Transfer'), # Received Cash Concentration + 'ICCT': _('Intra Company Transfer'), + 'XICT': _('Cross-Border Intra Company Transfer'), + 'FIOA': _('Financial Institution Own Account Transfer'), + 'BACT': _('Branch Account Transfer'), + 'ACON': _('ACH Concentration'), + 'COAT': _('Corporate Own Account Transfer'), # Issued Cash Concentration + 'ICCT': _('Intra Company Transfer'), + 'XICT': _('Cross-Border Intra Company Transfer'), + 'FIOA': _('Financial Institution Own Account Transfer'), + 'BACT': _('Branch Account Transfer'), + 'ACON': _('ACH Concentration'), + 'PMDD': _('Direct Debit'), # Received Direct Debit + 'URDD': _('Direct Debit under reserve'), + 'ESDD': _('SEPA Core Direct Debit'), + 'BBDD': _('SEPA B2B Direct Debit'), + 'XBDD': _('Cross-Border Direct Debit'), + 'OODD': _('One-Off Direct Debit'), + 'PADD': _('Pre-Authorised Direct Debit'), + 'FIDD': _('Financial Institution Direct Debit Payment'), + 'RCDD': _('Reversal due to a Payment Cancellation Request'), + 'UPDD': _('Reversal due to Return/Unpaid Direct Debit'), + 'PRDD': _('Reversal due to Payment Reversal'), + 'PMDD': _('Direct Debit Payment'), # Issued Direct Debit + 'URDD': _('Direct Debit under reserve'), + 'ESDD': _('SEPA Core Direct Debit'), + 'BBDD': _('SEPA B2B Direct Debit'), + 'OODD': _('One-Off Direct Debit'), + 'XBDD': _('Cross-Border Direct Debit'), + 'PADD': _('Pre-Authorised Direct Debit'), + 'FIDD': _('Financial Institution Direct Debit Payment'), + 'RCDD': _('Reversal due to a Payment Cancellation Request'), + 'UPDD': _('Reversal due to Return/Unpaid Direct Debit'), + 'PRDD': _('Reversal due to Payment Reversal'), + 'CCHQ': _('Cheque'), # Received Cheque + 'URCQ': _('Cheque Under Reserve'), + 'UPCQ': _('Unpaid Cheque'), + 'CQRV': _('Cheque Reversal'), + 'CCCH': _('Certified Customer Cheque'), + 'CLCQ': _('Circular Cheque'), + 'NPCC': _('Non-Presented Circular Cheque'), + 'CRCQ': _('Crossed Cheque'), + 'ORCQ': _('Order Cheque'), + 'OPCQ': _('Open Cheque'), + 'BCHQ': _('Bank Cheque'), + 'XBCQ': _('Foreign Cheque'), + 'XRCQ': _('Foreign Cheque Under Reserve'), + 'XPCQ': _('Unpaid Foreign Cheque'), + 'CDIS': _('Controlled Disbursement'), + 'ARPD': _('ARP Debit'), + 'CASH': _('Cash Letter'), + 'CSHA': _('Cash Letter Adjustment'), + 'CCHQ': _('Cheque'), # Issued Cheque + 'URCQ': _('Cheque Under Reserve'), + 'UPCQ': _('Unpaid Cheque'), + 'CQRV': _('Cheque Reversal'), + 'CCCH': _('Certified Customer Cheque'), + 'CLCQ': _('Circular Cheque'), + 'NPCC': _('Non-Presented Circular Cheque'), + 'CRCQ': _('Crossed Cheque'), + 'ORCQ': _('Order Cheque'), + 'OPCQ': _('Open Cheque'), + 'BCHQ': _('Bank Cheque'), + 'XBCQ': _('Foreign Cheque'), + 'XRCQ': _('Foreign Cheque Under Reserve'), + 'XPCQ': _('Unpaid Foreign Cheque'), + 'CDIS': _('Controlled Disbursement'), + 'ARPD': _('ARP Debit'), + 'CASH': _('Cash Letter'), + 'CSHA': _('Cash Letter Adjustment'), + 'CWDL': _('Cash Withdrawal'), # Customer Card Transaction + 'CDPT': _('Cash Deposit'), + 'XBCW': _('Cross-Border Cash Withdrawal'), + 'POSD': _('Point-of-Sale (POS) Payment - Debit Card'), + 'POSC': _('Credit Card Payment'), + 'XBCP': _('Cross-Border Credit Card Payment'), + 'SMRT': _('Smart-Card Payment'), + 'POSP': _('Point-of-Sale (POS) Payment'), # Merchant Card Transaction + 'POSC': _('Credit Card Payment'), + 'SMCD': _('Smart-Card Payment'), + 'UPCT': _('Unpaid Card Transaction'), + 'CDPT': _('Cash Deposit'), # Counter Transaction + 'CWDL': _('Cash Withdrawal'), + 'BCDP': _('Branch Deposit'), + 'BCWD': _('Branch Withdrawal'), + 'CHKD': _('Cheque Deposit'), + 'MIXD': _('Mixed Deposit'), + 'MSCD': _('Miscellaneous Deposit'), + 'FCDP': _('Foreign Currency Deposit'), + 'FCWD': _('Foreign Currency Withdrawal'), + 'TCDP': _('Travellers Cheques Deposit'), + 'TCWD': _('Travellers Cheques Withdrawal'), + 'LBCA': _('Credit Adjustment'), # Lockbox + 'LBDB': _('Debit'), + 'LBDP': _('Deposit'), + 'STAM': _('Settlement at Maturity'), # Drafts / Bill to Order + 'STLR': _('Settlement under reserve'), + 'DDFT': _('Discounted Draft'), + 'UDFT': _('Dishonoured/Unpaid Draft'), + 'DMCG': _('Draft Maturity Change'), + 'BOOK': _('Internal Book Transfer'), # Received Real-Time Credit Transfer + 'STDO': _('Standing Order'), + 'XBST': _('Cross-Border Standing Order'), + 'ESCT': _('SEPA Credit Transfer'), + 'DMCT': _('Domestic Credit Transfer'), + 'XBCT': _('Cross-Border Credit Transfer'), + 'VCOM': _('Credit Transfer with agreed Commercial Information'), + 'FICT': _('Financial Institution Credit Transfer'), + 'PRCT': _('Priority Credit Transfer'), + 'SALA': _('Payroll/Salary Payment'), + 'XBSA': _('Cross-Border Payroll/Salary Payment'), + 'SDVA': _('Same Day Value Credit Transfer'), + 'RPCR': _('Reversal due to Payment Cancellation Request'), + 'RRTN': _('Reversal due to Payment Return/reimbursement of a Credit Transfer'), + 'AUTT': _('Automatic Transfer'), + 'ATXN': _('ACH Transaction'), + 'ACOR': _('ACH Corporate Trade'), + 'APAC': _('ACH Pre-Authorised'), + 'ASET': _('ACH Settlement'), + 'ARET': _('ACH Return'), + 'AREV': _('ACH Reversal'), + 'ACDT': _('ACH Credit'), + 'ADBT': _('ACH Debit'), + 'TTLS': _('Treasury Tax And Loan Service'), + 'BOOK': _('Internal Book Transfer'), # Issued Real-Time Credit Transfer + 'STDO': _('Standing Order'), + 'XBST': _('Cross-Border Standing Order'), + 'ESCT': _('SEPA Credit Transfer'), + 'DMCT': _('Domestic Credit Transfer'), + 'XBCT': _('Cross-Border Credit Transfer'), + 'FICT': _('Financial Institution Credit Transfer'), + 'PRCT': _('Priority Credit Transfer'), + 'VCOM': _('Credit Transfer with agreed Commercial Information'), + 'SALA': _('Payroll/Salary Payment'), + 'XBSA': _('Cross-Border Payroll/Salary Payment'), + 'RPCR': _('Reversal due to Payment Cancellation Request'), + 'RRTN': _('Reversal due to Payment Return/reimbursement of a Credit Transfer'), + 'SDVA': _('Same Day Value Credit Transfer'), + 'AUTT': _('Automatic Transfer'), + 'ATXN': _('ACH Transaction'), + 'ACOR': _('ACH Corporate Trade'), + 'APAC': _('ACH Pre-Authorised'), + 'ASET': _('ACH Settlement'), + 'ARET': _('ACH Return'), + 'AREV': _('ACH Reversal'), + 'ACDT': _('ACH Credit'), + 'ADBT': _('ACH Debit'), + 'TTLS': _('Treasury Tax And Loan Service'), + # Cash Management Sub-Families + 'XBRD': _('Cross-Border'), # Cash Pooling + 'ZABA': _('Zero Balancing'), # Account Balancing + 'SWEP': _('Sweeping'), + 'TOPG': _('Topping'), + 'DSBR': _('Controlled Disbursement'), + 'ODFT': _('Overdraft'), + 'XBRD': _('Cross-Border'), + # Derivatives Sub-Families + 'SWUF': _('Upfront Payment'), + 'SWRS': _('Reset Payment'), + 'SWPP': _('Partial Payment'), + 'SWFP': _('Final Payment'), + 'SWCC': _('Client Owned Collateral'), + # Loans, Deposits & Syndications Sub-Families + 'DDWN': _('Drawdown'), + 'RNEW': _('Renewal'), + 'PPAY': _('Principal Payment'), + 'DPST': _('Deposit'), + 'RPMT': _('Repayment'), + # Trade Services Sub-Families + 'FRZF': _('Freeze of funds'), + 'SOSI': _('Settlement of Sight Import document'), + 'SOSE': _('Settlement of Sight Export document'), + 'SABG': _('Settlement against bank guarantee'), + 'STLR': _('Settlement under reserve'), + 'STLR': _('Settlement under reserve'), + 'STAC': _('Settlement after collection'), + 'STLM': _('Settlement'), + # Securities Sub-Families + 'PAIR': _('Pair-Off'), # Trade, Clearing and Settlement & Non Settled + 'TRAD': _('Trade'), + 'NETT': _('Netting'), + 'TRPO': _('Triparty Repo'), + 'TRVO': _('Triparty Reverse Repo'), + 'RVPO': _('Reverse Repo'), + 'REPU': _('Repo'), + 'SECB': _('Securities Borrowing'), + 'SECL': _('Securities Lending'), + 'BSBO': _('Buy Sell Back'), + 'BSBC': _('Sell Buy Back'), + 'FCTA': _('Factor Update'), + 'ISSU': _('Depositary Receipt Issue'), + 'INSP': _('Inspeci/Share Exchange'), + 'OWNE': _('External Account Transfer'), + 'OWNI': _('Internal Account Transfer'), + 'NSYN': _('Non Syndicated'), + 'PLAC': _('Placement'), + 'PORT': _('Portfolio Move'), + 'SYND': _('Syndicated'), + 'TBAC': _('TBA closing'), + 'TURN': _('Turnaround'), + 'REDM': _('Redemption'), + 'SUBS': _('Subscription'), + 'CROS': _('Cross Trade'), + 'SWIC': _('Switch'), + 'REAA': _('Redemption Asset Allocation'), + 'SUAA': _('Subscription Asset Allocation'), + 'PRUD': _('Principal Pay-down/pay-up'), + 'TOUT': _('Transfer Out'), + 'TRIN': _('Transfer In'), + 'XCHC': _('Exchange Traded CCP'), + 'XCHG': _('Exchange Traded'), + 'XCHN': _('Exchange Traded Non-CCP'), + 'OTCC': _('OTC CCP'), + 'OTCG': _('OTC'), + 'OTCN': _('OTC Non-CCP'), + 'XCHC': _('Exchange Traded CCP'), # Blocked Transactions & CSD Blocked Transactions + 'XCHG': _('Exchange Traded'), + 'XCHN': _('Exchange Traded Non-CCP'), + 'OTCC': _('OTC CCP'), + 'OTCG': _('OTC'), + 'OTCN': _('OTC Non-CCP'), + 'MARG': _('Margin Payments'), # Collateral Management + 'TRPO': _('Triparty Repo'), + 'REPU': _('Repo'), + 'SECB': _('Securities Borrowing'), + 'SECL': _('Securities Lending'), + 'OPBC': _('Option broker owned collateral'), + 'OPCC': _('Option client owned collateral'), + 'FWBC': _('Forwards broker owned collateral'), + 'FWCC': _('Forwards client owned collateral'), + 'MGCC': _('Margin client owned cash collateral'), + 'SWBC': _('Swap broker owned collateral'), + 'EQCO': _('Equity mark client owned'), + 'EQBO': _('Equity mark broker owned'), + 'CMCO': _('Corporate mark client owned'), + 'CMBO': _('Corporate mark broker owned'), + 'SLBC': _('Lending Broker Owned Cash Collateral'), + 'SLCC': _('Lending Client Owned Cash Collateral'), + 'CPRB': _('Corporate Rebate'), + 'BIDS': _('Repurchase offer/Issuer Bid/Reverse Rights.'), # Corporate Action & Custody + 'BONU': _('Bonus Issue/Capitalisation Issue'), + 'BPUT': _('Put Redemption'), + 'CAPG': _('Capital Gains Distribution'), + 'CONV': _('Conversion'), + 'DECR': _('Decrease in Value'), + 'DRAW': _('Drawing'), + 'DRIP': _('Dividend Reinvestment'), + 'DTCH': _('Dutch Auction'), + 'DVCA': _('Cash Dividend'), + 'DVOP': _('Dividend Option'), + 'EXOF': _('Exchange'), + 'EXRI': _('Call on intermediate securities'), + 'EXWA': _('Warrant Exercise/Warrant Conversion'), + 'INTR': _('Interest Payment'), + 'LIQU': _('Liquidation Dividend / Liquidation Payment'), + 'MCAL': _('Full Call / Early Redemption'), + 'MRGR': _('Merger'), + 'ODLT': _('Odd Lot Sale/Purchase'), + 'PCAL': _('Partial Redemption with reduction of nominal value'), + 'PRED': _('Partial Redemption Without Reduction of Nominal Value'), + 'PRII': _('Interest Payment with Principle'), + 'PRIO': _('Priority Issue'), + 'REDM': _('Final Maturity'), + 'RHTS': _('Rights Issue/Subscription Rights/Rights Offer'), + 'SHPR': _('Equity Premium Reserve'), + 'TEND': _('Tender'), + 'TREC': _('Tax Reclaim'), + 'RWPL': _('Redemption Withdrawing Plan'), + 'SSPL': _('Subscription Savings Plan'), + 'CSLI': _('Cash in lieu'), + 'CHAR': _('Charge/fees'), # Miscellaneous Securities Operations + 'BKFE': _('Bank Fees'), + 'CLAI': _('Compensation/Claims'), + 'MNFE': _('Management Fees'), + 'OVCH': _('Overdraft Charge'), + 'TRFE': _('Transaction Fees'), + 'UNCO': _('Underwriting Commission'), + 'STAM': _('Stamp duty'), + 'WITH': _('Withholding Tax'), + 'BROK': _('Brokerage fee'), + 'PRIN': _('Interest Payment with Principle'), + 'TREC': _('Tax Reclaim'), + 'GEN1': _('Withdrawal/distribution'), + 'GEN2': _('Deposit/Contribution'), + 'ERWI': _('Borrowing fee'), + 'ERWA': _('Lending income'), + 'SWEP': _('Sweep'), + 'SWAP': _('Swap Payment'), + 'FUTU': _('Future Variation Margin'), + 'RESI': _('Futures Residual Amount'), + 'FUCO': _('Futures Commission'), + 'INFD': _('Fixed Deposit Interest Amount'), + # Account Management Sub-Families + 'ACCO': _('Account Opening'), + 'ACCC': _('Account Closing'), + 'ACCT': _('Account Transfer'), + 'VALD': _('Value Date'), + 'BCKV': _('Back Value'), + 'YTDA': _('YTD Adjustment'), + 'FLTA': _('Float adjustment'), + 'ERTA': _('Exchange Rate Adjustment'), + 'PSTE': _('Posting Error'), + # General + 'NTAV': _('Not available'), + 'OTHR': _('Other'), + 'MCOP': _('Miscellaneous Credit Operations'), + 'MDOP': _('Miscellaneous Debit Operations'), +} + + +def _generic_get(*nodes, xpath, namespaces, placeholder=None): + if placeholder is not None: + xpath = xpath.format(placeholder=placeholder) + for node in nodes: + item = node.xpath(xpath, namespaces=namespaces) + if item: + return item[0] + return False + +_get_amount = partial(_generic_get, + xpath='ns:Amt/text() | ns:AmtDtls/ns:TxAmt/ns:Amt/text()') + +_get_rate = partial(_generic_get, + xpath='ns:XchgRate/text() | ns:AmtDtls/ns:TxAmt/ns:CcyXchg/ns:XchgRate/text()') + +_get_credit_debit_indicator = partial(_generic_get, + xpath='ns:CdtDbtInd/text()') + +_get_transaction_date = partial(_generic_get, + xpath=('ns:ValDt/ns:Dt/text()' + '| ns:BookgDt/ns:Dt/text()' + '| ns:BookgDt/ns:DtTm/text()')) + +_get_partner_name = partial(_generic_get, + xpath='.//ns:RltdPties/ns:{placeholder}/ns:Nm/text()') + +_get_account_number = partial(_generic_get, + xpath=('.//ns:RltdPties/ns:{placeholder}Acct/ns:Id/ns:IBAN/text()' + '| (.//ns:{placeholder}Acct/ns:Id/ns:Othr/ns:Id)[1]/text()')) + +_get_main_ref = partial(_generic_get, + xpath='.//ns:RmtInf/ns:Strd/ns:{placeholder}RefInf/ns:Ref/text()') + +_get_other_ref = partial(_generic_get, + xpath=('ns:AcctSvcrRef/text()' + '| {placeholder}ns:Refs/ns:TxId/text()' + '| {placeholder}ns:Refs/ns:InstrId/text()' + '| {placeholder}ns:Refs/ns:EndToEndId/text()' + '| {placeholder}ns:Refs/ns:MndtId/text()' + '| {placeholder}ns:Refs/ns:ChqNb/text()')) + +_get_additional_entry_info = partial(_generic_get, + xpath='ns:AddtlNtryInf/text()') + +def _get_signed_amount(*nodes, namespaces): + amount = float(_get_amount(*nodes, namespaces=namespaces)) + rate = float(_get_rate(*nodes, namespaces=namespaces)) or 1.0 + sign = _get_credit_debit_indicator(*nodes, namespaces=namespaces) + return amount * rate if sign == 'CRDT' else -amount * rate + +def _get_counter_party(*nodes, namespaces): + ind = _get_credit_debit_indicator(*nodes, namespaces=namespaces) + return 'Dbtr' if ind == 'CRDT' else 'Cdtr' + +def _set_amount_currency_and_currency_id(node, path, entry_vals, currency, curr_cache, has_multi_currency, namespaces): + instruc_amount = node.xpath('%s/text()' % path, namespaces=namespaces) + instruc_curr = node.xpath('%s/@Ccy' % path, namespaces=namespaces) + if (has_multi_currency and instruc_amount and instruc_curr and + instruc_curr[0] != currency and instruc_curr[0] in curr_cache): + entry_vals['amount_currency'] = math.copysign(abs(sum(map(float, instruc_amount))), entry_vals['amount']) + entry_vals['currency_id'] = curr_cache[instruc_curr[0]] + +def _get_transaction_name(node, namespaces): + xpaths = ('.//ns:RmtInf/ns:Ustrd/text()', + './/ns:RmtInf/ns:Strd/ns:CdtrRefInf/ns:Ref/text()', + 'ns:AddtlNtryInf/text()') + for xpath in xpaths: + transaction_name = node.xpath(xpath, namespaces=namespaces) + if transaction_name: + return ' '.join(transaction_name) + return '/' + +def _get_ref(node, counter_party, prefix, namespaces): + ref = _get_main_ref(node, placeholder=counter_party, namespaces=namespaces) + if ref is False: # Explicitely match False, not a falsy value + ref = _get_other_ref(node, placeholder=prefix, namespaces=namespaces) + return ref + +def _get_unique_import_id(entry, sequence, name, date, unique_import_set, namespaces): + unique_import_ref = entry.xpath('ns:AcctSvcrRef/text()', namespaces=namespaces) + if unique_import_ref and not _is_full_of_zeros(unique_import_ref[0]) and unique_import_ref[0] != 'NOTPROVIDED': + entry_ref = entry.xpath('ns:NtryRef/text()', namespaces=namespaces) + if entry_ref: + return '{}-{}'.format(unique_import_ref[0], entry_ref[0]) + elif not entry_ref and unique_import_ref[0] not in unique_import_set: + return unique_import_ref[0] + else: + return '{}-{}'.format(unique_import_ref[0], sequence) + else: + return '{}-{}-{}'.format(name, date, sequence) + +def _get_transaction_type(node, namespaces): + code = node.xpath('ns:Domn/ns:Cd/text()', namespaces=namespaces) + family = node.xpath('ns:Domn/ns:Fmly/ns:Cd/text()', namespaces=namespaces) + subfamily = node.xpath('ns:Domn/ns:Fmly/ns:SubFmlyCd/text()', namespaces=namespaces) + if code: + return {'transaction_type': "{code}: {family} ({subfamily})".format( + code=codes[code[0]], + family=family and codes[family[0]] or '', + subfamily=subfamily and codes[subfamily[0]] or '', + )} + return {} + +def _get_partner_address(node, ns, ph): + StrtNm = node.xpath('ns:RltdPties/ns:{}/ns:PstlAdr/ns:StrtNm/text()'.format(ph), namespaces=ns) + BldgNb = node.xpath('ns:RltdPties/ns:{}/ns:PstlAdr/ns:BldgNb/text()'.format(ph), namespaces=ns) + PstCd = node.xpath('ns:RltdPties/ns:{}/ns:PstlAdr/ns:PstCd/text()'.format(ph), namespaces=ns) + TwnNm = node.xpath('ns:RltdPties/ns:{}/ns:PstlAdr/ns:TwnNm/text()'.format(ph), namespaces=ns) + Ctry = node.xpath('ns:RltdPties/ns:{}/ns:PstlAdr/ns:Ctry/text()'.format(ph), namespaces=ns) + AdrLine = node.xpath('ns:RltdPties/ns:{}/ns:PstlAdr/ns:AdrLine/text()'.format(ph), namespaces=ns) + address = "\n".join(AdrLine) + if StrtNm: + address = "\n".join([address, ", ".join(StrtNm + BldgNb)]) + if PstCd or TwnNm: + address = "\n".join([address, " ".join(PstCd + TwnNm)]) + if Ctry: + address = "\n".join([address, Ctry[0]]) + return address + +def _is_full_of_zeros(strg): + pattern_zero = re.compile('^0+$') + return bool(pattern_zero.match(strg)) + +class AccountBankStatementImport(models.TransientModel): + _inherit = 'account.bank.statement.import' + + def _check_camt(self, data_file): + try: + root = etree.parse(io.BytesIO(data_file)).getroot() + except: + return None + if root.tag.find('camt.053') != -1: + return root + return None + + def _parse_file(self, data_file): + root = self._check_camt(data_file) + if root is not None: + return self._parse_file_camt(root) + return super(AccountBankStatementImport, self)._parse_file(data_file) + + def _parse_file_camt(self, root): + ns = {k or 'ns': v for k, v in root.nsmap.items()} + + curr_cache = {c['name']: c['id'] for c in self.env['res.currency'].search_read([], ['id', 'name'])} + statements_per_iban = {} + currency_per_iban = {} + unique_import_set = set([]) + currency = account_no = False + has_multi_currency = self.env.user.user_has_groups('base.group_multi_currency') + for statement in root[0].findall('ns:Stmt', ns): + statement_vals = {} + statement_vals['name'] = statement.xpath('ns:Id/text()', namespaces=ns)[0] + statement_vals['date'] = (statement.xpath("ns:Bal/ns:Tp/ns:CdOrPrtry[ns:Cd='CLBD']/../../ns:Dt/ns:Dt/text()", namespaces=ns) or statement.xpath("ns:Bal/ns:Tp/ns:CdOrPrtry[ns:Cd='CLAV']/../../ns:Dt/ns:Dt/text()", namespaces=ns))[0] + + # Transaction Entries 0..n + transactions = [] + sequence = 0 + + # Currency 0..1 + currency = statement.xpath('ns:Acct/ns:Ccy/text() | ns:Bal/ns:Amt/@Ccy', namespaces=ns)[0] + + for entry in statement.findall('ns:Ntry', ns): + # Date 0..1 + date = _get_transaction_date(entry, namespaces=ns) or statement_vals['date'] + + transaction_details = entry.xpath('.//ns:TxDtls', namespaces=ns) + for entry_details in transaction_details or [entry]: + sequence += 1 + counter_party = _get_counter_party(entry_details, entry, namespaces=ns) + partner_name = _get_partner_name(entry_details, placeholder=counter_party, namespaces=ns) + entry_vals = { + 'sequence': sequence, + 'date': date, + 'amount': _get_signed_amount(entry_details, entry, namespaces=ns), + 'payment_ref': _get_transaction_name(entry_details, namespaces=ns), + 'partner_name': partner_name, + 'account_number': _get_account_number(entry_details, placeholder=counter_party, namespaces=ns), + 'ref': _get_ref(entry_details, counter_party=counter_party, prefix='', namespaces=ns), + } + + entry_vals['unique_import_id'] = _get_unique_import_id( + entry=entry_details, + sequence=sequence, + name=statement_vals['name'], + date=entry_vals['date'], + unique_import_set=unique_import_set, + namespaces=ns) + + _set_amount_currency_and_currency_id( + node=entry_details, + path=transaction_details and 'ns:AmtDtls/ns:InstdAmt/ns:Amt' or 'ns:NtryDtls/ns:TxDtls/ns:AmtDtls/ns:InstdAmt/ns:Amt', + entry_vals=entry_vals, + currency=currency, + curr_cache=curr_cache, + has_multi_currency=has_multi_currency, + namespaces=ns) + + BkTxCd = entry.xpath('ns:BkTxCd', namespaces=ns)[0] + entry_vals.update(_get_transaction_type(BkTxCd, namespaces=ns)) + notes = [_get_additional_entry_info(entry, namespaces=ns) or ""] + partner_address = _get_partner_address(entry_details, ns, counter_party) + if partner_name: + notes.append(_('Counter Party: %(partner)s', partner=partner_name)) + if partner_address: + notes.append(_('Address:\n') + partner_address) + entry_vals['narration'] = "\n".join(notes) + + unique_import_set.add(entry_vals['unique_import_id']) + transactions.append(entry_vals) + + statement_vals['transactions'] = transactions + + # Start Balance + # any (OPBD, PRCD, ITBD): + # OPBD : Opening Balance + # PRCD : Previous Closing Balance + # ITBD : Interim Balance (in the case of preceeding pagination) + start_amount = float(statement.xpath("ns:Bal/ns:Tp/ns:CdOrPrtry[ns:Cd='OPBD' or ns:Cd='PRCD' or ns:Cd='ITBD' or ns:Cd='OPAV']/../../ns:Amt/text()", + namespaces=ns)[0]) + # Credit Or Debit Indicator 1..1 + sign = statement.xpath('ns:Bal/ns:CdtDbtInd/text()', namespaces=ns)[0] + if sign == 'DBIT': + start_amount *= -1 + statement_vals['balance_start'] = start_amount + # Ending Balance + # Statement Date + # 'CLBD', otherwise 'CLAV' + # CLBD : Closing Balance + # CLAV : Closing Available + end_amount = float((statement.xpath("ns:Bal/ns:Tp/ns:CdOrPrtry[ns:Cd='CLBD']/../../ns:Amt/text()", namespaces=ns) or statement.xpath("ns:Bal/ns:Tp/ns:CdOrPrtry[ns:Cd='CLAV']/../../ns:Amt/text()", namespaces=ns))[0]) + sign = (statement.xpath("ns:Bal/ns:Tp/ns:CdOrPrtry[ns:Cd='CLBD']/../../ns:CdtDbtInd/text()", namespaces=ns) or statement.xpath("ns:Bal/ns:Tp/ns:CdOrPrtry[ns:Cd='CLAV']/../../ns:CdtDbtInd/text()", namespaces=ns))[0] + if sign == 'DBIT': + end_amount *= -1 + statement_vals['balance_end_real'] = end_amount + + # Account Number 1..1 + # if not IBAN value then... would have. + account_no = statement.xpath('ns:Acct/ns:Id/ns:IBAN/text() | ns:Acct/ns:Id/ns:Othr/ns:Id/text()', namespaces=ns)[0] + + # Save statements and currency + statements_per_iban.setdefault(account_no, []).append(statement_vals) + currency_per_iban[account_no] = currency + + # If statements target multiple journals, returns thoses targeting the current journal + if len(statements_per_iban) > 1: + account_no = self.env['account.journal'].browse(self.env.context.get('journal_id')).bank_acc_number + _logger.warning("The following statements will not be imported because they are targeting another journal (current journal id: %s):\n- %s", + account_no, "\n- ".join("{}: {} statement(s)".format(iban, len(statements)) for iban, statements in statements_per_iban.items() if iban != account_no)) + if not account_no: + raise UserError(_("Please set the IBAN account on your bank journal.\n\nThis CAMT file is targeting several IBAN accounts but none match the current journal.")) + + # Otherwise, returns those from only account_no + statement_list = statements_per_iban.get(account_no, []) + currency = currency_per_iban.get(account_no) + return currency, account_no, statement_list diff --git a/odex25_accounting/odex25_account_bank_statement_import_csv/__init__.py b/odex25_accounting/odex25_account_bank_statement_import_csv/__init__.py new file mode 100644 index 000000000..f17d5cfc4 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_csv/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + + +from . import models +from . import wizard diff --git a/odex25_accounting/odex25_account_bank_statement_import_csv/__manifest__.py b/odex25_accounting/odex25_account_bank_statement_import_csv/__manifest__.py new file mode 100644 index 000000000..083a61a15 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_csv/__manifest__.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- + + +{ + 'name': 'Import CSV Bank Statement', + 'category': 'Odex25-Accounting/Odex25-Accounting', + 'author': "Expert Co. Ltd.", + 'website': "http://www.exp-sa.com", + 'version': '1.0', + 'description': ''' +Module to import CSV bank statements. +====================================== + +This module allows you to import CSV Files in Odoo: they are parsed and stored in human readable format in +Accounting \ Bank and Cash \ Bank Statements. + +Important Note +--------------------------------------------- +Because of the CSV format limitation, we cannot ensure the same transactions aren't imported several times or handle multicurrency. +Whenever possible, you should use a more appropriate file format like OFX. +''', + 'depends': ['odex25_account_bank_statement_import', 'base_import'], + 'data': [ + 'wizard/odex25_account_bank_statement_import_views.xml', + 'views/odex25_account_bank_statement_import_templates.xml', + ], + 'installable': True, + 'auto_install': True, + +} diff --git a/odex25_accounting/odex25_account_bank_statement_import_csv/i18n/ar.po b/odex25_accounting/odex25_account_bank_statement_import_csv/i18n/ar.po new file mode 100644 index 000000000..0d7a965f8 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_csv/i18n/ar.po @@ -0,0 +1,84 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * odex25_account_bank_statement_import_csv +# +# Translators: +# Mustafa Rawi , 2020 +# Osama Ahmaro , 2020 +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server saas~13.5+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-09-01 07:39+0000\n" +"PO-Revision-Date: 2020-09-07 08:17+0000\n" +"Last-Translator: Osama Ahmaro , 2020\n" +"Language-Team: Arabic (https://www.transifex.com/odoo/teams/41243/ar/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: ar\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" + +#. module: odex25_account_bank_statement_import_csv +#: model:ir.model,name:odex25_account_bank_statement_import_csv.model_base_import_import +msgid "Base Import" +msgstr "الاستيراد الأساسي" + +#. module: odex25_account_bank_statement_import_csv +#: model_terms:ir.ui.view,arch_db:odex25_account_bank_statement_import_csv.odex25_account_bank_statement_import_csv +msgid "Comma-Separated values (CSV)" +msgstr "" + +#. module: odex25_account_bank_statement_import_csv +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_csv.field_odex25_account_bank_statement_import__display_name +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_csv.field_account_journal__display_name +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_csv.field_base_import_import__display_name +msgid "Display Name" +msgstr "الاسم المعروض" + +#. module: odex25_account_bank_statement_import_csv +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_csv.field_odex25_account_bank_statement_import__id +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_csv.field_account_journal__id +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_csv.field_base_import_import__id +msgid "ID" +msgstr "المُعرف" + +#. module: odex25_account_bank_statement_import_csv +#. openerp-web +#: code:addons/odex25_account_bank_statement_import_csv/static/src/js/import_bank_stmt.js:0 +#: model:ir.model,name:odex25_account_bank_statement_import_csv.model_odex25_account_bank_statement_import +#, python-format +msgid "Import Bank Statement" +msgstr "استيراد كشف حساب بنكي" + +#. module: odex25_account_bank_statement_import_csv +#: model:ir.model,name:odex25_account_bank_statement_import_csv.model_account_journal +msgid "Journal" +msgstr "دفتر اليومية" + +#. module: odex25_account_bank_statement_import_csv +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_csv.field_odex25_account_bank_statement_import____last_update +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_csv.field_account_journal____last_update +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_csv.field_base_import_import____last_update +msgid "Last Modified on" +msgstr "آخر تعديل في" + +#. module: odex25_account_bank_statement_import_csv +#: code:addons/odex25_account_bank_statement_import_csv/wizard/odex25_account_bank_statement_import_csv.py:0 +#, python-format +msgid "Mixing CSV files with other file types is not allowed." +msgstr "" + +#. module: odex25_account_bank_statement_import_csv +#: code:addons/odex25_account_bank_statement_import_csv/wizard/odex25_account_bank_statement_import_csv.py:0 +#, python-format +msgid "Only one CSV file can be selected." +msgstr "" + +#. module: odex25_account_bank_statement_import_csv +#. openerp-web +#: code:addons/odex25_account_bank_statement_import_csv/static/src/js/import_bank_stmt.js:0 +#, python-format +msgid "Reconciliation on Bank Statements" +msgstr "التسوية على كشوفات الحسابات البنكية" diff --git a/odex25_accounting/odex25_account_bank_statement_import_csv/models/__init__.py b/odex25_accounting/odex25_account_bank_statement_import_csv/models/__init__.py new file mode 100644 index 000000000..0c5073d1a --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_csv/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + + +from . import account_journal \ No newline at end of file diff --git a/odex25_accounting/odex25_account_bank_statement_import_csv/models/account_journal.py b/odex25_accounting/odex25_account_bank_statement_import_csv/models/account_journal.py new file mode 100644 index 000000000..501dcc396 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_csv/models/account_journal.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- + + +from odoo import models + + +class AccountJournal(models.Model): + _inherit = 'account.journal' + + def _get_bank_statements_available_import_formats(self): + rslt = super(AccountJournal, self)._get_bank_statements_available_import_formats() + rslt.append('CSV') + return rslt diff --git a/odex25_accounting/odex25_account_bank_statement_import_csv/static/csv/account.bank.statement.csv b/odex25_accounting/odex25_account_bank_statement_import_csv/static/csv/account.bank.statement.csv new file mode 100644 index 000000000..b27f72166 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_csv/static/csv/account.bank.statement.csv @@ -0,0 +1,6 @@ +Date,Reference,Partner,Label,Amount,Amount Currency,Currency,Cumulative Balance +2017-05-10,INV/2017/0001,,#01,4610,,,4710 +2017-05-11,Payment bill 20170521,,#02,-100,,,4610 +2017-05-15,INV/2017/0003 discount 2% early payment,,#03,514.5,,,5124.5 +2017-05-30,INV/2017/0002 + INV/2017/0004,,#04,5260,,,10384.5 +2017-05-31,Payment bill EUR 001234565,,#05,-537.15,-500,EUR,9847.35 diff --git a/odex25_accounting/odex25_account_bank_statement_import_csv/static/description/icon.png b/odex25_accounting/odex25_account_bank_statement_import_csv/static/description/icon.png new file mode 100644 index 000000000..4141f52da Binary files /dev/null and b/odex25_accounting/odex25_account_bank_statement_import_csv/static/description/icon.png differ diff --git a/odex25_accounting/odex25_account_bank_statement_import_csv/static/src/js/import_bank_stmt.js b/odex25_accounting/odex25_account_bank_statement_import_csv/static/src/js/import_bank_stmt.js new file mode 100644 index 000000000..4ad320b48 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_csv/static/src/js/import_bank_stmt.js @@ -0,0 +1,74 @@ +odoo.define('bank_stmt_import_csv.import', function (require) { +"use strict"; + +var core = require('web.core'); +var BaseImport = require('base_import.import') + +var QWeb = core.qweb; +var _t = core._t; +var _lt = core._lt; + +var DataImportStmt = BaseImport.DataImport.extend({ + init: function (parent, action) { + this._super.apply(this, arguments); + action.display_name = _t('Import Bank Statement'); // Displayed in the breadcrumbs + this.filename = action.params.filename || {}; + this.first_load = true; + }, + start: function () { + var self = this; + return this._super().then(function (res) { + self.id = self.parent_context.wizard_id; + self.$('input[name=import_id]').val(self.id); + self['loaded_file'](); + }); + }, + create_model: function() { + return Promise.resolve(); + }, + import_options: function () { + var options = this._super(); + options['bank_stmt_import'] = true; + return options; + }, + onfile_loaded: function () { + var self = this; + if (this.first_load) { + this.$('.oe_import_file_show').val(this.filename); + this.$('.oe_import_file_reload').hide(); + this.first_load = false; + self['settings_changed'](); + } + else { + this.$('.oe_import_file_reload').show(); + this._super(); + } + }, + call_import: function(kwargs) { + var self = this; + var superProm = self._super.apply(this, arguments); + superProm.then(function (message) { + if(message.ids){ + self.statement_line_ids = message.ids + } + }); + return superProm; + }, + exit: function () { + this.do_action({ + name: _t("Reconciliation on Bank Statements"), + context: { + 'statement_line_ids': this.statement_line_ids + }, + type: 'ir.actions.client', + tag: 'bank_statement_reconciliation_view' + }); + }, + +}); +core.action_registry.add('import_bank_stmt', DataImportStmt); + +return { + DataImportStmt: DataImportStmt, +}; +}); diff --git a/odex25_accounting/odex25_account_bank_statement_import_csv/test_csv_file/test_csv.csv b/odex25_accounting/odex25_account_bank_statement_import_csv/test_csv_file/test_csv.csv new file mode 100644 index 000000000..8e8bfea8e --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_csv/test_csv_file/test_csv.csv @@ -0,0 +1,20 @@ +02 01 15;;LAST STATEMENT;; $21,699.55 +02 02 15;;"DEBIT CARD 6906 EFF 02-01""01/31 MAILCHIMP MAILCHIMP.COMGA";($240.00); $21,459.55 +02 02 15;;"DEBIT CARD 6906 EFF 02-01""01/31 INDEED 203-564-2400 CT";($500.08); $20,959.46 +02 02 15;;"ACH CREDIT""AMERICAN EXPRESS-SETTLEMENT";$3,728.87 ; $24,688.34 +02 02 15;;"DEBIT CARD 6906""BAYSIDE MARKET/1 SAN FRANCISCO CA";($41.64); $24,646.70 +02 02 15;;"DEBIT CARD 6906""02/02 COMFORT INNS SAN FRANCISCOCA";($2,064.82); $22,581.88 +02 03 15;;"ACH CREDIT""CHECKFLUID INC -013015";$2,500.00 ; $25,081.88 +02 03 15;;"DEBIT CARD 6906""02/02 DISTRICT SF SAN FRANCISCOCA";($45.86); $25,036.02 +02 03 15;;"DEPOSIT-WIRED FUNDS""TVET OPERATING PLLC";$8,366.00 ; $33,402.02 +02 03 15;;"DEBIT CARD 6906""02/03 IBM USED PC 888S 188-874-6742 NY";($4,344.66); $29,057.36 +02 03 15;;"DEBIT CARD 6906""02/02 VIR ATL 9327 180-08628621 CT";($1,284.33); $27,773.03 +02 03 15;;"DEBIT CARD 6906""02/02 VIR ATL 9327 180-08628621 CT";($1,284.33); $26,488.70 +02 03 15;;"DEBIT CARD 6906""02/02 VIR ATL 9327 180-08628621 CT";($1,284.33); $25,204.37 +02 03 15;;"DEBIT CARD 6906""02/02 VIR ATL 9327 180-08628621 CT";($1,123.33); $24,081.04 +02 03 15;;"DEBIT CARD 6906""02/02 VIR ATL 9327 180-08628621 CT";($1,123.33); $22,957.71 +02 03 15;;"ACH DEBIT""AUTHNET GATEWAY -BILLING";($25.00); $22,932.71 +02 03 15;;"ACH DEBIT""WW 222 BROADWAY -ACH";($7,500.00); $15,432.71 +02 04 15;;"DEBIT CARD 6906""02/03 VIR ATL 9327 180-08628621 CT";($1,284.33); $14,148.38 +02 04 15;;"DEBIT CARD 6906""02/04 GROUPON INC 877-788-7858 IL";($204.23); $13,944.15 +02 05 15;;"ACH CREDIT""MERCHE-SOLUTIONS-MERCH DEP";$9,518.40 ; $23,462.55 diff --git a/odex25_accounting/odex25_account_bank_statement_import_csv/tests/__init__.py b/odex25_accounting/odex25_account_bank_statement_import_csv/tests/__init__.py new file mode 100644 index 000000000..a1f586b56 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_csv/tests/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + + +from . import test_import_bank_statement diff --git a/odex25_accounting/odex25_account_bank_statement_import_csv/tests/test_import_bank_statement.py b/odex25_accounting/odex25_account_bank_statement_import_csv/tests/test_import_bank_statement.py new file mode 100644 index 000000000..d0f453eab --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_csv/tests/test_import_bank_statement.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- + +from odoo.addons.account.tests.common import AccountTestInvoicingCommon +from odoo import fields +from odoo.tests import tagged +from odoo.modules.module import get_module_resource + + +@tagged('post_install', '-at_install') +class TestAccountBankStatementImportCSV(AccountTestInvoicingCommon): + + def test_csv_file_import(self): + # Get OFX file content + csv_file_path = get_module_resource('odex25_account_bank_statement_import_csv', 'test_csv_file', 'test_csv.csv') + csv_file = open(csv_file_path, 'rb').read() + + # Create a bank account and journal corresponding to the CSV file (same currency and account number) + bank_journal = self.env['account.journal'].create({ + 'name': 'Bank 123456', + 'code': 'BNK67', + 'type': 'bank', + 'bank_acc_number': '123456', + 'currency_id': self.env.ref("base.USD").id, + }) + + # Use an import wizard to process the file + import_wizard = self.env['base_import.import'].create({ + 'res_model': 'account.bank.statement.line', + 'file': csv_file, + 'file_name': 'test_csv.csv', + 'file_type': 'text/csv', + }) + import_wizard_options = { + 'date_format': '%m %d %y', + 'keep_matches': False, + 'encoding': 'utf-8', + 'fields': [], + 'quoting': '"', + 'bank_stmt_import': True, + 'headers': True, + 'separator': ';', + 'float_thousand_separator': ',', + 'float_decimal_separator': '.', + 'advanced': False, + } + import_wizard_fields = ['date', False, 'payment_ref', 'amount', 'balance'] + import_wizard.with_context(journal_id=bank_journal.id).do(import_wizard_fields, [], import_wizard_options, dryrun=False) + + # Check the imported bank statement + imported_statement = self.env['account.bank.statement'].search([('company_id', '=', self.env.company.id)]) + self.assertRecordValues(imported_statement, [{ + 'reference': 'test_csv.csv', + 'balance_start': 21699.55, + 'balance_end_real': 23462.55, + }]) + self.assertRecordValues(imported_statement.line_ids.sorted(lambda line: (line.date, line.payment_ref)), [ + {'date': fields.Date.from_string('2015-02-02'), 'amount': 3728.87, 'payment_ref': 'ACH CREDIT"AMERICAN EXPRESS-SETTLEMENT'}, + {'date': fields.Date.from_string('2015-02-02'), 'amount': -500.08, 'payment_ref': 'DEBIT CARD 6906 EFF 02-01"01/31 INDEED 203-564-2400 CT'}, + {'date': fields.Date.from_string('2015-02-02'), 'amount': -240.00, 'payment_ref': 'DEBIT CARD 6906 EFF 02-01"01/31 MAILCHIMP MAILCHIMP.COMGA'}, + {'date': fields.Date.from_string('2015-02-02'), 'amount': -2064.82, 'payment_ref': 'DEBIT CARD 6906"02/02 COMFORT INNS SAN FRANCISCOCA'}, + {'date': fields.Date.from_string('2015-02-02'), 'amount': -41.64, 'payment_ref': 'DEBIT CARD 6906"BAYSIDE MARKET/1 SAN FRANCISCO CA'}, + {'date': fields.Date.from_string('2015-02-03'), 'amount': 2500.00, 'payment_ref': 'ACH CREDIT"CHECKFLUID INC -013015'}, + {'date': fields.Date.from_string('2015-02-03'), 'amount': -25.00, 'payment_ref': 'ACH DEBIT"AUTHNET GATEWAY -BILLING'}, + {'date': fields.Date.from_string('2015-02-03'), 'amount': -7500.00, 'payment_ref': 'ACH DEBIT"WW 222 BROADWAY -ACH'}, + {'date': fields.Date.from_string('2015-02-03'), 'amount': -45.86, 'payment_ref': 'DEBIT CARD 6906"02/02 DISTRICT SF SAN FRANCISCOCA'}, + {'date': fields.Date.from_string('2015-02-03'), 'amount': -1284.33, 'payment_ref': 'DEBIT CARD 6906"02/02 VIR ATL 9327 180-08628621 CT'}, + {'date': fields.Date.from_string('2015-02-03'), 'amount': -1284.33, 'payment_ref': 'DEBIT CARD 6906"02/02 VIR ATL 9327 180-08628621 CT'}, + {'date': fields.Date.from_string('2015-02-03'), 'amount': -1284.33, 'payment_ref': 'DEBIT CARD 6906"02/02 VIR ATL 9327 180-08628621 CT'}, + {'date': fields.Date.from_string('2015-02-03'), 'amount': -1123.33, 'payment_ref': 'DEBIT CARD 6906"02/02 VIR ATL 9327 180-08628621 CT'}, + {'date': fields.Date.from_string('2015-02-03'), 'amount': -1123.33, 'payment_ref': 'DEBIT CARD 6906"02/02 VIR ATL 9327 180-08628621 CT'}, + {'date': fields.Date.from_string('2015-02-03'), 'amount': -4344.66, 'payment_ref': 'DEBIT CARD 6906"02/03 IBM USED PC 888S 188-874-6742 NY'}, + {'date': fields.Date.from_string('2015-02-03'), 'amount': 8366.00, 'payment_ref': 'DEPOSIT-WIRED FUNDS"TVET OPERATING PLLC'}, + {'date': fields.Date.from_string('2015-02-04'), 'amount': -1284.33, 'payment_ref': 'DEBIT CARD 6906"02/03 VIR ATL 9327 180-08628621 CT'}, + {'date': fields.Date.from_string('2015-02-04'), 'amount': -204.23, 'payment_ref': 'DEBIT CARD 6906"02/04 GROUPON INC 877-788-7858 IL'}, + {'date': fields.Date.from_string('2015-02-05'), 'amount': 9518.40, 'payment_ref': 'ACH CREDIT"MERCHE-SOLUTIONS-MERCH DEP'}, + ]) diff --git a/odex25_accounting/odex25_account_bank_statement_import_csv/views/odex25_account_bank_statement_import_templates.xml b/odex25_accounting/odex25_account_bank_statement_import_csv/views/odex25_account_bank_statement_import_templates.xml new file mode 100644 index 000000000..67f845318 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_csv/views/odex25_account_bank_statement_import_templates.xml @@ -0,0 +1,8 @@ + + + + diff --git a/odex25_accounting/odex25_account_bank_statement_import_csv/wizard/__init__.py b/odex25_accounting/odex25_account_bank_statement_import_csv/wizard/__init__.py new file mode 100644 index 000000000..ef9a9a457 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_csv/wizard/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + + +from . import odex25_account_bank_statement_import_csv diff --git a/odex25_accounting/odex25_account_bank_statement_import_csv/wizard/odex25_account_bank_statement_import_csv.py b/odex25_accounting/odex25_account_bank_statement_import_csv/wizard/odex25_account_bank_statement_import_csv.py new file mode 100644 index 000000000..3cdd5b4e0 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_csv/wizard/odex25_account_bank_statement_import_csv.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- + + +import base64 +import psycopg2 + +from odoo import _, api, models +from odoo.exceptions import UserError + + +class AccountBankStatementImport(models.TransientModel): + _inherit = "account.bank.statement.import" + + def _check_csv(self, filename): + return filename and filename.lower().strip().endswith('.csv') + + def import_file(self): + # In case of CSV files, only one file can be imported at a time. + if len(self.attachment_ids) > 1: + csv = [bool(self._check_csv(att.name)) for att in self.attachment_ids] + if True in csv and False in csv: + raise UserError(_('Mixing CSV files with other file types is not allowed.')) + if csv.count(True) > 1: + raise UserError(_('Only one CSV file can be selected.')) + return super(AccountBankStatementImport, self).import_file() + + if not self._check_csv(self.attachment_ids.name): + return super(AccountBankStatementImport, self).import_file() + ctx = dict(self.env.context) + import_wizard = self.env['base_import.import'].create({ + 'res_model': 'account.bank.statement.line', + 'file': base64.b64decode(self.attachment_ids.datas), + 'file_name': self.attachment_ids.name, + 'file_type': 'text/csv' + }) + ctx['wizard_id'] = import_wizard.id + return { + 'type': 'ir.actions.client', + 'tag': 'import_bank_stmt', + 'params': { + 'model': 'account.bank.statement.line', + 'context': ctx, + 'filename': self.attachment_ids.name, + } + } + + +class AccountBankStmtImportCSV(models.TransientModel): + + _inherit = 'base_import.import' + + @api.model + def get_fields(self, model, depth=2): + fields_list = super(AccountBankStmtImportCSV, self).get_fields(model, depth=depth) + if self._context.get('bank_stmt_import', False): + add_fields = [{ + 'id': 'balance', + 'name': 'balance', + 'string': 'Cumulative Balance', + 'required': False, + 'fields': [], + 'type': 'monetary', + }, { + 'id': 'debit', + 'name': 'debit', + 'string': 'Debit', + 'required': False, + 'fields': [], + 'type': 'monetary', + }, { + 'id': 'credit', + 'name': 'credit', + 'string': 'Credit', + 'required': False, + 'fields': [], + 'type': 'monetary', + }] + fields_list.extend(add_fields) + return fields_list + + def _convert_to_float(self, value): + return float(value) if value else 0.0 + + def _parse_import_data(self, data, import_fields, options): + data = super(AccountBankStmtImportCSV, self)._parse_import_data(data, import_fields, options) + statement_id = self._context.get('bank_statement_id', False) + if not statement_id: + return data + statement = self.env['account.bank.statement'].browse(statement_id) + company_currency_name = statement.company_id.currency_id.name + ret_data = [] + + vals = {} + import_fields.append('statement_id/.id') + import_fields.append('sequence') + index_balance = False + convert_to_amount = False + if 'debit' in import_fields and 'credit' in import_fields: + index_debit = import_fields.index('debit') + index_credit = import_fields.index('credit') + self._parse_float_from_data(data, index_debit, 'debit', options) + self._parse_float_from_data(data, index_credit, 'credit', options) + import_fields.append('amount') + convert_to_amount = True + # add starting balance and ending balance to context + if 'balance' in import_fields: + index_balance = import_fields.index('balance') + self._parse_float_from_data(data, index_balance, 'balance', options) + vals['balance_start'] = self._convert_to_float(data[0][index_balance]) + vals['balance_start'] -= self._convert_to_float(data[0][import_fields.index('amount')]) \ + if not convert_to_amount \ + else abs(self._convert_to_float(data[0][index_credit]))-abs(self._convert_to_float(data[0][index_debit])) + vals['balance_end_real'] = data[len(data)-1][index_balance] + import_fields.remove('balance') + # Remove debit/credit field from import_fields + if convert_to_amount: + import_fields.remove('debit') + import_fields.remove('credit') + + currency_index = 'currency_id' in import_fields and import_fields.index('currency_id') or False + for index, line in enumerate(data): + line.append(statement_id) + line.append(index) + remove_index = [] + if convert_to_amount: + line.append( + abs(self._convert_to_float(line[index_credit])) + - abs(self._convert_to_float(line[index_debit])) + ) + remove_index.extend([index_debit, index_credit]) + if index_balance: + remove_index.append(index_balance) + # Remove added field debit/credit/balance + for index in sorted(remove_index, reverse=True): + line.remove(line[index]) + if line[import_fields.index('amount')]: + ret_data.append(line) + # Don't set the currency_id on statement line if the currency is the same as the company one. + if currency_index is not False and line[currency_index] == company_currency_name: + line[currency_index] = False + if 'date' in import_fields: + vals['date'] = data[len(data)-1][import_fields.index('date')] + + # add starting balance and date if there is one set in fields + if vals: + statement.write(vals) + return ret_data + + def parse_preview(self, options, count=10): + if options.get('bank_stmt_import', False): + self = self.with_context(bank_stmt_import=True) + return super(AccountBankStmtImportCSV, self).parse_preview(options, count=count) + + def do(self, fields, columns, options, dryrun=False): + if options.get('bank_stmt_import', False): + self._cr.execute('SAVEPOINT import_bank_stmt') + vals = { + 'journal_id': self._context.get('journal_id', False), + 'reference': self.file_name + } + statement = self.env['account.bank.statement'].create(vals) + res = super(AccountBankStmtImportCSV, self.with_context(bank_statement_id=statement.id)).do(fields, columns, options, dryrun=dryrun) + + try: + if dryrun: + self._cr.execute('ROLLBACK TO SAVEPOINT import_bank_stmt') + else: + self._cr.execute('RELEASE SAVEPOINT import_bank_stmt') + res['messages'].append({ + 'statement_id': statement.id, + 'type': 'bank_statement' + }) + except psycopg2.InternalError: + pass + return res + else: + return super(AccountBankStmtImportCSV, self).do(fields, columns, options, dryrun=dryrun) diff --git a/odex25_accounting/odex25_account_bank_statement_import_csv/wizard/odex25_account_bank_statement_import_views.xml b/odex25_accounting/odex25_account_bank_statement_import_csv/wizard/odex25_account_bank_statement_import_views.xml new file mode 100644 index 000000000..50586e0c5 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_csv/wizard/odex25_account_bank_statement_import_views.xml @@ -0,0 +1,13 @@ + + + + Upload Bank Statements CSV + account.bank.statement.import + + + +
  • Comma-Separated values (CSV)
  • +
    +
    +
    +
    diff --git a/odex25_accounting/odex25_account_bank_statement_import_ofx/__init__.py b/odex25_accounting/odex25_account_bank_statement_import_ofx/__init__.py new file mode 100644 index 000000000..f17d5cfc4 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_ofx/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + + +from . import models +from . import wizard diff --git a/odex25_accounting/odex25_account_bank_statement_import_ofx/__manifest__.py b/odex25_accounting/odex25_account_bank_statement_import_ofx/__manifest__.py new file mode 100644 index 000000000..ed40181a8 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_ofx/__manifest__.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- + + +{ + 'name': 'Import OFX Bank Statement', + 'category': 'Odex25-Accounting/Odex25-Accounting', + 'author': "Expert Co. Ltd.", + 'website': "http://www.exp-sa.com", + 'version': '1.0', + 'depends': ['odex25_account_bank_statement_import'], + 'description': """ +Module to import OFX bank statements. +====================================== + +This module allows you to import the machine readable OFX Files in Odoo: they are parsed and stored in human readable format in +Accounting \ Bank and Cash \ Bank Statements. + +Bank Statements may be generated containing a subset of the OFX information (only those transaction lines that are required for the +creation of the Financial Accounting records). + """, + 'data': [ + 'wizard/odex25_account_bank_statement_import_views.xml', + ], + 'installable': True, + 'auto_install': True, + +} diff --git a/odex25_accounting/odex25_account_bank_statement_import_ofx/i18n/ar.po b/odex25_accounting/odex25_account_bank_statement_import_ofx/i18n/ar.po new file mode 100644 index 000000000..0034df52b --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_ofx/i18n/ar.po @@ -0,0 +1,60 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * odex25_account_bank_statement_import_ofx +# +# Translators: +# Mustafa Rawi , 2020 +# Osama Ahmaro , 2020 +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server saas~13.5+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-09-01 07:39+0000\n" +"PO-Revision-Date: 2020-09-07 08:17+0000\n" +"Last-Translator: Osama Ahmaro , 2020\n" +"Language-Team: Arabic (https://www.transifex.com/odoo/teams/41243/ar/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: ar\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" + +#. module: odex25_account_bank_statement_import_ofx +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_ofx.field_odex25_account_bank_statement_import__display_name +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_ofx.field_account_journal__display_name +msgid "Display Name" +msgstr "الاسم المعروض" + +#. module: odex25_account_bank_statement_import_ofx +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_ofx.field_odex25_account_bank_statement_import__id +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_ofx.field_account_journal__id +msgid "ID" +msgstr "المُعرف" + +#. module: odex25_account_bank_statement_import_ofx +#: model:ir.model,name:odex25_account_bank_statement_import_ofx.model_odex25_account_bank_statement_import +msgid "Import Bank Statement" +msgstr "استيراد كشف حساب بنكي" + +#. module: odex25_account_bank_statement_import_ofx +#: model:ir.model,name:odex25_account_bank_statement_import_ofx.model_account_journal +msgid "Journal" +msgstr "دفتر اليومية" + +#. module: odex25_account_bank_statement_import_ofx +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_ofx.field_odex25_account_bank_statement_import____last_update +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_ofx.field_account_journal____last_update +msgid "Last Modified on" +msgstr "آخر تعديل في" + +#. module: odex25_account_bank_statement_import_ofx +#: model_terms:ir.ui.view,arch_db:odex25_account_bank_statement_import_ofx.odex25_account_bank_statement_import_ofx +msgid "Open Financial Exchange (OFX)" +msgstr "" + +#. module: odex25_account_bank_statement_import_ofx +#: code:addons/odex25_account_bank_statement_import_ofx/wizard/odex25_account_bank_statement_import_ofx.py:0 +#, python-format +msgid "The library 'ofxparse' is missing, OFX import cannot proceed." +msgstr "المكتبة 'ofxparse' غير مثبتة، لن يمكن استيراد ملفات OFX بدونها." diff --git a/odex25_accounting/odex25_account_bank_statement_import_ofx/models/__init__.py b/odex25_accounting/odex25_account_bank_statement_import_ofx/models/__init__.py new file mode 100644 index 000000000..0c5073d1a --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_ofx/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + + +from . import account_journal \ No newline at end of file diff --git a/odex25_accounting/odex25_account_bank_statement_import_ofx/models/account_journal.py b/odex25_accounting/odex25_account_bank_statement_import_ofx/models/account_journal.py new file mode 100644 index 000000000..0421065a9 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_ofx/models/account_journal.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- + + +from odoo import models + + +class AccountJournal(models.Model): + _inherit = 'account.journal' + + def _get_bank_statements_available_import_formats(self): + rslt = super(AccountJournal, self)._get_bank_statements_available_import_formats() + rslt.append('OFX') + return rslt diff --git a/odex25_accounting/odex25_account_bank_statement_import_ofx/static/description/icon.png b/odex25_accounting/odex25_account_bank_statement_import_ofx/static/description/icon.png new file mode 100644 index 000000000..ab61e2f37 Binary files /dev/null and b/odex25_accounting/odex25_account_bank_statement_import_ofx/static/description/icon.png differ diff --git a/odex25_accounting/odex25_account_bank_statement_import_ofx/static/ofx/test_ofx.ofx b/odex25_accounting/odex25_account_bank_statement_import_ofx/static/ofx/test_ofx.ofx new file mode 100644 index 000000000..e23d0fed9 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_ofx/static/ofx/test_ofx.ofx @@ -0,0 +1,100 @@ + + + + + + + 0 + INFO + + 20130831165153.000[-8:PST] + ENG + + + + + 0 + + 0 + INFO + + + USD + + 000000123 + 123456 + CHECKING + + + 20130801 + 20130831165153.000[-8:PST] + + POS + 20130824080000 + -80 + 219378 + Norbert Brant + + + + 20130801 + 20130831165153.000[-8:PST] + + POS + 20130824080000 + -90 + 219379 + China Export + + + + 20130801 + 20130831165153.000[-8:PST] + + POS + 20130824080000 + -100 + 219380 + Axelor Scuba + + + + 20130801 + 20130831165153.000[-8:PST] + + POS + 20130824080000 + -90 + 219381 + China Scuba + + + + 2156.56 + 20130831165153 + + + + + + + 0 + + 0 + INFO + + + USD + + 123456 + + + + + -562.00 + 20130831165153 + + + + + diff --git a/odex25_accounting/odex25_account_bank_statement_import_ofx/tests/__init__.py b/odex25_accounting/odex25_account_bank_statement_import_ofx/tests/__init__.py new file mode 100644 index 000000000..a1f586b56 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_ofx/tests/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + + +from . import test_import_bank_statement diff --git a/odex25_accounting/odex25_account_bank_statement_import_ofx/tests/test_import_bank_statement.py b/odex25_accounting/odex25_account_bank_statement_import_ofx/tests/test_import_bank_statement.py new file mode 100644 index 000000000..a261d9b40 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_ofx/tests/test_import_bank_statement.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- + +from odoo.addons.account.tests.common import AccountTestInvoicingCommon +from odoo.tests import tagged +from odoo.modules.module import get_module_resource + +import base64 + + +@tagged('post_install', '-at_install') +class TestAccountBankStatementImportOFX(AccountTestInvoicingCommon): + + def test_ofx_file_import(self): + bank_journal = self.env['account.journal'].create({ + 'name': 'Bank 123456', + 'code': 'BNK67', + 'type': 'bank', + 'bank_acc_number': '123456', + 'currency_id': self.env.ref('base.USD').id, + }) + + partner_norbert = self.env['res.partner'].create({ + 'name': 'Norbert Brant', + 'is_company': True, + }) + bank_norbert = self.env['res.bank'].create({'name': 'test'}) + partner_bank_norbert = self.env['res.partner.bank'].create({ + 'acc_number': 'BE93999574162167', + 'partner_id': partner_norbert.id, + 'bank_id': bank_norbert.id, + }) + + # Get OFX file content + ofx_file_path = get_module_resource('odex25_account_bank_statement_import_ofx', 'static/ofx', 'test_ofx.ofx') + ofx_file = base64.b64encode(open(ofx_file_path, 'rb').read()) + + # Use an import wizard to process the file + self.env['account.bank.statement.import']\ + .with_context(journal_id=bank_journal.id)\ + .create({'attachment_ids': [(0, 0, {'name': 'test_ofx.ofx', 'datas': ofx_file})]})\ + .import_file() + + # Check the imported bank statement + imported_statement = self.env['account.bank.statement'].search([('company_id', '=', self.env.company.id)]) + self.assertRecordValues(imported_statement, [{ + 'reference': 'test_ofx.ofx', + 'balance_start': 2516.56, + 'balance_end_real': 2156.56, + }]) + self.assertRecordValues(imported_statement.line_ids.sorted('payment_ref'), [ + { + 'payment_ref': 'Axelor Scuba', + 'amount': -100.0, + 'partner_id': False, + 'partner_bank_id': False, + }, + { + 'payment_ref': 'China Export', + 'amount': -90.0, + 'partner_id': False, + 'partner_bank_id': False, + }, + { + 'payment_ref': 'China Scuba', + 'amount': -90.0, + 'partner_id': False, + 'partner_bank_id': False, + }, + { + 'payment_ref': partner_norbert.name, + 'amount': -80.0, + 'partner_id': partner_norbert.id, + 'partner_bank_id': partner_bank_norbert.id, + }, + ]) diff --git a/odex25_accounting/odex25_account_bank_statement_import_ofx/wizard/__init__.py b/odex25_accounting/odex25_account_bank_statement_import_ofx/wizard/__init__.py new file mode 100644 index 000000000..1965e9921 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_ofx/wizard/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + + +from . import odex25_account_bank_statement_import_ofx diff --git a/odex25_accounting/odex25_account_bank_statement_import_ofx/wizard/odex25_account_bank_statement_import_ofx.py b/odex25_accounting/odex25_account_bank_statement_import_ofx/wizard/odex25_account_bank_statement_import_ofx.py new file mode 100644 index 000000000..141beccc0 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_ofx/wizard/odex25_account_bank_statement_import_ofx.py @@ -0,0 +1,164 @@ +# -*- coding: utf-8 -*- + + +import datetime +import io +import logging +import re +import unicodedata +from xml.etree import ElementTree + +try: + from ofxparse import OfxParser + from ofxparse.ofxparse import OfxParserException + OfxParserClass = OfxParser +except ImportError: + logging.getLogger(__name__).warning("The ofxparse python library is not installed, ofx import will not work.") + OfxParser = OfxParserException = None + OfxParserClass = object + +from odoo import models, _ +from odoo.exceptions import UserError + + +class PatchedOfxParser(OfxParserClass): + """ This class monkey-patches the ofxparse library in order to fix the following known bug: ',' is a valid + decimal separator for amounts, as we can encounter in ofx files made by european banks. + """ + + @classmethod + def decimal_separator_cleanup(cls_, tag): + if hasattr(tag, "contents"): + tag.string = tag.contents[0].replace(',', '.') + + @classmethod + def parseStatement(cls_, stmt_ofx): + ledger_bal_tag = stmt_ofx.find('ledgerbal') + if hasattr(ledger_bal_tag, "contents"): + balamt_tag = ledger_bal_tag.find('balamt') + cls_.decimal_separator_cleanup(balamt_tag) + avail_bal_tag = stmt_ofx.find('availbal') + if hasattr(avail_bal_tag, "contents"): + balamt_tag = avail_bal_tag.find('balamt') + cls_.decimal_separator_cleanup(balamt_tag) + return super(PatchedOfxParser, cls_).parseStatement(stmt_ofx) + + @classmethod + def parseTransaction(cls_, txn_ofx): + amt_tag = txn_ofx.find('trnamt') + cls_.decimal_separator_cleanup(amt_tag) + return super(PatchedOfxParser, cls_).parseTransaction(txn_ofx) + + @classmethod + def parseInvestmentPosition(cls_, ofx): + tag = ofx.find('units') + cls_.decimal_separator_cleanup(tag) + tag = ofx.find('unitprice') + cls_.decimal_separator_cleanup(tag) + return super(PatchedOfxParser, cls_).parseInvestmentPosition(ofx) + + @classmethod + def parseInvestmentTransaction(cls_, ofx): + tag = ofx.find('units') + cls_.decimal_separator_cleanup(tag) + tag = ofx.find('unitprice') + cls_.decimal_separator_cleanup(tag) + return super(PatchedOfxParser, cls_).parseInvestmentTransaction(ofx) + + @classmethod + def parseOfxDateTime(cls_, ofxDateTime): + res = re.search("^[0-9]*\.([0-9]{0,5})", ofxDateTime) + if res: + msec = datetime.timedelta(seconds=float("0." + res.group(1))) + else: + msec = datetime.timedelta(seconds=0) + + # Some banks seem to return some OFX dates as YYYY-MM-DD; so we remove + # the '-' characters to support them as well + ofxDateTime = ofxDateTime.replace('-', '') + + try: + local_date = datetime.datetime.strptime( + ofxDateTime[:14], '%Y%m%d%H%M%S' + ) + return local_date + msec + except: + if ofxDateTime[:8] == "00000000": + return None + + return datetime.datetime.strptime( + ofxDateTime[:8], '%Y%m%d') + msec + + +class AccountBankStatementImport(models.TransientModel): + _inherit = 'account.bank.statement.import' + + def _check_ofx(self, data_file): + if data_file.startswith(b"OFXHEADER"): + #v1 OFX + return True + try: + #v2 OFX + return b"" in data_file.lower() + except ElementTree.ParseError: + return False + + def _parse_file(self, data_file): + if not self._check_ofx(data_file): + return super(AccountBankStatementImport, self)._parse_file(data_file) + if OfxParser is None: + raise UserError(_("The library 'ofxparse' is missing, OFX import cannot proceed.")) + + try: + ofx = PatchedOfxParser.parse(io.BytesIO(data_file)) + except UnicodeDecodeError: + # Replacing utf-8 chars with ascii equivalent + encoding = re.findall(b'encoding="(.*?)"', data_file) + encoding = encoding[0] if len(encoding) > 1 else 'utf-8' + data_file = unicodedata.normalize('NFKD', data_file.decode(encoding)).encode('ascii', 'ignore') + ofx = PatchedOfxParser.parse(io.BytesIO(data_file)) + vals_bank_statement = [] + account_lst = set() + currency_lst = set() + for account in ofx.accounts: + account_lst.add(account.number) + currency_lst.add(account.statement.currency) + transactions = [] + total_amt = 0.00 + for transaction in account.statement.transactions: + # Since ofxparse doesn't provide account numbers, we'll have to find res.partner and res.partner.bank here + # (normal behaviour is to provide 'account_number', which the generic module uses to find partner/bank) + bank_account_id = partner_id = False + partner_bank = self.env['res.partner.bank'].search([('partner_id.name', '=', transaction.payee)], limit=1) + if partner_bank: + bank_account_id = partner_bank.id + partner_id = partner_bank.partner_id.id + vals_line = { + 'date': transaction.date, + 'payment_ref': transaction.payee + (transaction.memo and ': ' + transaction.memo or ''), + 'ref': transaction.id, + 'amount': float(transaction.amount), + 'unique_import_id': transaction.id, + 'partner_bank_id': bank_account_id, + 'partner_id': partner_id, + 'sequence': len(transactions) + 1, + } + total_amt += float(transaction.amount) + transactions.append(vals_line) + + vals_bank_statement.append({ + 'transactions': transactions, + # WARNING: the provided ledger balance is not necessarily the ending balance of the statement + # see https://github.com/odoo/odoo/issues/3003 + 'balance_start': float(account.statement.balance) - total_amt, + 'balance_end_real': account.statement.balance, + }) + + if account_lst and len(account_lst) == 1: + account_lst = account_lst.pop() + currency_lst = currency_lst.pop() + else: + account_lst = None + currency_lst = None + + return currency_lst, account_lst, vals_bank_statement diff --git a/odex25_accounting/odex25_account_bank_statement_import_ofx/wizard/odex25_account_bank_statement_import_views.xml b/odex25_accounting/odex25_account_bank_statement_import_ofx/wizard/odex25_account_bank_statement_import_views.xml new file mode 100644 index 000000000..a926e1806 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_ofx/wizard/odex25_account_bank_statement_import_views.xml @@ -0,0 +1,13 @@ + + + + Upload Bank Statements OFX + account.bank.statement.import + + + +
  • Open Financial Exchange (OFX)
  • +
    +
    +
    +
    diff --git a/odex25_accounting/odex25_account_bank_statement_import_qif/__init__.py b/odex25_accounting/odex25_account_bank_statement_import_qif/__init__.py new file mode 100644 index 000000000..f17d5cfc4 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_qif/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + + +from . import models +from . import wizard diff --git a/odex25_accounting/odex25_account_bank_statement_import_qif/__manifest__.py b/odex25_accounting/odex25_account_bank_statement_import_qif/__manifest__.py new file mode 100644 index 000000000..6d76f1e97 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_qif/__manifest__.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- + + +{ + 'name': 'Import QIF Bank Statement', + 'category': 'Odex25-Accounting/Odex25-Accounting', + 'author': "Expert Co. Ltd.", + 'website': "http://www.exp-sa.com", + 'version': '1.0', + 'description': ''' +Module to import QIF bank statements. +====================================== + +This module allows you to import the machine readable QIF Files in Odoo: they are parsed and stored in human readable format in +Accounting \ Bank and Cash \ Bank Statements. + +Important Note +--------------------------------------------- +Because of the QIF format limitation, we cannot ensure the same transactions aren't imported several times or handle multicurrency. +Whenever possible, you should use a more appropriate file format like OFX. +''', + 'depends': ['odex25_account_bank_statement_import'], + 'data': [ + 'wizard/odex25_account_bank_statement_import_views.xml', + ], + 'installable': True, + 'auto_install': False, + +} diff --git a/odex25_accounting/odex25_account_bank_statement_import_qif/i18n/ar.po b/odex25_accounting/odex25_account_bank_statement_import_qif/i18n/ar.po new file mode 100644 index 000000000..77929225c --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_qif/i18n/ar.po @@ -0,0 +1,157 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * odex25_account_bank_statement_import_qif +# +# Translators: +# Mustafa Rawi , 2020 +# Martin Trigaux, 2020 +# Osama Ahmaro , 2020 +# Islam Eldeeb , 2020 +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server saas~13.5+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-09-01 07:39+0000\n" +"PO-Revision-Date: 2020-09-07 08:17+0000\n" +"Last-Translator: Islam Eldeeb , 2020\n" +"Language-Team: Arabic (https://www.transifex.com/odoo/teams/41243/ar/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Language: ar\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" + +#. module: odex25_account_bank_statement_import_qif +#: model:ir.model.fields,help:odex25_account_bank_statement_import_qif.field_odex25_account_bank_statement_import__journal_id +msgid "" +"Accounting journal related to the bank statement you're importing. It has to" +" be manually chosen for statement formats which doesn't allow automatic " +"journal detection (QIF for example)." +msgstr "" +"دفتر اليومية المحاسبية المقترن بكشف الحساب البنكي الذي تقوم باستيراده. يجب " +"أن يتم اختياره يدويًا لأن بعض صيغ كشوفات الحساب لا تسمح بالكشف عن دفتر " +"اليومية آلياً (ملفات QIF مثلًا)." + +#. module: odex25_account_bank_statement_import_qif +#: model:ir.model.fields,help:odex25_account_bank_statement_import_qif.field_odex25_account_bank_statement_import__qif_date_format +msgid "" +"Although the historic QIF date format is month-first (mm/dd/yy), many " +"financial institutions use the local format.Therefore, it is frequent " +"outside the US to have QIF date formated day-first (dd/mm/yy)." +msgstr "" +"بالرغم من أن نظام تنسيق التواريخ المعتاد بملفات QIF هو البدء بالشهر " +"(شهر/يوم/سنة)، إلا أن مؤسسات مالية عديدة تستخدم التنسيق المتعارف عليه " +"محلياً. لذا، كثيرًا ما يُضبط تنسيق التواريخ بملفات QIF خارج الولايات المتحدة" +" الأمريكية ليكون بنظام البدء باليوم (يوم/شهر/سنة)." + +#. module: odex25_account_bank_statement_import_qif +#: code:addons/odex25_account_bank_statement_import_qif/wizard/odex25_account_bank_statement_import_qif.py:0 +#, python-format +msgid "Could not decipher the QIF file." +msgstr "لم يمكن فهم محتويات ملف QIF." + +#. module: odex25_account_bank_statement_import_qif +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_qif.field_odex25_account_bank_statement_import__qif_date_format +msgid "Dates format" +msgstr "تنسيق التواريخ" + +#. module: odex25_account_bank_statement_import_qif +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_qif.field_odex25_account_bank_statement_import__qif_decimal_point +msgid "Decimal Separator" +msgstr "فاصل الخانات العشرية" + +#. module: odex25_account_bank_statement_import_qif +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_qif.field_odex25_account_bank_statement_import__display_name +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_qif.field_account_journal__display_name +msgid "Display Name" +msgstr "الاسم المعروض" + +#. module: odex25_account_bank_statement_import_qif +#: model:ir.model.fields,help:odex25_account_bank_statement_import_qif.field_odex25_account_bank_statement_import__qif_decimal_point +msgid "Field used to avoid conversion issues." +msgstr "" + +#. module: odex25_account_bank_statement_import_qif +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_qif.field_odex25_account_bank_statement_import__hide_journal_field +msgid "Hide the journal field in the view" +msgstr "إخفاء حقل دفتر اليومية من الواجهة" + +#. module: odex25_account_bank_statement_import_qif +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_qif.field_odex25_account_bank_statement_import__id +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_qif.field_account_journal__id +msgid "ID" +msgstr "المُعرف" + +#. module: odex25_account_bank_statement_import_qif +#: model:ir.model,name:odex25_account_bank_statement_import_qif.model_odex25_account_bank_statement_import +msgid "Import Bank Statement" +msgstr "استيراد كشف حساب بنكي" + +#. module: odex25_account_bank_statement_import_qif +#: model_terms:ir.ui.view,arch_db:odex25_account_bank_statement_import_qif.odex25_account_bank_statement_import_view_inherited +msgid "" +"In order to avoid conversion errors, please specify the decimal separator " +"you wish to use." +msgstr "" + +#. module: odex25_account_bank_statement_import_qif +#: model:ir.model,name:odex25_account_bank_statement_import_qif.model_account_journal +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_qif.field_odex25_account_bank_statement_import__journal_id +msgid "Journal" +msgstr "دفتر اليومية" + +#. module: odex25_account_bank_statement_import_qif +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_qif.field_odex25_account_bank_statement_import____last_update +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_qif.field_account_journal____last_update +msgid "Last Modified on" +msgstr "آخر تعديل في" + +#. module: odex25_account_bank_statement_import_qif +#: model_terms:ir.ui.view,arch_db:odex25_account_bank_statement_import_qif.odex25_account_bank_statement_import_qif +msgid "Quicken Interchange Format (QIF)" +msgstr "" + +#. module: odex25_account_bank_statement_import_qif +#: model:ir.model.fields,field_description:odex25_account_bank_statement_import_qif.field_odex25_account_bank_statement_import__show_qif_date_format +msgid "Show Qif Date Format" +msgstr "إظهار تنسيق تواريخ QIF" + +#. module: odex25_account_bank_statement_import_qif +#: model:ir.model.fields,help:odex25_account_bank_statement_import_qif.field_odex25_account_bank_statement_import__show_qif_date_format +msgid "" +"Technical field used to ask the user for the date format used in the QIF " +"file, as this format is ambiguous." +msgstr "" +"حقل تقني يُستخدم لسؤال المستخدم عن تنسيق التاريخ المستخدم فى ملفات QIF، لأن " +"هذه الصيغة مبهمة." + +#. module: odex25_account_bank_statement_import_qif +#: model_terms:ir.ui.view,arch_db:odex25_account_bank_statement_import_qif.odex25_account_bank_statement_import_view_inherited +msgid "" +"The QIF format is ambiguous about dates: please check with your financial " +"institution whether they format it with month or day first.
    " +msgstr "" +"صيغة QIF مبهمة فيما يتعلق بالتواريخ: برجاء مراجعة مؤسستك المالية لمعرفة ما " +"إن كان تنسيق التواريخ يبدأ بالشهر أم باليوم.
    " + +#. module: odex25_account_bank_statement_import_qif +#: code:addons/odex25_account_bank_statement_import_qif/wizard/odex25_account_bank_statement_import_qif.py:0 +#, python-format +msgid "This file is either not a bank statement or is not correctly formed." +msgstr "إما أن هذا الملف ليس كشف حساب أو لم يتم تكوينه بشكل صحيح." + +#. module: odex25_account_bank_statement_import_qif +#: model_terms:ir.ui.view,arch_db:odex25_account_bank_statement_import_qif.odex25_account_bank_statement_import_view_inherited +msgid "Upload" +msgstr "رفع" + +#. module: odex25_account_bank_statement_import_qif +#: model:ir.model.fields.selection,name:odex25_account_bank_statement_import_qif.selection__odex25_account_bank_statement_import__qif_date_format__day_first +msgid "dd/mm/yy" +msgstr "يوم/شهر/سنة" + +#. module: odex25_account_bank_statement_import_qif +#: model:ir.model.fields.selection,name:odex25_account_bank_statement_import_qif.selection__odex25_account_bank_statement_import__qif_date_format__month_first +msgid "mm/dd/yy" +msgstr "شهر/يوم/ سنة" diff --git a/odex25_accounting/odex25_account_bank_statement_import_qif/models/__init__.py b/odex25_accounting/odex25_account_bank_statement_import_qif/models/__init__.py new file mode 100644 index 000000000..0c5073d1a --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_qif/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + + +from . import account_journal \ No newline at end of file diff --git a/odex25_accounting/odex25_account_bank_statement_import_qif/models/account_journal.py b/odex25_accounting/odex25_account_bank_statement_import_qif/models/account_journal.py new file mode 100644 index 000000000..e252ac089 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_qif/models/account_journal.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- + + +from odoo import models + + +class AccountJournal(models.Model): + _inherit = 'account.journal' + + def _get_bank_statements_available_import_formats(self): + rslt = super(AccountJournal, self)._get_bank_statements_available_import_formats() + rslt.append('QIF') + return rslt diff --git a/odex25_accounting/odex25_account_bank_statement_import_qif/static/description/icon.png b/odex25_accounting/odex25_account_bank_statement_import_qif/static/description/icon.png new file mode 100644 index 000000000..d58121472 Binary files /dev/null and b/odex25_accounting/odex25_account_bank_statement_import_qif/static/description/icon.png differ diff --git a/odex25_accounting/odex25_account_bank_statement_import_qif/static/qif/test_qif.qif b/odex25_accounting/odex25_account_bank_statement_import_qif/static/qif/test_qif.qif new file mode 100644 index 000000000..5388e6dae --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_qif/static/qif/test_qif.qif @@ -0,0 +1,21 @@ +!Type:Bank +D8/12/13 +T-1,000.00 +PDelta PC +^ +D8/15/13 +T-75.46 +PWalts Drugs +^ +D3/3/13 +T-379.00 +PEpic Technologies +^ +D3/4/13 +T-20.28 +PYOUR LOCAL SUPERMARKET +^ +D3/3/13 +T-421.35 +PSPRINGFIELD WATER UTILITY +^ diff --git a/odex25_accounting/odex25_account_bank_statement_import_qif/tests/__init__.py b/odex25_accounting/odex25_account_bank_statement_import_qif/tests/__init__.py new file mode 100644 index 000000000..a1f586b56 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_qif/tests/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + + +from . import test_import_bank_statement diff --git a/odex25_accounting/odex25_account_bank_statement_import_qif/tests/test_import_bank_statement.py b/odex25_accounting/odex25_account_bank_statement_import_qif/tests/test_import_bank_statement.py new file mode 100644 index 000000000..4bf24e6b7 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_qif/tests/test_import_bank_statement.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- + +from odoo.addons.account.tests.common import AccountTestInvoicingCommon +from odoo.tests import tagged +from odoo.modules.module import get_module_resource + +import base64 + + +@tagged('post_install', '-at_install') +class TestAccountBankStatementImportQIF(AccountTestInvoicingCommon): + + def test_qif_file_import(self): + bank_journal = self.env['account.journal'].create({ + 'name': 'bank QIF', + 'code': 'BNK67', + 'type': 'bank', + 'bank_acc_number': '123456', + 'currency_id': self.env.ref('base.USD').id, + }) + + qif_file_path = get_module_resource('odex25_account_bank_statement_import_qif', 'static/qif', 'test_qif.qif') + qif_file = base64.b64encode(open(qif_file_path, 'rb').read()) + + self.env['account.bank.statement.import']\ + .with_context(journal_id=bank_journal.id)\ + .create({'attachment_ids': [(0, 0, {'name': 'test file', 'datas': qif_file})]})\ + .import_file() + + imported_statement = self.env['account.bank.statement'].search([('company_id', '=', self.env.company.id)]) + self.assertRecordValues(imported_statement, [{ + 'balance_start': 0.0, + 'balance_end_real': -1896.09, + }]) + self.assertRecordValues(imported_statement.line_ids.sorted('payment_ref'), [ + {'amount': -1000.00, 'payment_ref': 'Delta PC'}, + {'amount': -379.00, 'payment_ref': 'Epic Technologies'}, + {'amount': -421.35, 'payment_ref': 'SPRINGFIELD WATER UTILITY'}, + {'amount': -75.46, 'payment_ref': 'Walts Drugs'}, + {'amount': -20.28, 'payment_ref': 'YOUR LOCAL SUPERMARKET'}, + ]) diff --git a/odex25_accounting/odex25_account_bank_statement_import_qif/wizard/__init__.py b/odex25_accounting/odex25_account_bank_statement_import_qif/wizard/__init__.py new file mode 100644 index 000000000..f435e270f --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_qif/wizard/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + + +from . import odex25_account_bank_statement_import_qif diff --git a/odex25_accounting/odex25_account_bank_statement_import_qif/wizard/odex25_account_bank_statement_import_qif.py b/odex25_accounting/odex25_account_bank_statement_import_qif/wizard/odex25_account_bank_statement_import_qif.py new file mode 100644 index 000000000..73788102f --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_qif/wizard/odex25_account_bank_statement_import_qif.py @@ -0,0 +1,119 @@ +# -*- coding: utf-8 -*- + + +import base64 +import io +import logging + +import dateutil.parser + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError + + +logger = logging.getLogger(__name__) +class AccountBankStatementImport(models.TransientModel): + _inherit = "account.bank.statement.import" + + def _get_hide_journal_field(self): + return self.env.context and 'journal_id' in self.env.context or False + + journal_id = fields.Many2one('account.journal', string='Journal', + help="Accounting journal related to the bank statement you're importing. It has to be manually chosen " + "for statement formats which doesn't allow automatic journal detection (QIF for example).") + hide_journal_field = fields.Boolean(string='Hide the journal field in the view', default=_get_hide_journal_field) + qif_decimal_point = fields.Char(string="Decimal Separator", default='.', + help="Field used to avoid conversion issues.") + + show_qif_date_format = fields.Boolean(default=False, store=False, + help="Technical field used to ask the user for the date format used in the QIF file, as this format is ambiguous.") + qif_date_format = fields.Selection([('month_first', "mm/dd/yy"), ('day_first', "dd/mm/yy")], string='Dates format', required=True, store=False, + help="Although the historic QIF date format is month-first (mm/dd/yy), many financial institutions use the local format." + "Therefore, it is frequent outside the US to have QIF date formated day-first (dd/mm/yy).") + + @api.onchange('attachment_ids') + def _onchange_data_file(self): + file_contents = self.attachment_ids.mapped('datas') + self.show_qif_date_format = any(self._check_qif(base64.b64decode(content)) for content in file_contents) + + def _find_additional_data(self, *args): + """ As .QIF format does not allow us to detect the journal, we need to let the user choose it. + We set it in context in the same way it's done when calling the import action from a journal. + """ + if self.journal_id: + self.env.context = dict(self.env.context, journal_id=self.journal_id.id) + return super(AccountBankStatementImport, self)._find_additional_data(*args) + + def _check_qif(self, data_file): + return data_file.strip().startswith(b'!Type:') + + def _parse_file(self, data_file): + if not self._check_qif(data_file): + return super(AccountBankStatementImport, self)._parse_file(data_file) + + data_list = [ + line.rstrip(b'\r\n') + for line in io.BytesIO(data_file) + ] + try: + header = data_list[0].strip().split(b':')[1] + except: + raise UserError(_('Could not decipher the QIF file.')) + + transactions = [] + vals_line = {'payment_ref': []} + total = 0.0 + # Identified header types of the QIF format that we support. + # Other types might need to be added. Here are the possible values + # according to the QIF spec: Cash, Bank, CCard, Invst, Oth A, Oth L, Invoice. + if header in [b'Bank', b'Cash', b'CCard']: + vals_bank_statement = {} + for line in data_list: + line = line.strip() + if not line: + continue + vals_line['sequence'] = len(transactions) + 1 + data = line[1:] + if line[:1] == DATE_OF_TRANSACTION: + dayfirst = self.env.context.get('qif_date_format') == 'day_first' + vals_line['date'] = dateutil.parser.parse(data, fuzzy=True, dayfirst=dayfirst).date() + elif line[:1] == TOTAL_AMOUNT: + amount = float(data.replace(b',', b'.' if self.qif_decimal_point == ',' else b'')) + total += amount + vals_line['amount'] = amount + elif line[:1] == CHECK_NUMBER: + vals_line['ref'] = data.decode('utf-8') + elif line[:1] == PAYEE: + name = data.decode('utf-8') + vals_line['payment_ref'].append(name) + # Since QIF doesn't provide account numbers, we'll have to find res.partner and res.partner.bank here + # (normal behavious is to provide 'account_number', which the generic module uses to find partner/bank) + partner_bank = self.env['res.partner.bank'].search([('partner_id.name', '=', name)], limit=1) + if partner_bank: + vals_line['partner_bank_id'] = partner_bank.id + vals_line['partner_id'] = partner_bank.partner_id.id + elif line[:1] == MEMO: + vals_line['payment_ref'].append(data.decode('utf-8')) + elif line[:1] == END_OF_ITEM: + if vals_line['payment_ref']: + vals_line['payment_ref'] = u': '.join(vals_line['payment_ref']) + else: + del vals_line['payment_ref'] + transactions.append(vals_line) + vals_line = {'payment_ref': []} + elif line[:1] == b'\n': + transactions = [] + else: + raise UserError(_('This file is either not a bank statement or is not correctly formed.')) + + vals_bank_statement.update({ + 'balance_end_real': total, + 'transactions': transactions + }) + return None, None, [vals_bank_statement] +DATE_OF_TRANSACTION = b'D' +TOTAL_AMOUNT = b'T' +CHECK_NUMBER = b'N' +PAYEE = b'P' +MEMO = b'M' +END_OF_ITEM = b'^' diff --git a/odex25_accounting/odex25_account_bank_statement_import_qif/wizard/odex25_account_bank_statement_import_views.xml b/odex25_accounting/odex25_account_bank_statement_import_qif/wizard/odex25_account_bank_statement_import_views.xml new file mode 100644 index 000000000..fbb86e289 --- /dev/null +++ b/odex25_accounting/odex25_account_bank_statement_import_qif/wizard/odex25_account_bank_statement_import_views.xml @@ -0,0 +1,45 @@ + + + + Upload Bank Statements QIF + account.bank.statement.import + + + +
  • Quicken Interchange Format (QIF)
  • +
    +
    +
    + + + Upload Bank Statements Inherited + account.bank.statement.import + + + + + + + + + + +

    + The QIF format is ambiguous about dates: please check with your financial institution whether they format it with month or day first.
    +

    + +
    + +

    + In order to avoid conversion errors, please specify the decimal separator you wish to use. +

    + +
    +
    + +