diff --git a/odex30_base/branch/LICENSE b/odex30_base/branch/LICENSE new file mode 100644 index 0000000..de7bcc6 --- /dev/null +++ b/odex30_base/branch/LICENSE @@ -0,0 +1,28 @@ +Odoo Proprietary License v1.0 + +This software and associated files (the "Software") may only be used (executed, +modified, executed after modifications) if you have purchased a valid license +from the authors, typically via Odoo Apps, or if you have received a written +agreement from the authors of the Software (see the COPYRIGHT file). + +You may develop Odoo modules that use the Software as a library (typically +by depending on it, importing it and using its resources), but without copying +any source code or material from the Software. You may distribute those +modules under the license of your choice, provided that this license is +compatible with the terms of the Odoo Proprietary License (For example: +LGPL, MIT, or proprietary licenses similar to this one). + +It is forbidden to publish, distribute, sublicense, or sell copies of the Software +or modified copies of the Software. + +The above copyright notice and this permission notice must be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + diff --git a/odex30_base/branch/README.txt b/odex30_base/branch/README.txt new file mode 100644 index 0000000..d6336ee --- /dev/null +++ b/odex30_base/branch/README.txt @@ -0,0 +1,44 @@ + +Version 14.0.0.1 : (23/10/20) + - Update _assign_picking() and _create_account_move_line() methods as per base. + +14.0.0.3==> added abstract_web_client js according to v14. + +=> 14.0.0.4 : Add language translate with index. + + +date 03/05/21 +version 14.0.0.5 +issue solve:- + - invoice and bill genenrated in sinlge click + +=> 14.0.0.9 : Add French, Spanish , Arabic and Dutch translation in module also improved an index. + + +date 02/09/21 +version 14.0.1.0 +issue solve:- + - account payment register wizard not show branch field. + +date 09/09/21 +version 14.0.2.0 +issue solve:- + - show branch field in sale , purchase ,invoice bill and payment tree view + +date 13/09/21 +version 14.0.3.0 +issue solve:- +1. From demo user->In sale rights, I give User: Own Documents Only ->but it shows the sale order of all the users(when I give branch in sale order) + +2. From demo user, ->change branch from header ->in pos, when I open shop it generates traceback + +3. from demo user->in Invoice -> It shows all the invoices of all the branches. + +date 27/09/21 +version 14.0.4.0 +issue solve:- +1.) . Sales -> Quotation / Orders -> On changing Branch from dropdown header it shows older branch records until refresh the page. Not refreshing records with changing branch. + + +14.0.4.1 (1-10-21) : Pass branch in account move correct, two view name same for different object changed it and fixed. + diff --git a/odex30_base/branch/__init__.py b/odex30_base/branch/__init__.py new file mode 100644 index 0000000..129043b --- /dev/null +++ b/odex30_base/branch/__init__.py @@ -0,0 +1,9 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from . import models +from . import reports +from . import wizard +from . import controllers +from .hooks import post_init_hook + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/odex30_base/branch/__manifest__.py b/odex30_base/branch/__manifest__.py new file mode 100644 index 0000000..913289e --- /dev/null +++ b/odex30_base/branch/__manifest__.py @@ -0,0 +1,129 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +{ + 'name': 'Multiple Branch Unit Operation Setup for All Applications Odoo', + 'version': '18.0.1.0.0', + 'category': 'Sales', + 'summary': 'Multiple Branch Management Multi Branch app Multiple Unit multiple Operating unit sales branch Sales Purchase branch Invoicing branch billing Voucher branch warehouse branch Payment branch Accounting Reports for single company Multi Branches multi company', + "description": """ + Multiple Unit operation management for single company Multiple Branch management for single company + multiple operation for single company branching company in odoo multiple store multiple company in odoo + Branch for POS Branch for Sales Branch for Purchase Branch for all Branch for Accounting Branch for invoicing Branch for Payment order Branch for point of sales Branch for voucher + Branch for All Accounting reports Branch Accounting filter Branch for warehouse branch for sale stock branch for location + Unit for POS Unit for Sales Unit for Purchase Unit for all Unit for Accounting Unit for invoicing Unit for Payment order Unit for point of sales Unit for voucher Unit + unit All Accounting reports Unit Accounting filter branch unit for warehouse branch unit for sale stock branch unit for location + Unit Operation for POS Unit Operation for Sales Unit operation for Purchase Unit operation for all Unit operation for Accounting Unit Operation for invoicing Unit operation for Payment order Unit operation for point of sales Unit operation for voucher Unit operation for All Accounting reports Unit operation Accounting filter. + Branch Operation for POS Branch Operation for Sales Branch operation for Purchase Branch operation for all Branch operation for Accounting Branch Operation for invoicing Branch operation for Payment order Branch operation for point of sales Branch operation for voucher Branch operation for All Accounting reports Branch operation Accounting filter. + Odoo pos multi branch POS odoo point of sale multi branch point of sales + odoo point of sales multi branch on POS + Odoo pos multiple branch POS odoo point of sale multiple branch point of sales + odoo point of sales multiple branch on POS + Odoo pos multiple-branch POS odoo point of sale multiple-branch point of sales + odoo point of sales multiple-branch on POS + odoo Multiple Unit operation management for single company Multiple Branch management for single company + odoo multiple operation for single company. branching company in odoo multiple store multiple company in odoo + odoo Branch for POS Branch for Sales Branch for Purchase Branch for all Branch for Accounting Branch for invoicing Branch for Payment order Branch for point of sales Branch for voucher + odoo Branch for All Accounting reports Branch Accounting filter Branch for warehouse branch for sale stock branch for location + odoo Unit for POS Unit for Sales Unit for Purchase Unit for all Unit for Accounting Unit for invoicing Unit for Payment order + odoo Unit for point of sales Unit for voucher Unit for All Accounting reports Unit Accounting filter + odoo branch unit for warehouse branch unit for sale stock branch unit for location + odoo Unit Operation for POS Unit Operation for Sales Unit operation for Purchase Unit operation for all Unit operation for Accounting + odoo Unit Operation for invoicing Unit operation for Payment order Unit operation for point of sales Unit operation for voucher Unit operation for All Accounting reports + odoo Unit operation Accounting filter Branch Operation for POS Branch Operation for Sales + odoo Branch operation for Purchase Branch operation for all Branch operation for Accounting Branch Operation for invoicing + odoo Branch operation for Payment order Branch operation for point of sales Branch operation for voucher Branch operation for All Accounting reports Branch operation Accounting filter. + odoo branch helpdesk and support branch support and helpdesk + odoo helpdesk branch helpdesk unit helpdek multiple unit helpdesk operation unit + odoo branch crm odoo crm branch crm operating unit crm unit operation management crm multiple unit operating unit crm + odoo branch Subscription branch contract Subscription branch management + odoo contract branch management operating unit Subscription operating unit contract + odoo Subscription unit management contract unit management Subscription operating unit management + odoo contract operating unit management operating unit for company multi branch management + odoo multi branch application multi operation unit application multi branch odoo multi branch + odoo all in one multi branch application multi branch unit operation multi unit operation branch management + odoo multi branches management application multi operation management operating Unit for POS operating Unit for Sales + odoo operating Units for Purchase operating Unit for all operating Unit for Accounting operating Unit for invoicing + odoo operating Unit for Payment order operating Unit for point of sales operating Unit for voucher operating Unit for All Accounting reports operating Unit Accounting filter. + odoo Operating unit for picking operating unit for warehouse operating unit for sale stock operating unit for location +odoo operating-Unit Operation for POS operating-Unit Operation for Sales operating-Unit operation for Purchase operating-Unit operation for all +odoo operating-Unit operation for Accounting operating-Unit Operation for invoicing operating-Unit operation for Payment order operating-Unit operation for point of sales +odoo operating-Unit operation for voucher operating-Unit operation for All Accounting reports operating-Unit operation Accounting filter. +odoo multi branches management odoo branches management odoo multiple branches management on odoo branchs mananegement +odoo many branches for single company odoo + + branch helpdesk and support + branch support and helpdesk + helpdesk branch + helpdesk unit + helpdek multiple unit + helpdesk operation unit + branch crm + MultiBranch + multi company + crm branch + crm operating unit + crm unit operation management + crm multiple unit + operating unit crm + branch Subscription + branch contract + Subscription branch management + contract branch management + operating unit Subscription + operating unit contract + Subscription unit management + contract unit management + Subscription operating unit management + contract operating unit management + + operating unit for company. + multi branch management + multi branch application + multi operation unit application multi branch odoo multi branch + all in one multi branch application multi branch unit operation multi unit operation branch management + odoo multi branches management application multi operation management + +operating Unit for POS,operating Unit for Sales,operating Unit for Purchase,operating Unit for all,operating Unit for Accounting,operating Unit for invoicing,operating Unit for Payment order,operating Unit for point of sales,operating Unit for voucher,operating Unit for All Accounting reports,operating Unit Accounting filter. Operating unit for picking, operating unit for warehouse, operating unit for sale stock, operating unit for location +operating-Unit Operation for POS,operating-Unit Operation for Sales,operating-Unit operation for Purchase,operating-Unit operation for all, operating-Unit operation for Accounting,operating-Unit Operation for invoicing,operating-Unit operation for Payment order,operating-Unit operation for point of sales,operating-Unit operation for voucher,operating-Unit operation for All Accounting reports,operating-Unit operation Accounting filter. + """, + 'author': 'BrowseInfo', + 'website': 'https://www.browseinfo.in', + "price": 149.00, + "currency": 'EUR', + 'depends': ['base', 'sale_management', 'purchase', 'stock', 'account', 'purchase_stock','web'], + 'data': [ + 'security/branch_security.xml', + 'security/multi_branch.xml', + 'security/ir.model.access.csv', + 'views/res_branch_view.xml', + 'views/inherited_res_users.xml', + 'views/inherited_sale_order.xml', + 'views/inherited_stock_picking.xml', + 'views/inherited_stock_move.xml', + 'views/inherited_account_invoice.xml', + 'views/inherited_purchase_order.xml', + 'views/inherited_stock_warehouse.xml', + 'views/inherited_stock_location.xml', + 'views/inherited_account_bank_statement.xml', + 'wizard/inherited_account_payment.xml', + 'views/inherited_stock_inventory.xml', + 'views/inherited_product.xml', + 'views/inherited_partner.xml', + 'views/branch_template.xml', + ], + 'assets': { + 'web.assets_backend': [ + 'branch/static/src/js/session.js', + 'branch/static/src/js/abstract_web_client.js', + 'branch/static/src/js/default_branch.js', + 'branch/static/src/xml/branch.xml', + ], + }, + 'installable': True, + 'auto_install': False, + 'live_test_url':'https://youtu.be/hi1b8kH5Z94', + "images":['static/description/Banner.png'], + 'post_init_hook': 'post_init_hook', +} + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/odex30_base/branch/controllers/__init__.py b/odex30_base/branch/controllers/__init__.py new file mode 100644 index 0000000..5824557 --- /dev/null +++ b/odex30_base/branch/controllers/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from . import main + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file diff --git a/odex30_base/branch/controllers/main.py b/odex30_base/branch/controllers/main.py new file mode 100644 index 0000000..97f169e --- /dev/null +++ b/odex30_base/branch/controllers/main.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from odoo import http, _ +from odoo.addons.portal.controllers.portal import CustomerPortal, pager as portal_pager +from odoo.http import request + +class SetBranch(http.Controller): + + @http.route('/set_brnach', type='json', auth="public", methods=['POST'], website=True) + def custom_hours(self, BranchID, **post): + user_id = request.env['res.users'].sudo().search([('id','=',request.env.user.id)]) + user_id.branch_id = BranchID + return + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file diff --git a/odex30_base/branch/hooks.py b/odex30_base/branch/hooks.py new file mode 100644 index 0000000..d26afc8 --- /dev/null +++ b/odex30_base/branch/hooks.py @@ -0,0 +1,15 @@ +# -*- encoding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import SUPERUSER_ID +from odoo import api + + +def post_init_hook(cr, registry): + """ + website menu hide + """ + env = api.Environment(cr, SUPERUSER_ID, {}) + cr.execute(""" + update ir_model_data set noupdate=False where + model ='ir.rule' """) diff --git a/odex30_base/branch/i18n/ar_001.po b/odex30_base/branch/i18n/ar_001.po new file mode 100644 index 0000000..d48fd10 --- /dev/null +++ b/odex30_base/branch/i18n/ar_001.po @@ -0,0 +1,273 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * branch +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-02-08 13:27+0000\n" +"PO-Revision-Date: 2021-02-08 13:27+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: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__address +msgid "Address" +msgstr "عنوان" + +#. module: branch +#: code:addons/branch/models/inherited_account_bank_statement.py:0 +#, python-format +msgid "All the account entries lines must be processed in order to close the statement." +msgstr "يجب معالجة جميع سطور إدخالات الحساب لإغلاق البيان." + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_users__branch_ids +msgid "Allowed Branch" +msgstr "الفرع المسموح به" + +#. module: branch +#: model:ir.model,name:branch.model_account_bank_statement +msgid "Bank Statement" +msgstr "كشف حساب بنكى" + +#. module: branch +#: model:ir.model,name:branch.model_account_bank_statement_line +msgid "Bank Statement Line" +msgstr "خط كشف الحساب المصرفي" + +#. module: branch +#: model:ir.actions.act_window,name:branch.branch_action_res_branch +#: model:ir.model,name:branch.model_res_branch +#: model:ir.model.fields,field_description:branch.field_account_bank_statement__branch_id +#: model:ir.model.fields,field_description:branch.field_account_bank_statement_line__branch_id +#: model:ir.model.fields,field_description:branch.field_account_invoice_report__branch_id +#: model:ir.model.fields,field_description:branch.field_account_move__branch_id +#: model:ir.model.fields,field_description:branch.field_account_move_line__branch_id +#: model:ir.model.fields,field_description:branch.field_account_payment__branch_id +#: model:ir.model.fields,field_description:branch.field_product_product__branch_id +#: model:ir.model.fields,field_description:branch.field_product_template__branch_id +#: model:ir.model.fields,field_description:branch.field_purchase_order__branch_id +#: model:ir.model.fields,field_description:branch.field_purchase_order_line__branch_id +#: model:ir.model.fields,field_description:branch.field_purchase_report__branch_id +#: model:ir.model.fields,field_description:branch.field_res_partner__branch_id +#: model:ir.model.fields,field_description:branch.field_res_users__branch_id +#: model:ir.model.fields,field_description:branch.field_sale_order__branch_id +#: model:ir.model.fields,field_description:branch.field_sale_report__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_inventory__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_location__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_move__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_picking__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_picking_type__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_warehouse__branch_id +#: model:ir.module.category,name:branch.module_branch_management +#: model:ir.ui.menu,name:branch.branch_menu_res_branch +#: model_terms:ir.ui.view,arch_db:branch.branch_res_branch_view_form +#: model_terms:ir.ui.view,arch_db:branch.branch_res_branch_view_tree +#: model_terms:ir.ui.view,arch_db:branch.view_move_line_order_filter_inherit_branch11 +#: model_terms:ir.ui.view,arch_db:branch.view_order_form_inherit_branch +#: model_terms:ir.ui.view,arch_db:branch.view_purchase_order_filter_inherit_branch +#: model_terms:ir.ui.view,arch_db:branch.view_sales_order_filter_inherit_branch +msgid "Branch" +msgstr "فرع شجرة" + +#. module: branch +#: model_terms:ir.actions.act_window,help:branch.branch_action_res_branch +msgid "Click here to create a new branch." +msgstr "انقر هنا لإنشاء فرع جديد." + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__company_id +msgid "Company" +msgstr "شركة" + +#. module: branch +#: code:addons/branch/models/inherited_stock_location.py:0 +#, python-format +msgid "Configuration error You must select same branch on a location as assigned on a warehouse configuration." +msgstr "خطأ في التكوين يجب تحديد نفس الفرع في الموقع كما تم تعيينه في تكوين المستودع." + +#. module: branch +#: model:ir.model,name:branch.model_res_partner +msgid "Contact" +msgstr "اتصل" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__create_uid +msgid "Created by" +msgstr "انشأ من قبل" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__create_date +msgid "Created on" +msgstr "تم إنشاؤها على" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__display_name +msgid "Display Name" +msgstr "اسم العرض" + +#. module: branch +#. openerp-web +#: code:addons/branch/static/src/xml/branch.xml:0 +#, python-format +msgid "Dropdown menu" +msgstr "القائمة المنسدلة" + +#. module: branch +#: model:ir.model,name:branch.model_ir_http +msgid "HTTP Routing" +msgstr "" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__id +msgid "ID" +msgstr "" + +#. module: branch +#: model:ir.model,name:branch.model_stock_inventory +msgid "Inventory" +msgstr "المخزون" + +#. module: branch +#: model:ir.model,name:branch.model_stock_location +msgid "Inventory Locations" +msgstr "مواقع الجرد" + +#. module: branch +#: model:ir.model,name:branch.model_account_invoice_report +msgid "Invoices Statistics" +msgstr "إحصائيات الفواتير" + +#. module: branch +#: model:ir.model,name:branch.model_account_move +msgid "Journal Entries" +msgstr "إدخالات دفتر اليومية" + +#. module: branch +#: model:ir.model,name:branch.model_account_move_line +msgid "Journal Item" +msgstr "عنصر المجلة" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch____last_update +msgid "Last Modified on" +msgstr "تاريخ آخر تعديل" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__write_uid +msgid "Last Updated by" +msgstr "آخر تحديث بواسطة" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__write_date +msgid "Last Updated on" +msgstr "آخر تحديث في" + +#. module: branch +#: model:res.groups,name:branch.group_branch_user_manager +msgid "Manager" +msgstr "مدير" + +#. module: branch +#: model:res.groups,name:branch.group_multi_branch +msgid "Multi Branches" +msgstr "متعدد الفروع" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__name +msgid "Name" +msgstr "اسم" + +#. module: branch +#: model:ir.model,name:branch.model_account_payment +msgid "Payments" +msgstr "المدفوعات" + +#. module: branch +#: model:ir.model,name:branch.model_stock_picking_type +msgid "Picking Type" +msgstr "نوع الانتقاء" + +#. module: branch +#: model:ir.model,name:branch.model_product_template +msgid "Product Template" +msgstr "نموذج المنتج" + +#. module: branch +#: model:ir.model,name:branch.model_purchase_order +msgid "Purchase Order" +msgstr "أمر شراء" + +#. module: branch +#: model:ir.model,name:branch.model_purchase_order_line +msgid "Purchase Order Line" +msgstr "خط طلب الشراء" + +#. module: branch +#: model:ir.model,name:branch.model_purchase_report +msgid "Purchase Report" +msgstr "تقرير الشراء" + +#. module: branch +#: model:ir.model,name:branch.model_sale_advance_payment_inv +msgid "Sales Advance Payment Invoice" +msgstr "فاتورة دفع مقدم المبيعات" + +#. module: branch +#: model:ir.model,name:branch.model_sale_report +msgid "Sales Analysis Report" +msgstr "تقرير تحليل المبيعات" + +#. module: branch +#: model:ir.model,name:branch.model_sale_order +msgid "Sales Order" +msgstr "طلب المبيعات" + +#. module: branch +#: code:addons/branch/models/inherited_account_bank_statement.py:0 +#, python-format +msgid "Statement %s confirmed, journal items were created." +msgstr "" + +#. module: branch +#: model:ir.model,name:branch.model_stock_move +msgid "Stock Move" +msgstr "نقل الأسهم" + +#. module: branch +#. openerp-web +#: code:addons/branch/static/src/xml/branch.xml:0 +#, python-format +msgid "Switch to this branch" +msgstr "قم بالتبديل إلى هذا الفرع" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__telephone +msgid "Telephone No" +msgstr "الهاتف لا" + +#. module: branch +#: model:ir.model,name:branch.model_stock_picking +msgid "Transfer" +msgstr "نقل" + +#. module: branch +#: model:res.groups,name:branch.group_branch_user +msgid "User" +msgstr "المستعمل" + +#. module: branch +#: model:ir.model,name:branch.model_res_users +msgid "Users" +msgstr "المستخدمين" + +#. module: branch +#: model:ir.model,name:branch.model_stock_warehouse +msgid "Warehouse" +msgstr "مستودع" diff --git a/odex30_base/branch/i18n/es.po b/odex30_base/branch/i18n/es.po new file mode 100644 index 0000000..bb9a365 --- /dev/null +++ b/odex30_base/branch/i18n/es.po @@ -0,0 +1,273 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * branch +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-02-09 05:28+0000\n" +"PO-Revision-Date: 2021-02-09 05:28+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: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__address +msgid "Address" +msgstr "Habla a" + +#. module: branch +#: code:addons/branch/models/inherited_account_bank_statement.py:0 +#, python-format +msgid "All the account entries lines must be processed in order to close the statement." +msgstr "Todas las líneas de asientos de cuenta deben procesarse para cerrar el estado de cuenta." + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_users__branch_ids +msgid "Allowed Branch" +msgstr "Rama permitida" + +#. module: branch +#: model:ir.model,name:branch.model_account_bank_statement +msgid "Bank Statement" +msgstr "Extracto de cuenta" + +#. module: branch +#: model:ir.model,name:branch.model_account_bank_statement_line +msgid "Bank Statement Line" +msgstr "Línea de extracto bancario" + +#. module: branch +#: model:ir.actions.act_window,name:branch.branch_action_res_branch +#: model:ir.model,name:branch.model_res_branch +#: model:ir.model.fields,field_description:branch.field_account_bank_statement__branch_id +#: model:ir.model.fields,field_description:branch.field_account_bank_statement_line__branch_id +#: model:ir.model.fields,field_description:branch.field_account_invoice_report__branch_id +#: model:ir.model.fields,field_description:branch.field_account_move__branch_id +#: model:ir.model.fields,field_description:branch.field_account_move_line__branch_id +#: model:ir.model.fields,field_description:branch.field_account_payment__branch_id +#: model:ir.model.fields,field_description:branch.field_product_product__branch_id +#: model:ir.model.fields,field_description:branch.field_product_template__branch_id +#: model:ir.model.fields,field_description:branch.field_purchase_order__branch_id +#: model:ir.model.fields,field_description:branch.field_purchase_order_line__branch_id +#: model:ir.model.fields,field_description:branch.field_purchase_report__branch_id +#: model:ir.model.fields,field_description:branch.field_res_partner__branch_id +#: model:ir.model.fields,field_description:branch.field_res_users__branch_id +#: model:ir.model.fields,field_description:branch.field_sale_order__branch_id +#: model:ir.model.fields,field_description:branch.field_sale_report__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_inventory__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_location__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_move__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_picking__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_picking_type__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_warehouse__branch_id +#: model:ir.module.category,name:branch.module_branch_management +#: model:ir.ui.menu,name:branch.branch_menu_res_branch +#: model_terms:ir.ui.view,arch_db:branch.branch_res_branch_view_form +#: model_terms:ir.ui.view,arch_db:branch.branch_res_branch_view_tree +#: model_terms:ir.ui.view,arch_db:branch.view_move_line_order_filter_inherit_branch11 +#: model_terms:ir.ui.view,arch_db:branch.view_order_form_inherit_branch +#: model_terms:ir.ui.view,arch_db:branch.view_purchase_order_filter_inherit_branch +#: model_terms:ir.ui.view,arch_db:branch.view_sales_order_filter_inherit_branch +msgid "Branch" +msgstr "Rama" + +#. module: branch +#: model_terms:ir.actions.act_window,help:branch.branch_action_res_branch +msgid "Click here to create a new branch." +msgstr "Haga clic aquí para crear una nueva rama." + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__company_id +msgid "Company" +msgstr "Empresa" + +#. module: branch +#: code:addons/branch/models/inherited_stock_location.py:0 +#, python-format +msgid "Configuration error You must select same branch on a location as assigned on a warehouse configuration." +msgstr "Error de configuración Debe seleccionar la misma sucursal en una ubicación asignada en una configuración de almacén." + +#. module: branch +#: model:ir.model,name:branch.model_res_partner +msgid "Contact" +msgstr "Contacto" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__create_date +msgid "Created on" +msgstr "Creado en" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__display_name +msgid "Display Name" +msgstr "Nombre para mostrar" + +#. module: branch +#. openerp-web +#: code:addons/branch/static/src/xml/branch.xml:0 +#, python-format +msgid "Dropdown menu" +msgstr "Menú desplegable" + +#. module: branch +#: model:ir.model,name:branch.model_ir_http +msgid "HTTP Routing" +msgstr "" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__id +msgid "ID" +msgstr "" + +#. module: branch +#: model:ir.model,name:branch.model_stock_inventory +msgid "Inventory" +msgstr "Inventario" + +#. module: branch +#: model:ir.model,name:branch.model_stock_location +msgid "Inventory Locations" +msgstr "Ubicaciones de inventario" + +#. module: branch +#: model:ir.model,name:branch.model_account_invoice_report +msgid "Invoices Statistics" +msgstr "Estadísticas de facturas" + +#. module: branch +#: model:ir.model,name:branch.model_account_move +msgid "Journal Entries" +msgstr "Entradas de diario" + +#. module: branch +#: model:ir.model,name:branch.model_account_move_line +msgid "Journal Item" +msgstr "Artículo de diario" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch____last_update +msgid "Last Modified on" +msgstr "Última modificación el" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__write_uid +msgid "Last Updated by" +msgstr "Actualizado por última vez por" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__write_date +msgid "Last Updated on" +msgstr "Ultima actualización en" + +#. module: branch +#: model:res.groups,name:branch.group_branch_user_manager +msgid "Manager" +msgstr "Gerente" + +#. module: branch +#: model:res.groups,name:branch.group_multi_branch +msgid "Multi Branches" +msgstr "Varias ramas" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__name +msgid "Name" +msgstr "Nombre" + +#. module: branch +#: model:ir.model,name:branch.model_account_payment +msgid "Payments" +msgstr "Pagos" + +#. module: branch +#: model:ir.model,name:branch.model_stock_picking_type +msgid "Picking Type" +msgstr "Tipo de selección" + +#. module: branch +#: model:ir.model,name:branch.model_product_template +msgid "Product Template" +msgstr "Plantilla de producto" + +#. module: branch +#: model:ir.model,name:branch.model_purchase_order +msgid "Purchase Order" +msgstr "Orden de compra" + +#. module: branch +#: model:ir.model,name:branch.model_purchase_order_line +msgid "Purchase Order Line" +msgstr "Línea de orden de compra" + +#. module: branch +#: model:ir.model,name:branch.model_purchase_report +msgid "Purchase Report" +msgstr "Informe de compra" + +#. module: branch +#: model:ir.model,name:branch.model_sale_advance_payment_inv +msgid "Sales Advance Payment Invoice" +msgstr "Factura de anticipo de ventas" + +#. module: branch +#: model:ir.model,name:branch.model_sale_report +msgid "Sales Analysis Report" +msgstr "Informe de análisis de ventas" + +#. module: branch +#: model:ir.model,name:branch.model_sale_order +msgid "Sales Order" +msgstr "Órdenes de venta" + +#. module: branch +#: code:addons/branch/models/inherited_account_bank_statement.py:0 +#, python-format +msgid "Statement confirmed, journal items were created." +msgstr "Declaración confirmada, se crearon elementos del diario." + +#. module: branch +#: model:ir.model,name:branch.model_stock_move +msgid "Stock Move" +msgstr "Movimiento de stock" + +#. module: branch +#. openerp-web +#: code:addons/branch/static/src/xml/branch.xml:0 +#, python-format +msgid "Switch to this branch" +msgstr "Cambiar a esta rama" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__telephone +msgid "Telephone No" +msgstr "Teléfono no" + +#. module: branch +#: model:ir.model,name:branch.model_stock_picking +msgid "Transfer" +msgstr "Transferir" + +#. module: branch +#: model:res.groups,name:branch.group_branch_user +msgid "User" +msgstr "Usuaria" + +#. module: branch +#: model:ir.model,name:branch.model_res_users +msgid "Users" +msgstr "Usuarias" + +#. module: branch +#: model:ir.model,name:branch.model_stock_warehouse +msgid "Warehouse" +msgstr "Almacén" diff --git a/odex30_base/branch/i18n/fr.po b/odex30_base/branch/i18n/fr.po new file mode 100644 index 0000000..8a7f308 --- /dev/null +++ b/odex30_base/branch/i18n/fr.po @@ -0,0 +1,273 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * branch +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-02-09 06:11+0000\n" +"PO-Revision-Date: 2021-02-09 06: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: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__address +msgid "Address" +msgstr "Adresse" + +#. module: branch +#: code:addons/branch/models/inherited_account_bank_statement.py:0 +#, python-format +msgid "All the account entries lines must be processed in order to close the statement." +msgstr "Toutes les lignes d'écritures de compte doivent être traitées afin de fermer le relevé." + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_users__branch_ids +msgid "Allowed Branch" +msgstr "Succursale autorisée" + +#. module: branch +#: model:ir.model,name:branch.model_account_bank_statement +msgid "Bank Statement" +msgstr "Relevé bancaire" + +#. module: branch +#: model:ir.model,name:branch.model_account_bank_statement_line +msgid "Bank Statement Line" +msgstr "Ligne de relevé bancaire" + +#. module: branch +#: model:ir.actions.act_window,name:branch.branch_action_res_branch +#: model:ir.model,name:branch.model_res_branch +#: model:ir.model.fields,field_description:branch.field_account_bank_statement__branch_id +#: model:ir.model.fields,field_description:branch.field_account_bank_statement_line__branch_id +#: model:ir.model.fields,field_description:branch.field_account_invoice_report__branch_id +#: model:ir.model.fields,field_description:branch.field_account_move__branch_id +#: model:ir.model.fields,field_description:branch.field_account_move_line__branch_id +#: model:ir.model.fields,field_description:branch.field_account_payment__branch_id +#: model:ir.model.fields,field_description:branch.field_product_product__branch_id +#: model:ir.model.fields,field_description:branch.field_product_template__branch_id +#: model:ir.model.fields,field_description:branch.field_purchase_order__branch_id +#: model:ir.model.fields,field_description:branch.field_purchase_order_line__branch_id +#: model:ir.model.fields,field_description:branch.field_purchase_report__branch_id +#: model:ir.model.fields,field_description:branch.field_res_partner__branch_id +#: model:ir.model.fields,field_description:branch.field_res_users__branch_id +#: model:ir.model.fields,field_description:branch.field_sale_order__branch_id +#: model:ir.model.fields,field_description:branch.field_sale_report__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_inventory__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_location__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_move__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_picking__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_picking_type__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_warehouse__branch_id +#: model:ir.module.category,name:branch.module_branch_management +#: model:ir.ui.menu,name:branch.branch_menu_res_branch +#: model_terms:ir.ui.view,arch_db:branch.branch_res_branch_view_form +#: model_terms:ir.ui.view,arch_db:branch.branch_res_branch_view_tree +#: model_terms:ir.ui.view,arch_db:branch.view_move_line_order_filter_inherit_branch11 +#: model_terms:ir.ui.view,arch_db:branch.view_order_form_inherit_branch +#: model_terms:ir.ui.view,arch_db:branch.view_purchase_order_filter_inherit_branch +#: model_terms:ir.ui.view,arch_db:branch.view_sales_order_filter_inherit_branch +msgid "Branch" +msgstr "Branche" + +#. module: branch +#: model_terms:ir.actions.act_window,help:branch.branch_action_res_branch +msgid "Click here to create a new branch." +msgstr "Cliquez ici pour créer une nouvelle branche." + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__company_id +msgid "Company" +msgstr "Entreprise" + +#. module: branch +#: code:addons/branch/models/inherited_stock_location.py:0 +#, python-format +msgid "Configuration error You must select same branch on a location as assigned on a warehouse configuration." +msgstr "Erreur de configuration Vous devez sélectionner la même succursale sur un emplacement comme affectée dans une configuration d'entrepôt." + +#. module: branch +#: model:ir.model,name:branch.model_res_partner +msgid "Contact" +msgstr "" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__create_uid +msgid "Created by" +msgstr "Créé par" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__create_date +msgid "Created on" +msgstr "Créé sur" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__display_name +msgid "Display Name" +msgstr "Afficher un nom" + +#. module: branch +#. openerp-web +#: code:addons/branch/static/src/xml/branch.xml:0 +#, python-format +msgid "Dropdown menu" +msgstr "Menu déroulant" + +#. module: branch +#: model:ir.model,name:branch.model_ir_http +msgid "HTTP Routing" +msgstr "" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__id +msgid "ID" +msgstr "" + +#. module: branch +#: model:ir.model,name:branch.model_stock_inventory +msgid "Inventory" +msgstr "Inventaire" + +#. module: branch +#: model:ir.model,name:branch.model_stock_location +msgid "Inventory Locations" +msgstr "" + +#. module: branch +#: model:ir.model,name:branch.model_account_invoice_report +msgid "Invoices Statistics" +msgstr "Statistiques des factures" + +#. module: branch +#: model:ir.model,name:branch.model_account_move +msgid "Journal Entries" +msgstr "Entrées de journal" + +#. module: branch +#: model:ir.model,name:branch.model_account_move_line +msgid "Journal Item" +msgstr "Article de journal" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch____last_update +msgid "Last Modified on" +msgstr "Dernière modification le" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__write_uid +msgid "Last Updated by" +msgstr "Dernière mise à jour par" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__write_date +msgid "Last Updated on" +msgstr "Dernière mise à jour le" + +#. module: branch +#: model:res.groups,name:branch.group_branch_user_manager +msgid "Manager" +msgstr "Directrice" + +#. module: branch +#: model:res.groups,name:branch.group_multi_branch +msgid "Multi Branches" +msgstr "Branches multiples" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__name +msgid "Name" +msgstr "Nom" + +#. module: branch +#: model:ir.model,name:branch.model_account_payment +msgid "Payments" +msgstr "Paiements" + +#. module: branch +#: model:ir.model,name:branch.model_stock_picking_type +msgid "Picking Type" +msgstr "Type de prélèvement" + +#. module: branch +#: model:ir.model,name:branch.model_product_template +msgid "Product Template" +msgstr "Modèle de produit" + +#. module: branch +#: model:ir.model,name:branch.model_purchase_order +msgid "Purchase Order" +msgstr "Bon de commande" + +#. module: branch +#: model:ir.model,name:branch.model_purchase_order_line +msgid "Purchase Order Line" +msgstr "Ligne de commande d'achat" + +#. module: branch +#: model:ir.model,name:branch.model_purchase_report +msgid "Purchase Report" +msgstr "Rapport d'achat" + +#. module: branch +#: model:ir.model,name:branch.model_sale_advance_payment_inv +msgid "Sales Advance Payment Invoice" +msgstr "Facture de paiement anticipé des ventes" + +#. module: branch +#: model:ir.model,name:branch.model_sale_report +msgid "Sales Analysis Report" +msgstr "Rapport d'analyse des ventes" + +#. module: branch +#: model:ir.model,name:branch.model_sale_order +msgid "Sales Order" +msgstr "Commande client" + +#. module: branch +#: code:addons/branch/models/inherited_account_bank_statement.py:0 +#, python-format +msgid "Statement confirmed, journal items were created." +msgstr "Relevé confirmé, des éléments de journal ont été créés." + +#. module: branch +#: model:ir.model,name:branch.model_stock_move +msgid "Stock Move" +msgstr "Déplacement de stock" + +#. module: branch +#. openerp-web +#: code:addons/branch/static/src/xml/branch.xml:0 +#, python-format +msgid "Switch to this branch" +msgstr "Passer à cette branche" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__telephone +msgid "Telephone No" +msgstr "N ° de téléphone" + +#. module: branch +#: model:ir.model,name:branch.model_stock_picking +msgid "Transfer" +msgstr "Transfert" + +#. module: branch +#: model:res.groups,name:branch.group_branch_user +msgid "User" +msgstr "Utilisateur" + +#. module: branch +#: model:ir.model,name:branch.model_res_users +msgid "Users" +msgstr "Utilisateurs" + +#. module: branch +#: model:ir.model,name:branch.model_stock_warehouse +msgid "Warehouse" +msgstr "Entrepôt" diff --git a/odex30_base/branch/i18n/nl.po b/odex30_base/branch/i18n/nl.po new file mode 100644 index 0000000..282af19 --- /dev/null +++ b/odex30_base/branch/i18n/nl.po @@ -0,0 +1,273 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * branch +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-02-09 06:37+0000\n" +"PO-Revision-Date: 2021-02-09 06:37+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: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__address +msgid "Address" +msgstr "Adres" + +#. module: branch +#: code:addons/branch/models/inherited_account_bank_statement.py:0 +#, python-format +msgid "All the account entries lines must be processed in order to close the statement." +msgstr "Alle regels voor rekeningboekingen moeten worden verwerkt om het overzicht af te sluiten." + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_users__branch_ids +msgid "Allowed Branch" +msgstr "Toegestane tak" + +#. module: branch +#: model:ir.model,name:branch.model_account_bank_statement +msgid "Bank Statement" +msgstr "Bankafschrift" + +#. module: branch +#: model:ir.model,name:branch.model_account_bank_statement_line +msgid "Bank Statement Line" +msgstr "Bankafschriftregel" + +#. module: branch +#: model:ir.actions.act_window,name:branch.branch_action_res_branch +#: model:ir.model,name:branch.model_res_branch +#: model:ir.model.fields,field_description:branch.field_account_bank_statement__branch_id +#: model:ir.model.fields,field_description:branch.field_account_bank_statement_line__branch_id +#: model:ir.model.fields,field_description:branch.field_account_invoice_report__branch_id +#: model:ir.model.fields,field_description:branch.field_account_move__branch_id +#: model:ir.model.fields,field_description:branch.field_account_move_line__branch_id +#: model:ir.model.fields,field_description:branch.field_account_payment__branch_id +#: model:ir.model.fields,field_description:branch.field_product_product__branch_id +#: model:ir.model.fields,field_description:branch.field_product_template__branch_id +#: model:ir.model.fields,field_description:branch.field_purchase_order__branch_id +#: model:ir.model.fields,field_description:branch.field_purchase_order_line__branch_id +#: model:ir.model.fields,field_description:branch.field_purchase_report__branch_id +#: model:ir.model.fields,field_description:branch.field_res_partner__branch_id +#: model:ir.model.fields,field_description:branch.field_res_users__branch_id +#: model:ir.model.fields,field_description:branch.field_sale_order__branch_id +#: model:ir.model.fields,field_description:branch.field_sale_report__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_inventory__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_location__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_move__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_picking__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_picking_type__branch_id +#: model:ir.model.fields,field_description:branch.field_stock_warehouse__branch_id +#: model:ir.module.category,name:branch.module_branch_management +#: model:ir.ui.menu,name:branch.branch_menu_res_branch +#: model_terms:ir.ui.view,arch_db:branch.branch_res_branch_view_form +#: model_terms:ir.ui.view,arch_db:branch.branch_res_branch_view_tree +#: model_terms:ir.ui.view,arch_db:branch.view_move_line_order_filter_inherit_branch11 +#: model_terms:ir.ui.view,arch_db:branch.view_order_form_inherit_branch +#: model_terms:ir.ui.view,arch_db:branch.view_purchase_order_filter_inherit_branch +#: model_terms:ir.ui.view,arch_db:branch.view_sales_order_filter_inherit_branch +msgid "Branch" +msgstr "Afdeling" + +#. module: branch +#: model_terms:ir.actions.act_window,help:branch.branch_action_res_branch +msgid "Click here to create a new branch." +msgstr "Klik hier om een nieuwe branch aan te maken." + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__company_id +msgid "Company" +msgstr "Bedrijf" + +#. module: branch +#: code:addons/branch/models/inherited_stock_location.py:0 +#, python-format +msgid "Configuration error You must select same branch on a location as assigned on a warehouse configuration." +msgstr "Configuratiefout U moet hetzelfde filiaal op een locatie selecteren als toegewezen aan een magazijnconfiguratie." + +#. module: branch +#: model:ir.model,name:branch.model_res_partner +msgid "Contact" +msgstr "" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__create_uid +msgid "Created by" +msgstr "Gemaakt door" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__create_date +msgid "Created on" +msgstr "Gemaakt op" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__display_name +msgid "Display Name" +msgstr "Weergavenaam" + +#. module: branch +#. openerp-web +#: code:addons/branch/static/src/xml/branch.xml:0 +#, python-format +msgid "Dropdown menu" +msgstr "" + +#. module: branch +#: model:ir.model,name:branch.model_ir_http +msgid "HTTP Routing" +msgstr "" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__id +msgid "ID" +msgstr "" + +#. module: branch +#: model:ir.model,name:branch.model_stock_inventory +msgid "Inventory" +msgstr "Voorraad" + +#. module: branch +#: model:ir.model,name:branch.model_stock_location +msgid "Inventory Locations" +msgstr "Voorraadlocaties" + +#. module: branch +#: model:ir.model,name:branch.model_account_invoice_report +msgid "Invoices Statistics" +msgstr "Facturenstatistieken" + +#. module: branch +#: model:ir.model,name:branch.model_account_move +msgid "Journal Entries" +msgstr "Journaalboekingen" + +#. module: branch +#: model:ir.model,name:branch.model_account_move_line +msgid "Journal Item" +msgstr "Dagboekitem" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch____last_update +msgid "Last Modified on" +msgstr "Laatst gewijzigd op" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__write_uid +msgid "Last Updated by" +msgstr "Laatst bijgewerkt door" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__write_date +msgid "Last Updated on" +msgstr "Laatst geupdate op" + +#. module: branch +#: model:res.groups,name:branch.group_branch_user_manager +msgid "Manager" +msgstr "" + +#. module: branch +#: model:res.groups,name:branch.group_multi_branch +msgid "Multi Branches" +msgstr "Meerdere takken" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__name +msgid "Name" +msgstr "Naam" + +#. module: branch +#: model:ir.model,name:branch.model_account_payment +msgid "Payments" +msgstr "Betalingen" + +#. module: branch +#: model:ir.model,name:branch.model_stock_picking_type +msgid "Picking Type" +msgstr "Type plukken" + +#. module: branch +#: model:ir.model,name:branch.model_product_template +msgid "Product Template" +msgstr "Product sjabloon" + +#. module: branch +#: model:ir.model,name:branch.model_purchase_order +msgid "Purchase Order" +msgstr "Bestelling" + +#. module: branch +#: model:ir.model,name:branch.model_purchase_order_line +msgid "Purchase Order Line" +msgstr "Inkooporderregel" + +#. module: branch +#: model:ir.model,name:branch.model_purchase_report +msgid "Purchase Report" +msgstr "Aankooprapport" + +#. module: branch +#: model:ir.model,name:branch.model_sale_advance_payment_inv +msgid "Sales Advance Payment Invoice" +msgstr "Verkoopvooruitbetalingsfactuur" + +#. module: branch +#: model:ir.model,name:branch.model_sale_report +msgid "Sales Analysis Report" +msgstr "Verkoopanalyserapport" + +#. module: branch +#: model:ir.model,name:branch.model_sale_order +msgid "Sales Order" +msgstr "Verkooporder" + +#. module: branch +#: code:addons/branch/models/inherited_account_bank_statement.py:0 +#, python-format +msgid "Statement confirmed, journal items were created." +msgstr "Afschrift bevestigd, journaalposten zijn gemaakt." + +#. module: branch +#: model:ir.model,name:branch.model_stock_move +msgid "Stock Move" +msgstr "Voorraad verplaatsen" + +#. module: branch +#. openerp-web +#: code:addons/branch/static/src/xml/branch.xml:0 +#, python-format +msgid "Switch to this branch" +msgstr "Schakel over naar deze tak" + +#. module: branch +#: model:ir.model.fields,field_description:branch.field_res_branch__telephone +msgid "Telephone No" +msgstr "Telefoon Nee" + +#. module: branch +#: model:ir.model,name:branch.model_stock_picking +msgid "Transfer" +msgstr "Overdracht" + +#. module: branch +#: model:res.groups,name:branch.group_branch_user +msgid "User" +msgstr "Gebruiker" + +#. module: branch +#: model:ir.model,name:branch.model_res_users +msgid "Users" +msgstr "Gebruikers" + +#. module: branch +#: model:ir.model,name:branch.model_stock_warehouse +msgid "Warehouse" +msgstr "Magazijn" diff --git a/odex30_base/branch/models/__init__.py b/odex30_base/branch/models/__init__.py new file mode 100644 index 0000000..67886b1 --- /dev/null +++ b/odex30_base/branch/models/__init__.py @@ -0,0 +1,20 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from . import branch +from . import inherited_res_users +from . import inherited_sale_order +from . import inherited_stock_move +from . import inherited_stock_picking +from . import inherited_account_move +from . import inherited_account_payment +from . import inherited_purchase_order +from . import inherited_stock_warehouse +from . import inherited_stock_location +from . import inherited_account_bank_statement +from . import inherited_account_bank_statement_line +from . import inherited_stock_inventory +from . import inherited_customer +from . import inherited_product +from . import ir_http + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/odex30_base/branch/models/branch.py b/odex30_base/branch/models/branch.py new file mode 100644 index 0000000..34e2b53 --- /dev/null +++ b/odex30_base/branch/models/branch.py @@ -0,0 +1,13 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ + + +class ResBranch(models.Model): + _name = 'res.branch' + _description = 'Branch' + + name = fields.Char(required=True) + company_id = fields.Many2one('res.company', required=True) + telephone = fields.Char(string='Telephone No') + address = fields.Text('Address') diff --git a/odex30_base/branch/models/inherited_account_bank_statement.py b/odex30_base/branch/models/inherited_account_bank_statement.py new file mode 100644 index 0000000..952f92e --- /dev/null +++ b/odex30_base/branch/models/inherited_account_bank_statement.py @@ -0,0 +1,64 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError +import time + +class AccountBankStatement(models.Model): + _inherit = 'account.bank.statement' + + branch_id = fields.Many2one('res.branch') + + def _get_opening_balance(self, journal_id): + curr_user_id = self.env['res.users'].browse(self.env.context.get('uid', False)) + last_bnk_stmt = self.search([('journal_id', '=', journal_id),('branch_id','=',curr_user_id.branch_id.id)], limit=1) + if last_bnk_stmt: + return last_bnk_stmt.balance_end + return 0 + + @api.model + def default_get(self,fields): + res = super(AccountBankStatement, self).default_get(fields) + branch_id = False + if self.env.user.branch_id: + branch_id = self.env.user.branch_id.id + res.update({ + 'branch_id' : branch_id + }) + return res + + def button_confirm_bank(self): + self._balance_check() + statements = self.filtered(lambda r: r.state == 'open') + for statement in statements: + moves = self.env['account.move'] + for st_line in statement.line_ids: + #upon bank statement confirmation, look if some lines have the account_id set. It would trigger a journal entry + #creation towards that account, with the wanted side-effect to skip that line in the bank reconciliation widget. + st_line.fast_counterpart_creation() + if not st_line.account_id and not st_line.journal_entry_ids.ids and not st_line.statement_id.currency_id.is_zero(st_line.amount): + raise UserError(_('All the account entries lines must be processed in order to close the statement.')) + for aml in st_line.journal_entry_ids: + aml.branch_id = st_line.branch_id.id + moves |= aml.move_id + + if moves: + if self._context.get('session'): + session = self._context.get('session') + for move in moves: + move.branch_id =session.branch_id.id + for line in move.line_ids: + line.branch_id = session.branch_id.id + moves.filtered(lambda m: m.state != 'posted').post() + statement.write({'branch_id': statement.pos_session_id.branch_id.id}) + else: + moves.filtered(lambda m: m.state != 'posted').post() + for move in moves: + for move_line in move.line_ids: + line_branch = move_line.branch_id.id + move.branch_id = line_branch + + + statement.message_post(body=_('Statement %s confirmed, journal items were created.') % (statement.name,)) + + statements.write({'state': 'confirm', 'date_done': time.strftime("%Y-%m-%d %H:%M:%S")}) \ No newline at end of file diff --git a/odex30_base/branch/models/inherited_account_bank_statement_line.py b/odex30_base/branch/models/inherited_account_bank_statement_line.py new file mode 100644 index 0000000..cdda49b --- /dev/null +++ b/odex30_base/branch/models/inherited_account_bank_statement_line.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ + + +class account_bank_statement_line(models.Model): + + _inherit = 'account.bank.statement.line' + + @api.model + def default_get(self, default_fields): + res = super(account_bank_statement_line, self).default_get(default_fields) + branch_id = False + if self._context.get('branch_id'): + branch_id = self._context.get('branch_id') + elif self.env.user.branch_id: + branch_id = self.env.user.branch_id.id + res.update({ + 'branch_id' : branch_id + }) + return res + + branch_id = fields.Many2one('res.branch', string='Branch') + diff --git a/odex30_base/branch/models/inherited_account_move.py b/odex30_base/branch/models/inherited_account_move.py new file mode 100644 index 0000000..ec6d468 --- /dev/null +++ b/odex30_base/branch/models/inherited_account_move.py @@ -0,0 +1,57 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError +from odoo.tools.float_utils import float_compare + + + + +class AccountMove(models.Model): + _inherit = 'account.move' + + @api.model + def default_get(self, default_fields): + res = super(AccountMove, self).default_get(default_fields) + branch_id = False + + if self._context.get('branch_id'): + branch_id = self._context.get('branch_id') + elif self.env.user.branch_id: + branch_id = self.env.user.branch_id.id + res.update({ + 'branch_id' : branch_id + }) + return res + + branch_id = fields.Many2one('res.branch', string="Branch") + + @api.onchange('branch_id') + def _onchange_branch_id(self): + selected_brach = self.branch_id + if selected_brach: + user_id = self.env.user + user_branch = user_id.sudo().branch_id + if user_branch and user_branch.id != selected_brach.id: + raise UserError("Please select active branch only. Other may create the Multi branch issue. \n\ne.g: If you wish to add other branch then Switch branch from the header and set that.") + + +class AccountMoveLine(models.Model): + _inherit = 'account.move.line' + + @api.model + def default_get(self, default_fields): + res = super(AccountMoveLine, self).default_get(default_fields) + branch_id = False + + if self._context.get('branch_id'): + branch_id = self._context.get('branch_id') + elif self.env.user.branch_id: + branch_id = self.env.user.branch_id.id + + if self.move_id.branch_id : + branch_id = self.move_id.branch_id.id + res.update({'branch_id' : branch_id}) + return res + + branch_id = fields.Many2one('res.branch', string="Branch",related="move_id.branch_id",store=True) diff --git a/odex30_base/branch/models/inherited_account_payment.py b/odex30_base/branch/models/inherited_account_payment.py new file mode 100644 index 0000000..ae8da45 --- /dev/null +++ b/odex30_base/branch/models/inherited_account_payment.py @@ -0,0 +1,34 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError + +MAP_INVOICE_TYPE_PARTNER_TYPE = { + 'out_invoice': 'customer', + 'out_refund': 'customer', + 'in_invoice': 'supplier', + 'in_refund': 'supplier', +} + +class AccountPayment(models.Model): + _inherit = 'account.payment' + + @api.model + def default_get(self, fields): + rec = super(AccountPayment, self).default_get(fields) + invoice_defaults = self.reconciled_invoice_ids + if invoice_defaults and len(invoice_defaults) == 1: + invoice = invoice_defaults[0] + rec['branch_id'] = invoice.branch_id.id + return rec + + branch_id = fields.Many2one('res.branch') + + @api.onchange('branch_id') + def _onchange_branch_id(self): + selected_brach = self.branch_id + if selected_brach: + user_id = self.env.user + user_branch = user_id.sudo().branch_id + if user_branch and user_branch.id != selected_brach.id: + raise UserError("Please select active branch only. Other may create the Multi branch issue. \n\ne.g: If you wish to add other branch then Switch branch from the header and set that.") diff --git a/odex30_base/branch/models/inherited_customer.py b/odex30_base/branch/models/inherited_customer.py new file mode 100644 index 0000000..6c5ac64 --- /dev/null +++ b/odex30_base/branch/models/inherited_customer.py @@ -0,0 +1,19 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ + + +class ResPartnerIn(models.Model): + _inherit = 'res.partner' + + + @api.model + def default_get(self, default_fields): + res = super(ResPartnerIn, self).default_get(default_fields) + if self.env.user.branch_id: + res.update({ + 'branch_id' : self.env.user.branch_id.id or False + }) + return res + + branch_id = fields.Many2one('res.branch', string="Branch") \ No newline at end of file diff --git a/odex30_base/branch/models/inherited_product.py b/odex30_base/branch/models/inherited_product.py new file mode 100644 index 0000000..b1ffccd --- /dev/null +++ b/odex30_base/branch/models/inherited_product.py @@ -0,0 +1,19 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ + + +class ProductTemplateIn(models.Model): + _inherit = 'product.template' + + + @api.model + def default_get(self, default_fields): + res = super(ProductTemplateIn, self).default_get(default_fields) + if self.env.user.branch_id: + res.update({ + 'branch_id' : self.env.user.branch_id.id or False + }) + return res + + branch_id = fields.Many2one('res.branch', string="Branch") \ No newline at end of file diff --git a/odex30_base/branch/models/inherited_purchase_order.py b/odex30_base/branch/models/inherited_purchase_order.py new file mode 100644 index 0000000..f064b77 --- /dev/null +++ b/odex30_base/branch/models/inherited_purchase_order.py @@ -0,0 +1,137 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError + + +class purchase_order(models.Model): + + _inherit = 'purchase.order.line' + + + def _prepare_account_move_line(self, move=False): + result = super(purchase_order, self)._prepare_account_move_line(move) + result.update({ + 'branch_id' : self.order_id.branch_id.id or False, + + }) + return result + + + @api.model + def default_get(self, default_fields): + res = super(purchase_order, self).default_get(default_fields) + branch_id = False + if self._context.get('branch_id'): + branch_id = self._context.get('branch_id') + elif self.env.user.branch_id: + branch_id = self.env.user.branch_id.id + res.update({'branch_id' : branch_id}) + return res + + branch_id = fields.Many2one('res.branch', string="Branch") + + + def _prepare_stock_moves(self, picking): + result = super(purchase_order, self)._prepare_stock_moves(picking) + + branch_id = False + if self.branch_id: + branch_id = self.branch_id.id + elif self.env.user.branch_id: + branch_id = self.env.user.branch_id.id + + for res in result: + res.update({'branch_id' : branch_id}) + + return result + + +class PurchaseOrder(models.Model): + _inherit = 'purchase.order' + + + @api.model + def default_get(self,fields): + res = super(PurchaseOrder, self).default_get(fields) + branch_id = picking_type_id = False + + if self.env.user.branch_id: + branch_id = self.env.user.branch_id.id + + if branch_id: + branched_warehouse = self.env['stock.warehouse'].search([('branch_id','=',branch_id)]) + if branched_warehouse: + picking_type_id = branched_warehouse[0].in_type_id.id + else: + picking = self._default_picking_type() + picking_type_id = picking.id + + res.update({ + 'branch_id' : branch_id, + 'picking_type_id' : picking_type_id + }) + + return res + + branch_id = fields.Many2one('res.branch', string='Branch') + + @api.model + def _prepare_picking(self): + res = super(PurchaseOrder, self)._prepare_picking() + branch_id = False + if self.branch_id: + branch_id = self.branch_id.id + elif self.env.user.branch_id: + branch_id = self.env.user.branch_id.id + res.update({ + 'branch_id' : branch_id + }) + return res + + + def _prepare_invoice(self): + result = super(PurchaseOrder, self)._prepare_invoice() + branch_id = False + if self.branch_id: + branch_id = self.branch_id.id + elif self.env.user.branch_id: + branch_id = self.env.user.branch_id.id + + result.update({ + + 'branch_id' : branch_id + }) + + return result + def action_view_invoice(self, invoices=False): + ''' + This function returns an action that display existing vendor bills of given purchase order ids. + When only one found, show the vendor bill immediately. + ''' + + result = super(PurchaseOrder, self).action_view_invoice(invoices) + + branch_id = False + if self.branch_id: + branch_id = self.branch_id.id + elif self.env.user.branch_id: + branch_id = self.env.user.branch_id.id + + + result.update({ + + 'branch_id' : branch_id + }) + + + return result + + @api.onchange('branch_id') + def _onchange_branch_id(self): + selected_brach = self.branch_id + if selected_brach: + user_id = self.env.user + user_branch = user_id.sudo().branch_id + if user_branch and user_branch.id != selected_brach.id: + raise UserError("Please select active branch only. Other may create the Multi branch issue. \n\ne.g: If you wish to add other branch then Switch branch from the header and set that.") \ No newline at end of file diff --git a/odex30_base/branch/models/inherited_res_users.py b/odex30_base/branch/models/inherited_res_users.py new file mode 100644 index 0000000..d278b0d --- /dev/null +++ b/odex30_base/branch/models/inherited_res_users.py @@ -0,0 +1,18 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ + + +class ResUsers(models.Model): + _inherit = 'res.users' + + branch_ids = fields.Many2many('res.branch',string="Allowed Branch") + branch_id = fields.Many2one('res.branch', string= 'Branch') + + def write(self, values): + if 'branch_id' in values or 'branch_ids' in values: + self.env['ir.model.access'].call_cache_clearing_methods() + self.env['ir.rule'].clear_caches() + # self.has_group.clear_cache(self) + user = super(ResUsers, self).write(values) + return user diff --git a/odex30_base/branch/models/inherited_sale_order.py b/odex30_base/branch/models/inherited_sale_order.py new file mode 100644 index 0000000..93ddbc0 --- /dev/null +++ b/odex30_base/branch/models/inherited_sale_order.py @@ -0,0 +1,48 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError + + +class SaleOrder(models.Model): + _inherit = 'sale.order' + + + @api.model + def default_get(self,fields): + res = super(SaleOrder, self).default_get(fields) + branch_id = warehouse_id = False + if self.env.user.branch_id: + branch_id = self.env.user.branch_id.id + if branch_id: + branched_warehouse = self.env['stock.warehouse'].search([('branch_id','=',branch_id)]) + if branched_warehouse: + warehouse_id = branched_warehouse.ids[0] + else: + warehouse_id = self._default_warehouse_id() + warehouse_id = warehouse_id.id + + res.update({ + 'branch_id' : branch_id, + 'warehouse_id' : warehouse_id + }) + + return res + + branch_id = fields.Many2one('res.branch', string="Branch") + + + def _prepare_invoice(self): + res = super(SaleOrder, self)._prepare_invoice() + res['branch_id'] = self.branch_id.id + return res + + + @api.onchange('branch_id') + def _onchange_branch_id(self): + selected_brach = self.branch_id + if selected_brach: + user_id = self.env.user + user_branch = user_id.sudo().branch_id + if user_branch and user_branch.id != selected_brach.id: + raise UserError("Please select active branch only. Other may create the Multi branch issue. \n\ne.g: If you wish to add other branch then Switch branch from the header and set that.") \ No newline at end of file diff --git a/odex30_base/branch/models/inherited_stock_inventory.py b/odex30_base/branch/models/inherited_stock_inventory.py new file mode 100644 index 0000000..4576f53 --- /dev/null +++ b/odex30_base/branch/models/inherited_stock_inventory.py @@ -0,0 +1,46 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError + + +class stock_inventory(models.Model): + _inherit = 'stock.inventory' + + + @api.model + def default_get(self,fields): + res = super(stock_inventory, self).default_get(fields) + if res.get('location_id'): + location_branch = self.env['stock.location'].browse(res.get('location_id')).branch_id.id + if location_branch: + res['branch_id'] = location_branch + else: + user_branch = self.env.user.branch_id + if user_branch: + res['branch_id'] = user_branch.id + return res + + branch_id = fields.Many2one('res.branch') + + + def post_inventory(self): + # The inventory is posted as a single step which means quants cannot be moved from an internal location to another using an inventory + # as they will be moved to inventory loss, and other quants will be created to the encoded quant location. This is a normal behavior + # as quants cannot be reuse from inventory location (users can still manually move the products before/after the inventory if they want). + self.mapped('move_ids').filtered(lambda move: move.state != 'done')._action_done() + for move_id in self.move_ids: + account_move =self.env['account.move'].search([('stock_move_id','=',move_id.id)]) + account_move.write({'branch_id':self.branch_id.id}) + for line in account_move.line_ids: + line.write({'branch_id':self.branch_id.id}) + + + @api.onchange('branch_id') + def _onchange_branch_id(self): + selected_brach = self.branch_id + if selected_brach: + user_id = self.env.user + user_branch = user_id.sudo().branch_id + if user_branch and user_branch.id != selected_brach.id: + raise UserError("Please select active branch only. Other may create the Multi branch issue. \n\ne.g: If you wish to add other branch then Switch branch from the header and set that.") \ No newline at end of file diff --git a/odex30_base/branch/models/inherited_stock_location.py b/odex30_base/branch/models/inherited_stock_location.py new file mode 100644 index 0000000..5da195f --- /dev/null +++ b/odex30_base/branch/models/inherited_stock_location.py @@ -0,0 +1,30 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError + + +class StockLocation(models.Model): + _inherit = 'stock.location' + + branch_id = fields.Many2one('res.branch') + + @api.constrains('branch_id') + def _check_branch(self): + warehouse_obj = self.env['stock.warehouse'] + warehouse_id = warehouse_obj.search( + ['|', '|', ('wh_input_stock_loc_id', '=', self.id), + ('lot_stock_id', '=', self.id), + ('wh_output_stock_loc_id', '=', self.id)]) + for warehouse in warehouse_id: + if self.branch_id != warehouse.branch_id: + raise UserError(_('Configuration error\nYou must select same branch on a location as assigned on a warehouse configuration.')) + + @api.onchange('branch_id') + def _onchange_branch_id(self): + selected_brach = self.branch_id + if selected_brach: + user_id = self.env.user + user_branch = user_id.sudo().branch_id + if user_branch and user_branch.id != selected_brach.id: + raise UserError("Please select active branch only. Other may create the Multi branch issue. \n\ne.g: If you wish to add other branch then Switch branch from the header and set that.") \ No newline at end of file diff --git a/odex30_base/branch/models/inherited_stock_move.py b/odex30_base/branch/models/inherited_stock_move.py new file mode 100644 index 0000000..606408b --- /dev/null +++ b/odex30_base/branch/models/inherited_stock_move.py @@ -0,0 +1,82 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError +from itertools import groupby + +class StockMove(models.Model): + _inherit = 'stock.move' + + branch_id = fields.Many2one('res.branch') + + def _assign_picking(self): + """ Try to assign the moves to an existing picking that has not been + reserved yet and has the same procurement group, locations and picking + type (moves should already have them identical). Otherwise, create a new + picking to assign them to. """ + Picking = self.env['stock.picking'] + grouped_moves = groupby(sorted(self, key=lambda m: [f.id for f in m._key_assign_picking()]), key=lambda m: [m._key_assign_picking()]) + for group, moves in grouped_moves: + moves = self.env['stock.move'].concat(*list(moves)) + branch_id = self.group_id.sale_id.branch_id.id if self.group_id.sale_id and self.group_id.sale_id.branch_id else False + moves.write({'branch_id': branch_id}) + new_picking = False + # Could pass the arguments contained in group but they are the same + # for each move that why moves[0] is acceptable + picking = moves[0]._search_picking_for_assignation() + if picking: + if any(picking.partner_id.id != m.partner_id.id or + picking.origin != m.origin for m in moves): + # If a picking is found, we'll append `move` to its move list and thus its + # `partner_id` and `ref` field will refer to multiple records. In this + # case, we chose to wipe them. + picking.write({ + 'partner_id': False, + 'origin': False, + }) + else: + new_picking = True + picking = Picking.create(moves._get_new_picking_values()) + + moves.write({'picking_id': picking.id}) + moves._assign_picking_post_process(new=new_picking) + return True + + def _get_new_picking_values(self): + vals = super(StockMove, self)._get_new_picking_values() + vals['branch_id'] = self.group_id.sale_id.branch_id.id + return vals + + def _create_account_move_line(self, credit_account_id, debit_account_id, journal_id, qty, description, svl_id, cost): + self.ensure_one() + AccountMove = self.env['account.move'].with_context(default_journal_id=journal_id) + + move_lines = self._prepare_account_move_line(qty, cost, credit_account_id, debit_account_id, description) + if move_lines: + date = self._context.get('force_period_date', fields.Date.context_today(self)) + new_account_move = AccountMove.sudo().create({ + 'journal_id': journal_id, + 'line_ids': move_lines, + 'date': date, + 'ref': description, + 'stock_move_id': self.id, + 'stock_valuation_layer_ids': [(6, None, [svl_id])], + 'move_type': 'entry', + 'branch_id': self.picking_id.branch_id.id or self.branch_id.id or False, + }) + new_account_move._post() + + def _generate_valuation_lines_data(self, partner_id, qty, debit_value, credit_value, debit_account_id, credit_account_id, description): + # This method returns a dictionary to provide an easy extension hook to modify the valuation lines (see purchase for an example) + result = super(StockMove, self)._generate_valuation_lines_data(partner_id, qty, debit_value, credit_value, debit_account_id, credit_account_id, description) + + branch_id = False + if self.branch_id: + branch_id = self.branch_id.id + elif self.env.user.branch_id: + branch_id = self.env.user.branch_id.id + + for res in result: + result[res].update({'branch_id' : branch_id}) + + return result \ No newline at end of file diff --git a/odex30_base/branch/models/inherited_stock_picking.py b/odex30_base/branch/models/inherited_stock_picking.py new file mode 100644 index 0000000..63dedaf --- /dev/null +++ b/odex30_base/branch/models/inherited_stock_picking.py @@ -0,0 +1,28 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError + + +class StockPicking(models.Model): + _inherit = 'stock.picking' + + @api.model + def default_get(self, default_fields): + res = super(StockPicking, self).default_get(default_fields) + if self.env.user.branch_id: + res.update({ + 'branch_id' : self.env.user.branch_id.id or False + }) + return res + + branch_id = fields.Many2one('res.branch', string="Branch") + + @api.onchange('branch_id') + def _onchange_branch_id(self): + selected_brach = self.branch_id + if selected_brach: + user_id = self.env.user + user_branch = user_id.sudo().branch_id + if user_branch and user_branch.id != selected_brach.id: + raise UserError("Please select active branch only. Other may create the Multi branch issue. \n\ne.g: If you wish to add other branch then Switch branch from the header and set that.") \ No newline at end of file diff --git a/odex30_base/branch/models/inherited_stock_warehouse.py b/odex30_base/branch/models/inherited_stock_warehouse.py new file mode 100644 index 0000000..6c736de --- /dev/null +++ b/odex30_base/branch/models/inherited_stock_warehouse.py @@ -0,0 +1,25 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError + +class StockWarehouse(models.Model): + _inherit = 'stock.warehouse' + + branch_id = fields.Many2one('res.branch') + + @api.onchange('branch_id') + def _onchange_branch_id(self): + selected_brach = self.branch_id + if selected_brach: + user_id = self.env.user + user_branch = user_id.sudo().branch_id + if user_branch and user_branch.id != selected_brach.id: + raise UserError("Please select active branch only. Other may create the Multi branch issue. \n\ne.g: If you wish to add other branch then Switch branch from the header and set that.") + + + +class StockPickingTypeIn(models.Model): + _inherit = 'stock.picking.type' + + branch_id = fields.Many2one('res.branch',related='warehouse_id.branch_id', store=True,) diff --git a/odex30_base/branch/models/ir_http.py b/odex30_base/branch/models/ir_http.py new file mode 100644 index 0000000..b4116a7 --- /dev/null +++ b/odex30_base/branch/models/ir_http.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +import hashlib +import json +from odoo import api, models +from odoo.http import request +from odoo.tools import ustr +from odoo.addons.web.controllers.main import module_boot, HomeStaticTemplateHelpers +import odoo + +class Http(models.AbstractModel): + _inherit = 'ir.http' + + def session_info(self): + user = request.env.user + version_info = odoo.service.common.exp_version() + + user_context = request.session.get_context() if request.session.uid else {} + + session_info = { + "uid": request.session.uid, + "is_system": user._is_system() if request.session.uid else False, + "is_admin": user._is_admin() if request.session.uid else False, + "user_context": request.session.get_context() if request.session.uid else {}, + "db": request.session.db, + "server_version": version_info.get('server_version'), + "server_version_info": version_info.get('server_version_info'), + "name": user.name, + "username": user.login, + "partner_display_name": user.partner_id.display_name, + "company_id": user.company_id.id if request.session.uid else None, # YTI TODO: Remove this from the user context + "branch_id": user.branch_id.id if request.session.uid else None, + "partner_id": user.partner_id.id if request.session.uid and user.partner_id else None, + "web.base.url": self.env['ir.config_parameter'].sudo().get_param('web.base.url', default=''), + } + if self.env.user.has_group('base.group_user'): + # the following is only useful in the context of a webclient bootstrapping + # but is still included in some other calls (e.g. '/web/session/authenticate') + # to avoid access errors and unnecessary information, it is only included for users + # with access to the backend ('internal'-type users) + mods = module_boot() + qweb_checksum = HomeStaticTemplateHelpers.get_qweb_templates_checksum(addons=mods, debug=request.session.debug) + lang = user_context.get("lang") + translation_hash = request.env['ir.translation'].get_web_translations_hash(mods, lang) + menu_json_utf8 = json.dumps(request.env['ir.ui.menu'].load_menus(request.session.debug), default=ustr, sort_keys=True).encode() + cache_hashes = { + "load_menus": hashlib.sha1(menu_json_utf8).hexdigest(), + "qweb": qweb_checksum, + "translations": translation_hash, + } + session_info.update({ + # current_company should be default_company + "user_companies": {'current_company': (user.company_id.id, user.company_id.name), 'allowed_companies': [(comp.id, comp.name) for comp in user.company_ids]}, + "user_branches": {'current_branch': (user.branch_id.id, user.branch_id.name), 'allowed_branch': [(comp.id, comp.name) for comp in user.branch_ids]}, + "currencies": self.get_currencies(), + "show_effect": True, + "display_switch_company_menu": user.has_group('base.group_multi_company') and len(user.company_ids) > 1, + "display_switch_branch_menu": user.has_group('branch.group_multi_branch') and len(user.branch_ids) > 1, + "cache_hashes": cache_hashes, + "allowed_branch_ids" : user.branch_id.ids + }) + return session_info + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file diff --git a/odex30_base/branch/reports/__init__.py b/odex30_base/branch/reports/__init__.py new file mode 100644 index 0000000..798a488 --- /dev/null +++ b/odex30_base/branch/reports/__init__.py @@ -0,0 +1,8 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from . import inherited_sale_report +from . import inherited_account_invoice_report +from . import inherited_purchase_report + + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/odex30_base/branch/reports/inherited_account_invoice_report.py b/odex30_base/branch/reports/inherited_account_invoice_report.py new file mode 100644 index 0000000..63f29cf --- /dev/null +++ b/odex30_base/branch/reports/inherited_account_invoice_report.py @@ -0,0 +1,12 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class AccountInvoiceReport(models.Model): + _inherit = "account.invoice.report" + + branch_id = fields.Many2one('res.branch') + + def _select(self): + return super(AccountInvoiceReport, self)._select() + ", move.branch_id" \ No newline at end of file diff --git a/odex30_base/branch/reports/inherited_purchase_report.py b/odex30_base/branch/reports/inherited_purchase_report.py new file mode 100644 index 0000000..32fde6b --- /dev/null +++ b/odex30_base/branch/reports/inherited_purchase_report.py @@ -0,0 +1,15 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class PurchaseReport(models.Model): + _inherit = "purchase.report" + + branch_id = fields.Many2one('res.branch') + + def _select(self): + return super(PurchaseReport, self)._select() + ", po.branch_id as branch_id" + + def _group_by(self): + return super(PurchaseReport, self)._group_by() + ", po.branch_id" \ No newline at end of file diff --git a/odex30_base/branch/reports/inherited_sale_report.py b/odex30_base/branch/reports/inherited_sale_report.py new file mode 100644 index 0000000..2ec518c --- /dev/null +++ b/odex30_base/branch/reports/inherited_sale_report.py @@ -0,0 +1,14 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class SaleReport(models.Model): + _inherit = "sale.report" + + branch_id = fields.Many2one('res.branch') + + def _query(self, with_clause='', fields={}, groupby='', from_clause=''): + fields['branch_id'] = ", s.branch_id as branch_id" + return super(SaleReport, self)._query(with_clause, fields, groupby, from_clause) + diff --git a/odex30_base/branch/security/branch_security.xml b/odex30_base/branch/security/branch_security.xml new file mode 100644 index 0000000..c63bb1b --- /dev/null +++ b/odex30_base/branch/security/branch_security.xml @@ -0,0 +1,263 @@ + + + + + + Branch + 11 + + + + User + + + + + + Manager + + + + + + + + Res Branch Manager + + + [(1,'=',1)] + + + + + + Res Branch User + + + [('id','=',user.branch_id.id)] + + + + + + Personal Orders + + ['|',('branch_id','=',user.branch_id.id),('branch_id','=',False),('user_id','=',user.id)] + + + + + All Branch Orders + + ['|',('branch_id','=',False),('branch_id','=',user.branch_id.id)] + + + + + All Orders + + [(1,'=',1)] + + + + + + Purchase Branch Manager + + + [(1,'=',1)] + + + + + + + + Purchase Branch + + + ['|',('branch_id','=',False),('branch_id','=',user.branch_id.id)] + + + + + Picking Branch Manager + + + [(1,'=',1)] + + + + + Picking Branch + + + ['|',('branch_id','=',False),('branch_id','=',user.branch_id.id)] + + + + + Warehouse Branch Manager + + + [(1,'=',1)] + + + + + Warehouse Branch + + + ['|',('branch_id','=',False),('branch_id','=',user.branch_id.id)] + + + + + Location Branch Manager + + + [(1,'=',1)] + + + + + Location Branch + + + ['|',('branch_id','=',False),('branch_id','=',user.branch_id.id)] + + + + + Picking Type Branch Manager + + + [(1,'=',1)] + + + + + Picking Type Branch + + + ['|',('branch_id','=',False),('branch_id','=',user.branch_id.id)] + + + + + Stock Quant Branch Manager + + + [(1,'=',1)] + + + + + Stock Quant Branch + + + ['|',('location_id.branch_id','=',False),('location_id.branch_id','=',user.branch_id.id)] + + + + + Stock Move Line Branch Manager + + + [(1,'=',1)] + + + + + Stock Move Line Branch + + + ['|',('location_dest_id.branch_id','=',False),('location_dest_id.branch_id','=',user.branch_id.id)] + + + + + Warehouse Branch Manager + + + [(1,'=',1)] + + + + + Warehouse Branch + + + ['|',('branch_id','=',False),('branch_id','=',user.branch_id.id)] + + + + + Product Template Branch Manager + + + [(1,'=',1)] + + + + + Product Template Branch + + + ['|',('branch_id','=',False),('branch_id','=',user.branch_id.id)] + + + + + Product Product Branch Manager + + + [(1,'=',1)] + + + + + Product Product Branch + + + ['|',('product_tmpl_id.branch_id','=',False),('product_tmpl_id.branch_id','=',user.branch_id.id)] + + + + + + + + + + diff --git a/odex30_base/branch/security/ir.model.access.csv b/odex30_base/branch/security/ir.model.access.csv new file mode 100644 index 0000000..b506e49 --- /dev/null +++ b/odex30_base/branch/security/ir.model.access.csv @@ -0,0 +1,10 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink + +access_res_branch_user,res.branch.user,model_res_branch,branch.group_branch_user,1,1,0,0 +access_res_branch_user_all,res.branch.user.all,model_res_branch,,1,1,0,0 +access_res_branch_manager,res.branch.manager,model_res_branch,branch.group_branch_user_manager,1,1,1,1 +action_res_branch_location_rule,res.branch.user.location,stock.model_stock_location,branch.group_branch_user,1,1,1,1 +action_res_branch_location_rule_manager,res.branch.user.location,stock.model_stock_location,branch.group_branch_user_manager,1,1,1,1 +access_stock_warehouse_branch_user,stock.warehouse.branch.user,stock.model_stock_warehouse,branch.group_branch_user,1,1,0,0 +access_stock_warehouse_branch_manager,stock.warehouse.branch.manager,stock.model_stock_warehouse,branch.group_branch_user_manager,1,1,1,1 +access_stock_picking_branc_user,stock.picking.branch.user,stock.model_stock_picking,branch.group_branch_user,1,1,1,1 \ No newline at end of file diff --git a/odex30_base/branch/security/multi_branch.xml b/odex30_base/branch/security/multi_branch.xml new file mode 100644 index 0000000..0041133 --- /dev/null +++ b/odex30_base/branch/security/multi_branch.xml @@ -0,0 +1,8 @@ + + + + + Multi Branches + + + \ No newline at end of file diff --git a/odex30_base/branch/static/description/10_sale_branch.png b/odex30_base/branch/static/description/10_sale_branch.png new file mode 100644 index 0000000..ead53e8 Binary files /dev/null and b/odex30_base/branch/static/description/10_sale_branch.png differ diff --git a/odex30_base/branch/static/description/11_branch_groupby.png b/odex30_base/branch/static/description/11_branch_groupby.png new file mode 100644 index 0000000..b675afd Binary files /dev/null and b/odex30_base/branch/static/description/11_branch_groupby.png differ diff --git a/odex30_base/branch/static/description/12_brnach_analysis.png b/odex30_base/branch/static/description/12_brnach_analysis.png new file mode 100644 index 0000000..0525d51 Binary files /dev/null and b/odex30_base/branch/static/description/12_brnach_analysis.png differ diff --git a/odex30_base/branch/static/description/13_branch_picking.png b/odex30_base/branch/static/description/13_branch_picking.png new file mode 100644 index 0000000..3f5ea80 Binary files /dev/null and b/odex30_base/branch/static/description/13_branch_picking.png differ diff --git a/odex30_base/branch/static/description/14_branch_invoice.png b/odex30_base/branch/static/description/14_branch_invoice.png new file mode 100644 index 0000000..9c26571 Binary files /dev/null and b/odex30_base/branch/static/description/14_branch_invoice.png differ diff --git a/odex30_base/branch/static/description/15_journal_items.png b/odex30_base/branch/static/description/15_journal_items.png new file mode 100644 index 0000000..0ac821e Binary files /dev/null and b/odex30_base/branch/static/description/15_journal_items.png differ diff --git a/odex30_base/branch/static/description/16_branch_payment.png b/odex30_base/branch/static/description/16_branch_payment.png new file mode 100644 index 0000000..a58380e Binary files /dev/null and b/odex30_base/branch/static/description/16_branch_payment.png differ diff --git a/odex30_base/branch/static/description/17_branch_branck_statement.png b/odex30_base/branch/static/description/17_branch_branck_statement.png new file mode 100644 index 0000000..6f72432 Binary files /dev/null and b/odex30_base/branch/static/description/17_branch_branck_statement.png differ diff --git a/odex30_base/branch/static/description/18_branch_purchase.png b/odex30_base/branch/static/description/18_branch_purchase.png new file mode 100644 index 0000000..dc788df Binary files /dev/null and b/odex30_base/branch/static/description/18_branch_purchase.png differ diff --git a/odex30_base/branch/static/description/19_branch_groupby.png b/odex30_base/branch/static/description/19_branch_groupby.png new file mode 100644 index 0000000..ad537ad Binary files /dev/null and b/odex30_base/branch/static/description/19_branch_groupby.png differ diff --git a/odex30_base/branch/static/description/1_branch_Access.png b/odex30_base/branch/static/description/1_branch_Access.png new file mode 100644 index 0000000..2ec6c3c Binary files /dev/null and b/odex30_base/branch/static/description/1_branch_Access.png differ diff --git a/odex30_base/branch/static/description/20_branch_analysis.png b/odex30_base/branch/static/description/20_branch_analysis.png new file mode 100644 index 0000000..2381494 Binary files /dev/null and b/odex30_base/branch/static/description/20_branch_analysis.png differ diff --git a/odex30_base/branch/static/description/21_branch_receipt.png b/odex30_base/branch/static/description/21_branch_receipt.png new file mode 100644 index 0000000..1d63b05 Binary files /dev/null and b/odex30_base/branch/static/description/21_branch_receipt.png differ diff --git a/odex30_base/branch/static/description/22_branch_bill.png b/odex30_base/branch/static/description/22_branch_bill.png new file mode 100644 index 0000000..63692b7 Binary files /dev/null and b/odex30_base/branch/static/description/22_branch_bill.png differ diff --git a/odex30_base/branch/static/description/23_branch_payment.png b/odex30_base/branch/static/description/23_branch_payment.png new file mode 100644 index 0000000..86c3dc3 Binary files /dev/null and b/odex30_base/branch/static/description/23_branch_payment.png differ diff --git a/odex30_base/branch/static/description/24_branch_warehouse.png b/odex30_base/branch/static/description/24_branch_warehouse.png new file mode 100644 index 0000000..03cfea5 Binary files /dev/null and b/odex30_base/branch/static/description/24_branch_warehouse.png differ diff --git a/odex30_base/branch/static/description/25_branch_location.png b/odex30_base/branch/static/description/25_branch_location.png new file mode 100644 index 0000000..c725462 Binary files /dev/null and b/odex30_base/branch/static/description/25_branch_location.png differ diff --git a/odex30_base/branch/static/description/26_branch_inventory.png b/odex30_base/branch/static/description/26_branch_inventory.png new file mode 100644 index 0000000..38dea83 Binary files /dev/null and b/odex30_base/branch/static/description/26_branch_inventory.png differ diff --git a/odex30_base/branch/static/description/2_branch_tree.png b/odex30_base/branch/static/description/2_branch_tree.png new file mode 100644 index 0000000..0dd7ebe Binary files /dev/null and b/odex30_base/branch/static/description/2_branch_tree.png differ diff --git a/odex30_base/branch/static/description/3_branch_form.png b/odex30_base/branch/static/description/3_branch_form.png new file mode 100644 index 0000000..ecdd9f6 Binary files /dev/null and b/odex30_base/branch/static/description/3_branch_form.png differ diff --git a/odex30_base/branch/static/description/4_branch_user.png b/odex30_base/branch/static/description/4_branch_user.png new file mode 100644 index 0000000..acc9508 Binary files /dev/null and b/odex30_base/branch/static/description/4_branch_user.png differ diff --git a/odex30_base/branch/static/description/5_multi_branch.png b/odex30_base/branch/static/description/5_multi_branch.png new file mode 100644 index 0000000..3edb712 Binary files /dev/null and b/odex30_base/branch/static/description/5_multi_branch.png differ diff --git a/odex30_base/branch/static/description/6_multi_branch_change.png b/odex30_base/branch/static/description/6_multi_branch_change.png new file mode 100644 index 0000000..da5af20 Binary files /dev/null and b/odex30_base/branch/static/description/6_multi_branch_change.png differ diff --git a/odex30_base/branch/static/description/7_branch_customer.png b/odex30_base/branch/static/description/7_branch_customer.png new file mode 100644 index 0000000..51f7802 Binary files /dev/null and b/odex30_base/branch/static/description/7_branch_customer.png differ diff --git a/odex30_base/branch/static/description/8_branch_product.png b/odex30_base/branch/static/description/8_branch_product.png new file mode 100644 index 0000000..8622072 Binary files /dev/null and b/odex30_base/branch/static/description/8_branch_product.png differ diff --git a/odex30_base/branch/static/description/9_branch_variant.png b/odex30_base/branch/static/description/9_branch_variant.png new file mode 100644 index 0000000..debfd49 Binary files /dev/null and b/odex30_base/branch/static/description/9_branch_variant.png differ diff --git a/odex30_base/branch/static/description/Banner.png b/odex30_base/branch/static/description/Banner.png new file mode 100644 index 0000000..669873a Binary files /dev/null and b/odex30_base/branch/static/description/Banner.png differ diff --git a/odex30_base/branch/static/description/bi_logo.png b/odex30_base/branch/static/description/bi_logo.png new file mode 100644 index 0000000..e5d60b2 Binary files /dev/null and b/odex30_base/branch/static/description/bi_logo.png differ diff --git a/odex30_base/branch/static/description/demanded/all_in_one_pos.png b/odex30_base/branch/static/description/demanded/all_in_one_pos.png new file mode 100644 index 0000000..e51fc57 Binary files /dev/null and b/odex30_base/branch/static/description/demanded/all_in_one_pos.png differ diff --git a/odex30_base/branch/static/description/demanded/bi_generic_import.png b/odex30_base/branch/static/description/demanded/bi_generic_import.png new file mode 100644 index 0000000..785b657 Binary files /dev/null and b/odex30_base/branch/static/description/demanded/bi_generic_import.png differ diff --git a/odex30_base/branch/static/description/demanded/branch.png b/odex30_base/branch/static/description/demanded/branch.png new file mode 100644 index 0000000..70209a6 Binary files /dev/null and b/odex30_base/branch/static/description/demanded/branch.png differ diff --git a/odex30_base/branch/static/description/demanded/customer_overdue.png b/odex30_base/branch/static/description/demanded/customer_overdue.png new file mode 100644 index 0000000..b9efae2 Binary files /dev/null and b/odex30_base/branch/static/description/demanded/customer_overdue.png differ diff --git a/odex30_base/branch/static/description/demanded/generic_excel_report.png b/odex30_base/branch/static/description/demanded/generic_excel_report.png new file mode 100644 index 0000000..4800329 Binary files /dev/null and b/odex30_base/branch/static/description/demanded/generic_excel_report.png differ diff --git a/odex30_base/branch/static/description/demanded/sale_commision.png b/odex30_base/branch/static/description/demanded/sale_commision.png new file mode 100644 index 0000000..145289f Binary files /dev/null and b/odex30_base/branch/static/description/demanded/sale_commision.png differ diff --git a/odex30_base/branch/static/description/features/branch_access.png b/odex30_base/branch/static/description/features/branch_access.png new file mode 100644 index 0000000..e7aee7c Binary files /dev/null and b/odex30_base/branch/static/description/features/branch_access.png differ diff --git a/odex30_base/branch/static/description/features/branch_metrics.png b/odex30_base/branch/static/description/features/branch_metrics.png new file mode 100644 index 0000000..59abab8 Binary files /dev/null and b/odex30_base/branch/static/description/features/branch_metrics.png differ diff --git a/odex30_base/branch/static/description/icon.png b/odex30_base/branch/static/description/icon.png new file mode 100644 index 0000000..a02d004 Binary files /dev/null and b/odex30_base/branch/static/description/icon.png differ diff --git a/odex30_base/branch/static/description/index.html b/odex30_base/branch/static/description/index.html new file mode 100644 index 0000000..7b5f197 --- /dev/null +++ b/odex30_base/branch/static/description/index.html @@ -0,0 +1,446 @@ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+

+ Multiple Branch/Unit(operation) Management Odoo Apps for Single Company +

+

+ Multi Branches management for All Application Odoo Apps +

+

+ Manage Different Branch Unit for single company in Odoo +

+

+ Do you have multiple unit for single company? Do you want them to works as separate entity inside the company? Here you go, This multiple branch management Odoo apps helps users to make different branches for single company with multi branch concept which works same as multi-company environment.
+ Also Don't worry about the access rights too, We have added branch user/manager roles inside the Odoo module, Branch user can only access records of its specific branch and Branch manager can see records of all Branches.
+ Branch functionality added to Sale Order, Purchase Order, Invoice/Billing, Accounting, Warehouse and Products etc. +
+

+

+ You can also manage multiple branch with multi company environment. For each company you can add several branches also multi company rules is already applied on branch object, so if user don't have access of company then that user can't have access of branch of that specific company. +

+

+ Multi branch Odoo apps works for both community and enterprise edition with all generic application like contact, product, sales, purchase, warehouse,billing, accounting etc. We have other separate apps available for Manufacturing,Projects, Subscription, Helpdesk etc, you can see that on Odoo store and If you can't see it contact us, we will help you on that. +
+ If you are using Odoo enterprise edition and don't want to use specific application i.e Purchase or Sales, then don't worry we will simply remove that dependency for you without any extra cost. +

+ +

looking for Multiple Branch Accounting Enterprise Reports Apps, please check below module link +
+ Financial Reports For Branch -Enterprise Edition Odoo Apps. +

+ +

Looking for Multiple Branch Accounting Community Reports Apps, please check below module link +
+ Multiple Branch Accounting Community Reports Odoo Apps. +

+ +

Here is Advance Multiple Branch Odoo Apps, please check below module link +
+ Advance Multi Branch Management Odoo Apps. +

+

Multi Language Translation Available

+

We have added Translation using google translate for English (US), Arabic, French / Français, Spanish / Español and Dutch / Nederlands, if you want to change translation terms or add new translation provide us translation, we will add that without any cost. +

+
+
+
+
+
+ English + Arabic + French + Spanish + Dutch +
+
+
+
+ +
+
+
+

Features

+
+
+
+
+
+ +
+
+

Multi Branch Concept.

+ It allows you to create Multiple Branch/Unit, Working as multi branch concept same as Odoo's multi company environment. +
+
+
+
+
+
+ +
+
+

Complete Workflow for Branch.

+ Branch functionality added to Sales, Purchase, Invoice, Warehouse, Access group created for branch manager and branch user with specific branch. +
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+

Branch Access Rights

+

User have to give branch access like User or Manage, User have to "Multi Branches".

+ +

+

+
+
+ +
+
+
+

Create Multiple Branch

+

Branch Manager can create multiple branch under Settings > Users & Companies > Branch menu, User also can set branch details like address, phone, company.

+ + +

Assign Branch User

+

Branch manager can assign a branch for which specific user is belongs.

+ +
+
+
+ +
+
+
+

Multi Branch Feature

+

Users with "Multi Branches" access rights can see and change multiple branch from header.

+ +

On clicking branch on header user can see allowed branches and can select one, on changing branch users branch will also changed under users settings.

+ +
+
+
+ +
+
+
+

Branch On Customer

+

Branch manager can set customer for specific branch by selecting branch on customer.

+ + +

Branch On Product Template

+

User can set branch on product template, selected branch on product template will automatically added to product variant.

+ + +

Branch On Product Variant

+ +
+
+
+ +
+
+
+

Branch On Sales Flow

+

While creating sales order user who is currently login, branch of the user is set as branch to the sales order and warehouse shipment address is also set according to selected branch.

+ +

User can see created records of sale order group by branch as shown bellow image.

+ +
+
+
+ +
+
+
+

Branch Sales Analysis Report

+

You can see sales analysis report based on branch.

+ +

Branch on Delivery Order

+

While Quotation get confirmed generated picking(delivery) will have same branch automatically set based on Sales Order.

+ +
+
+
+ +
+
+
+

Branch on Customer Invoices

+

While quotation get confirmed generated picking(delivery) will have same branch automatically set based on Sales Order.

+

When creating manual invoice then log in user's branch will be assigned to the invoice.

+ +
+
+
+ +
+
+
+

Branch On Journal Items

+

While invoice created the branch will automatically set on journal items from invoice.

+ +
+
+
+ +
+
+
+

Branch On Customer Payment

+

Selected branch of the invoice will automatically set on account payment.

+ +
+
+
+ +
+
+
+

Branch On Bank Statement

+

User can also see branch on bank statement generated for payment.

+ +
+
+
+ +
+
+
+

Branch On Purchase Order

+

While creating purchase order user who is currently login, branch of the user is set as branch to the purchase order.

+ +
+
+
+ +
+
+
+

User can see created records of purchase order group by branch as shown bellow image.

+ +

Branch Purchase Analysis Report

+

You can see purchase analysis report based on branch.

+ +
+
+
+ +
+
+
+

Branch on Picking

+

While RFQ(purchase) get confirmed generated picking(shipment) will have same branch automatically set based on RFQ.

+ +
+
+
+ + +
+
+
+

Branch On Vendor Bill

+

While bill created from the purchase order selected branch of the purchase order will automatically set on vendor bill.

+

After Validate invoice, Selected branch of the invoice will automatically set on Journal Items.

+ +
+
+
+ +
+
+
+

Branch On Vendor Payment

+

Selected branch of the invoice will automatically set on Account Payment.

+ +
+
+
+ +
+
+
+

Branch On Warehouse

+

You can also define branch in the warehouse and all the technical fields are set according to the branch.

+ +

Branch On Stock Locations

+

In warehouse locations you can also set branch.

+ +
+
+
+ +
+
+
+

Branch On Inventory Valuation

+

User also can set branch on inventory valuations.

+ +
+
+
+ +
+
+
+
+

Apps May You Like

+
+
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+
+
+ +
+
+
+
+

Most Demanded Apps

+
+
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+
+
+ +
+
+
+

Free Support

+

You will get 90 Days free support incase any bugs or issue (Except data recovery).

+

+ At BrowseInfo we offer end to end solution for Odoo services. Which includes analysis & consultation on the workflows and integration part. Please note that You're not allowed to distribute this module after purchase! Incase of any question regarding this module feel free to email us on ticket@browseinfo.in or raise a ticket on support. +

+
+
+
+ +
+
+
+
+ + + +
+
+ +
+
\ No newline at end of file diff --git a/odex30_base/branch/static/description/languages/Arabic.png b/odex30_base/branch/static/description/languages/Arabic.png new file mode 100644 index 0000000..d82390d Binary files /dev/null and b/odex30_base/branch/static/description/languages/Arabic.png differ diff --git a/odex30_base/branch/static/description/languages/Dutch.png b/odex30_base/branch/static/description/languages/Dutch.png new file mode 100644 index 0000000..b550f77 Binary files /dev/null and b/odex30_base/branch/static/description/languages/Dutch.png differ diff --git a/odex30_base/branch/static/description/languages/English.png b/odex30_base/branch/static/description/languages/English.png new file mode 100644 index 0000000..65d8adc Binary files /dev/null and b/odex30_base/branch/static/description/languages/English.png differ diff --git a/odex30_base/branch/static/description/languages/French.png b/odex30_base/branch/static/description/languages/French.png new file mode 100644 index 0000000..0359a67 Binary files /dev/null and b/odex30_base/branch/static/description/languages/French.png differ diff --git a/odex30_base/branch/static/description/languages/Spanish.png b/odex30_base/branch/static/description/languages/Spanish.png new file mode 100644 index 0000000..2899c0b Binary files /dev/null and b/odex30_base/branch/static/description/languages/Spanish.png differ diff --git a/odex30_base/branch/static/description/related/bi_add_custom_field_project.png b/odex30_base/branch/static/description/related/bi_add_custom_field_project.png new file mode 100644 index 0000000..0c57edf Binary files /dev/null and b/odex30_base/branch/static/description/related/bi_add_custom_field_project.png differ diff --git a/odex30_base/branch/static/description/related/bi_automated_sale_order.png b/odex30_base/branch/static/description/related/bi_automated_sale_order.png new file mode 100644 index 0000000..43b47a7 Binary files /dev/null and b/odex30_base/branch/static/description/related/bi_automated_sale_order.png differ diff --git a/odex30_base/branch/static/description/related/bi_discount_from_customer.png b/odex30_base/branch/static/description/related/bi_discount_from_customer.png new file mode 100644 index 0000000..6cca3e8 Binary files /dev/null and b/odex30_base/branch/static/description/related/bi_discount_from_customer.png differ diff --git a/odex30_base/branch/static/description/related/bi_purchase_tripple_approval.png b/odex30_base/branch/static/description/related/bi_purchase_tripple_approval.png new file mode 100644 index 0000000..b6d18ed Binary files /dev/null and b/odex30_base/branch/static/description/related/bi_purchase_tripple_approval.png differ diff --git a/odex30_base/branch/static/description/related/bi_top_growing_product.png b/odex30_base/branch/static/description/related/bi_top_growing_product.png new file mode 100644 index 0000000..778a1b0 Binary files /dev/null and b/odex30_base/branch/static/description/related/bi_top_growing_product.png differ diff --git a/odex30_base/branch/static/description/related/sale_purchase_invoice_discount.png b/odex30_base/branch/static/description/related/sale_purchase_invoice_discount.png new file mode 100644 index 0000000..f4cc4c3 Binary files /dev/null and b/odex30_base/branch/static/description/related/sale_purchase_invoice_discount.png differ diff --git a/odex30_base/branch/static/src/js/abstract_web_client.js b/odex30_base/branch/static/src/js/abstract_web_client.js new file mode 100644 index 0000000..1a70aa5 --- /dev/null +++ b/odex30_base/branch/static/src/js/abstract_web_client.js @@ -0,0 +1,76 @@ +import { browser } from "@web/core/browser/browser"; +import { cookie } from "@web/core/browser/cookie"; +import { router } from "@web/core/browser/router"; +import { registry } from "@web/core/registry"; +import { session } from "@web/session"; + +/** + * Branch Context Service + * Handles branch initialization and context management for the web client + */ + +function parseBranchIds(bids, separator = ",") { + if (typeof bids === "string") { + return bids.split(separator).map(Number); + } else if (typeof bids === "number") { + return [bids]; + } + return []; +} + +function getBranchIds() { + let bids; + const state = router.current; + if ("bids" in state) { + bids = parseBranchIds(state.bids); + } else { + bids = parseBranchIds(cookie.get("bids")); + } + return bids; +} + +function computeActiveBranchIds(bids) { + const { user_branches } = session; + let activeBranchIds = bids || []; + const availableBranchesFromSession = user_branches?.allowed_branch || []; + const notAllowedBranches = activeBranchIds.filter( + (id) => !availableBranchesFromSession.some(branch => branch[0] === id) + ); + + if (!activeBranchIds.length || notAllowedBranches.length) { + activeBranchIds = [user_branches?.current_branch?.[0] || 1]; + } + return activeBranchIds; +} + +export const branchContextService = { + dependencies: ["router"], + + start(env, { router }) { + // Initialize branch context on startup + const branchIds = getBranchIds(); + const activeBranchIds = computeActiveBranchIds(branchIds); + + // Update session context + if (session.user_context) { + session.user_context.allowed_branch_ids = activeBranchIds; + } + + // Update router state if needed + const currentState = router.current; + if (!currentState.bids || activeBranchIds.join(",") !== currentState.bids) { + router.replaceState({ bids: activeBranchIds.join(",") }); + } + + // Update cookie + cookie.set("bids", activeBranchIds.join(",")); + + return { + getBranchIds, + computeActiveBranchIds, + activeBranchIds, + }; + }, +}; + +registry.category("services").add("branchContext", branchContextService); diff --git a/odex30_base/branch/static/src/js/default_branch.js b/odex30_base/branch/static/src/js/default_branch.js new file mode 100644 index 0000000..c6e5c60 --- /dev/null +++ b/odex30_base/branch/static/src/js/default_branch.js @@ -0,0 +1,87 @@ +import { Component, useState } from "@odoo/owl"; +import { registry } from "@web/core/registry"; +import { useService } from "@web/core/utils/hooks"; +import { session } from "@web/session"; +import { jsonrpc } from "@web/core/network/rpc_service"; +import { _t } from "@web/core/l10n/translation"; +import { device } from "@web/core/browser/feature_detection"; + +/** + * When Odoo is configured in multi-branch mode, users should be able + * to switch their interface from one branch to the other. This is the purpose + * of this component, by displaying a dropdown menu in the systray. + */ + +class SwitchBranchMenu extends Component { + static template = "branch.SwitchBranchMenu"; + static props = {}; + + setup() { + this.branchService = useService("branch"); + this.isMobile = device.isMobile; + + this.state = useState({ + allowed_branch_ids: session.user_context.allowed_branch_ids || [], + user_branches: session.user_branches?.allowed_branch || [], + current_branch: null, + current_branch_name: "", + }); + + this._initializeBranchData(); + } + + _initializeBranchData() { + this.state.current_branch = this.state.allowed_branch_ids[0]; + + if (this.state.user_branches.length > 0) { + const currentBranch = this.state.user_branches.find( + branch => branch[0] === this.state.current_branch + ); + this.state.current_branch_name = currentBranch + ? currentBranch[1] + : this.state.user_branches[0][1]; + } + } + + /** + * @private + * @param {Event} ev + */ + async _onSwitchBranchClick(ev) { + ev.preventDefault(); + ev.stopPropagation(); + + const branchID = parseInt(ev.currentTarget.dataset.branchId); + let allowed_branch_ids = [...this.state.allowed_branch_ids]; + + // Handle branch selection logic + if (ev.currentTarget.querySelector('.fa-square-o')) { + if (this.state.allowed_branch_ids.length === 1) { + // Single branch mode + allowed_branch_ids = [branchID]; + } else { + // Multi branch mode + allowed_branch_ids.push(branchID); + } + } + + // Update session + this.branchService.setBranch(branchID, allowed_branch_ids); + + // Send RPC call + await jsonrpc('/set_brnach', { + BranchID: branchID, + }); + } + + get displaySwitchBranchMenu() { + return session.display_switch_branch_menu; + } +} + +export const switchBranchMenu = { + Component: SwitchBranchMenu, + condition: () => session.display_switch_branch_menu, +}; + +registry.category("systray").add("SwitchBranchMenu", switchBranchMenu, { sequence: 50 }); \ No newline at end of file diff --git a/odex30_base/branch/static/src/js/session.js b/odex30_base/branch/static/src/js/session.js new file mode 100644 index 0000000..4088b9f --- /dev/null +++ b/odex30_base/branch/static/src/js/session.js @@ -0,0 +1,61 @@ +import { browser } from "@web/core/browser/browser"; +import { cookie } from "@web/core/browser/cookie"; +import { router } from "@web/core/browser/router"; +import { registry } from "@web/core/registry"; +import { session } from "@web/session"; + +const BIDS_SEPARATOR = ","; + +function parseBranchIds(bids, separator = BIDS_SEPARATOR) { + if (typeof bids === "string") { + return bids.split(separator).map(Number); + } else if (typeof bids === "number") { + return [bids]; + } + return []; +} + +function computeActiveBranchIds(bids) { + const { user_branches } = session; + let activeBranchIds = bids || []; + const availableBranchesFromSession = user_branches?.allowed_branch || {}; + const notAllowedBranches = activeBranchIds.filter( + (id) => !(id in availableBranchesFromSession) + ); + + if (!activeBranchIds.length || notAllowedBranches.length) { + activeBranchIds = [user_branches?.current_branch || 1]; + } + return activeBranchIds; +} + +export const branchService = { + dependencies: ["router"], + + start(env, { router }) { + const setBranch = (main_branch_id, branch_ids) => { + const sortedBids = branch_ids.sort((a, b) => { + if (a === main_branch_id) { + return -1; + } else if (b === main_branch_id) { + return 1; + } else { + return a - b; + } + }); + + const bidsString = sortedBids.join(BIDS_SEPARATOR); + cookie.set("bids", bidsString || String(main_branch_id)); + router.pushState({ bids: bidsString }); + browser.location.reload(); + }; + + return { + setBranch, + parseBranchIds, + computeActiveBranchIds, + }; + }, +}; + +registry.category("services").add("branch", branchService); diff --git a/odex30_base/branch/static/src/xml/branch.xml b/odex30_base/branch/static/src/xml/branch.xml new file mode 100644 index 0000000..de53e50 --- /dev/null +++ b/odex30_base/branch/static/src/xml/branch.xml @@ -0,0 +1,42 @@ + + + +
  • + + +
  • +
    +
    diff --git a/odex30_base/branch/views/branch_template.xml b/odex30_base/branch/views/branch_template.xml new file mode 100644 index 0000000..edec293 --- /dev/null +++ b/odex30_base/branch/views/branch_template.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/odex30_base/branch/views/inherited_account_bank_statement.xml b/odex30_base/branch/views/inherited_account_bank_statement.xml new file mode 100644 index 0000000..4bd5c38 --- /dev/null +++ b/odex30_base/branch/views/inherited_account_bank_statement.xml @@ -0,0 +1,25 @@ + + + + + view.bank.statement.form.inherit.branch + account.bank.statement + + + + + + + + + + + + + {'branch_id' : branch_id} + + + + + + diff --git a/odex30_base/branch/views/inherited_account_invoice.xml b/odex30_base/branch/views/inherited_account_invoice.xml new file mode 100644 index 0000000..8610e1e --- /dev/null +++ b/odex30_base/branch/views/inherited_account_invoice.xml @@ -0,0 +1,107 @@ + + + + + + account.move.inherit.tree + account.move + + + + + + + + + + account.move.inherit.tree1 + account.move + + + + + + + + + + account.payment.inherit.tree + account.payment + + + + + + + + + + account.move.line.inherit.form + account.move.line + + + + + + + + + + account.move.line.inherit.tree2 + account.move.line + + + + + + + + + + + view.move.form.inherit.branch + account.move + + + + + + + + + + + + + view.move.line.tree.inherit.branch + account.move.line + + + + + + + + + + move.line.filter.inherit.branch + account.move.line + + + + + + + + + + diff --git a/odex30_base/branch/views/inherited_partner.xml b/odex30_base/branch/views/inherited_partner.xml new file mode 100644 index 0000000..4e4eff0 --- /dev/null +++ b/odex30_base/branch/views/inherited_partner.xml @@ -0,0 +1,13 @@ + + + + view_partner_structured_form + res.partner + + + + + + + + \ No newline at end of file diff --git a/odex30_base/branch/views/inherited_product.xml b/odex30_base/branch/views/inherited_product.xml new file mode 100644 index 0000000..8f42537 --- /dev/null +++ b/odex30_base/branch/views/inherited_product.xml @@ -0,0 +1,25 @@ + + + + product_extended.product.form.branch + product.template + + + + + + + + + + product.product.view.form.branch + product.product + + + + + + + + + diff --git a/odex30_base/branch/views/inherited_purchase_order.xml b/odex30_base/branch/views/inherited_purchase_order.xml new file mode 100644 index 0000000..d7b1ce9 --- /dev/null +++ b/odex30_base/branch/views/inherited_purchase_order.xml @@ -0,0 +1,52 @@ + + + + + purchase.order.form.inherit.branch + purchase.order + + + + + + + {'branch_id' : branch_id} + + + + + + view.purchase.order.filter.inherit.branch + purchase.order + + + + + + + + + + purchase.order.inherit.tree + purchase.order + + + + + + + + + + + purchase.order.inherit.tree1 + purchase.order + + + + + + + + + \ No newline at end of file diff --git a/odex30_base/branch/views/inherited_res_users.xml b/odex30_base/branch/views/inherited_res_users.xml new file mode 100644 index 0000000..d63a310 --- /dev/null +++ b/odex30_base/branch/views/inherited_res_users.xml @@ -0,0 +1,33 @@ + + + + + + view.users.form.inherit.branch + res.users + + + + + + + + + + + + + + + + res.user.preference.form.extended + res.users + + + + + + + + + diff --git a/odex30_base/branch/views/inherited_sale_order.xml b/odex30_base/branch/views/inherited_sale_order.xml new file mode 100644 index 0000000..56fe6d1 --- /dev/null +++ b/odex30_base/branch/views/inherited_sale_order.xml @@ -0,0 +1,55 @@ + + + + + + view.order.form.inherit.branch + sale.order + + + + + + + + + + + + + + + + view.sales.order.filter.inherit.branch + sale.order + + + + + + + + + + sale.order.inherit.tree + sale.order + + + + + + + + + + sale.order.inherit.tree1 + sale.order + + + + + + + + + \ No newline at end of file diff --git a/odex30_base/branch/views/inherited_stock_inventory.xml b/odex30_base/branch/views/inherited_stock_inventory.xml new file mode 100644 index 0000000..7af7e10 --- /dev/null +++ b/odex30_base/branch/views/inherited_stock_inventory.xml @@ -0,0 +1,15 @@ + + + + + view.stock.inventory.adjustment.form.inherit.branch + stock.inventory.adjustment.name + + + + + + + + + diff --git a/odex30_base/branch/views/inherited_stock_location.xml b/odex30_base/branch/views/inherited_stock_location.xml new file mode 100644 index 0000000..2d9df9b --- /dev/null +++ b/odex30_base/branch/views/inherited_stock_location.xml @@ -0,0 +1,15 @@ + + + + + view.location.form.inherit.branch + stock.location + + + + + + + + + \ No newline at end of file diff --git a/odex30_base/branch/views/inherited_stock_move.xml b/odex30_base/branch/views/inherited_stock_move.xml new file mode 100644 index 0000000..e7038e7 --- /dev/null +++ b/odex30_base/branch/views/inherited_stock_move.xml @@ -0,0 +1,16 @@ + + + + + + view.move.form.inherit.branch + stock.move + + + + + + + + + \ No newline at end of file diff --git a/odex30_base/branch/views/inherited_stock_picking.xml b/odex30_base/branch/views/inherited_stock_picking.xml new file mode 100644 index 0000000..1a69385 --- /dev/null +++ b/odex30_base/branch/views/inherited_stock_picking.xml @@ -0,0 +1,18 @@ + + + + + + view.picking.form.inherit.branch + stock.picking + + + + + + + + + + \ No newline at end of file diff --git a/odex30_base/branch/views/inherited_stock_warehouse.xml b/odex30_base/branch/views/inherited_stock_warehouse.xml new file mode 100644 index 0000000..6bb83d3 --- /dev/null +++ b/odex30_base/branch/views/inherited_stock_warehouse.xml @@ -0,0 +1,26 @@ + + + + + view.warehouse.inherit.branch + stock.warehouse + + + + + + + + + + view.stock.picking.type.inherit.branch + stock.picking.type + + + + + + + + + \ No newline at end of file diff --git a/odex30_base/branch/views/res_branch_view.xml b/odex30_base/branch/views/res_branch_view.xml new file mode 100644 index 0000000..74b0186 --- /dev/null +++ b/odex30_base/branch/views/res_branch_view.xml @@ -0,0 +1,56 @@ + + + + + + + branch.res.branch.view.form + res.branch + +
    + + + + + + + + + + + + +
    +
    +
    + + + + branch.res.branch.view.tree + res.branch + + + + + + + + + + + Branch + ir.actions.act_window + res.branch + list,form + +

    + Click here to create a new branch. +

    +
    +
    + + + + +
    +
    diff --git a/odex30_base/branch/wizard/__init__.py b/odex30_base/branch/wizard/__init__.py new file mode 100644 index 0000000..46068eb --- /dev/null +++ b/odex30_base/branch/wizard/__init__.py @@ -0,0 +1,5 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from . import inherited_sale_advance_payment_inv + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/odex30_base/branch/wizard/inherited_account_payment.xml b/odex30_base/branch/wizard/inherited_account_payment.xml new file mode 100644 index 0000000..bbea15b --- /dev/null +++ b/odex30_base/branch/wizard/inherited_account_payment.xml @@ -0,0 +1,41 @@ + + + + + + + view.account.payment.invoice.form.inherit.branch + account.payment + + + + + + + + + + + + view.account.payment.register.form.inherit.branch + account.payment.register + + + + + + + + + + \ No newline at end of file diff --git a/odex30_base/branch/wizard/inherited_sale_advance_payment_inv.py b/odex30_base/branch/wizard/inherited_sale_advance_payment_inv.py new file mode 100644 index 0000000..2ddd9e0 --- /dev/null +++ b/odex30_base/branch/wizard/inherited_sale_advance_payment_inv.py @@ -0,0 +1,47 @@ +# Part of BrowseInfo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError + + +class SaleAdvancePaymentInv(models.TransientModel): + _inherit = 'sale.advance.payment.inv' + + + def _create_invoice(self, order, so_line, amount): + result = super(SaleAdvancePaymentInv, self)._create_invoice(order, so_line, amount) + + branch_id = False + + if order.branch_id: + branch_id = order.branch_id.id + elif self.env.user.branch_id: + branch_id = self.env.user.branch_id.id + + result.write({ + 'branch_id' : branch_id + }) + + return result + +class AccountPaymentRegisterInv(models.TransientModel): + _inherit = 'account.payment.register' + + @api.model + def default_get(self, fields): + rec = super(AccountPaymentRegisterInv, self).default_get(fields) + invoice_defaults = self.env['account.move'].browse(self._context.get('active_ids', [])) + if invoice_defaults and len(invoice_defaults) == 1: + rec['branch_id'] = invoice_defaults.branch_id.id + return rec + + branch_id = fields.Many2one('res.branch') + + @api.onchange('branch_id') + def _onchange_branch_id(self): + selected_brach = self.branch_id + if selected_brach: + user_id = self.env.user + user_branch = user_id.sudo().branch_id + if user_branch and user_branch.id != selected_brach.id: + raise UserError("Please select active branch only. Other may create the Multi branch issue. \n\ne.g: If you wish to add other branch then Switch branch from the header and set that.") \ No newline at end of file diff --git a/odex30_base/cron_failure_notification/README.rst b/odex30_base/cron_failure_notification/README.rst new file mode 100755 index 0000000..48acf2e --- /dev/null +++ b/odex30_base/cron_failure_notification/README.rst @@ -0,0 +1,44 @@ +.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +Cron Failure Notification +========================= +* Notify the Admin About Cron Failures Via Mail. + +Configuration +============ +- Install our custom addon + +Company +------- +* `Cybrosys Techno Solutions `__ + +License +------- +General Public License, Version 3 (AGPL V3). +(http://www.gnu.org/licenses/agpl-3.0-standalone.html) + +Credits +------- +Developer: (V18) Muhammed Rishad, Contact: odoo@cybrosys.com + +Contacts +-------- +* Mail Contact : odoo@cybrosys.com + +Bug Tracker +----------- +Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. + +Maintainer +========== +.. image:: https://cybrosys.com/images/logo.png + :target: https://cybrosys.com +This module is maintained by Cybrosys Technologies. + +For support and more information, please visit https://www.cybrosys.com + +Further information +=================== +HTML Description: ``__ diff --git a/odex30_base/cron_failure_notification/__init__.py b/odex30_base/cron_failure_notification/__init__.py new file mode 100755 index 0000000..b971770 --- /dev/null +++ b/odex30_base/cron_failure_notification/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +################################################################################ +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2025-TODAY Cybrosys Technologies( +# ). +# Author: MUHAMMED RISHAD (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# 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 (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +################################################################################ +from . import models diff --git a/odex30_base/cron_failure_notification/__manifest__.py b/odex30_base/cron_failure_notification/__manifest__.py new file mode 100755 index 0000000..b3c47f1 --- /dev/null +++ b/odex30_base/cron_failure_notification/__manifest__.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +################################################################################ +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2025-TODAY Cybrosys Technologies( +# ). +# Author: MUHAMMED RISHAD (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# 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 (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +################################################################################ +{ + 'name': "Cron Failure Notification", + 'version': '18.0.1.0.1', + 'category': 'Discuss', + 'summary': 'Notify the Admin About Cron Failures Via Mail', + 'description': """This module helps to send notification to admin with + lists of failed scheduled actions.""", + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'maintainer': 'Cybrosys Techno Solutions', + 'website': 'https://www.cybrosys.com', + 'depends': ['base', 'mail'], + 'data': ['security/ir.model.access.csv', + 'report/ir_cron_failure_templates.xml', + 'report/ir_cron_reports.xml', + 'data/failure_mail_data.xml', + 'data/mail_template_data.xml', + 'views/ir_cron_views.xml', + 'views/failure_history_views.xml'], + 'images': ['static/description/banner.png'], + 'license': 'AGPL-3', + 'installable': True, + 'auto_install': False, + 'application': False, +} diff --git a/odex30_base/cron_failure_notification/data/failure_mail_data.xml b/odex30_base/cron_failure_notification/data/failure_mail_data.xml new file mode 100755 index 0000000..2afd6bf --- /dev/null +++ b/odex30_base/cron_failure_notification/data/failure_mail_data.xml @@ -0,0 +1,15 @@ + + + + + + Mail: Cron Error Notification + + code + model.mail_send_cron() + + 1 + days + + + diff --git a/odex30_base/cron_failure_notification/data/mail_template_data.xml b/odex30_base/cron_failure_notification/data/mail_template_data.xml new file mode 100755 index 0000000..73bf9a5 --- /dev/null +++ b/odex30_base/cron_failure_notification/data/mail_template_data.xml @@ -0,0 +1,19 @@ + + + + + + Mail: Cron Action Error23 + + {{ object.name }} Cron Failed + + +

    Dear Admin,

    +

    Here is attaching failures from scheduled cron jobs on our + server, so please quickly take an action for this. +

    +

    Thank You.

    +
    +
    +
    +
    diff --git a/odex30_base/cron_failure_notification/doc/RELEASE_NOTES.md b/odex30_base/cron_failure_notification/doc/RELEASE_NOTES.md new file mode 100755 index 0000000..54f6b8c --- /dev/null +++ b/odex30_base/cron_failure_notification/doc/RELEASE_NOTES.md @@ -0,0 +1,13 @@ +## Module + +#### 19.02.2025 +#### Version 18.0.1.0.0 +#### ADD + +- Initial commit for Cron Failure Notification + +#### 19.02.2025 +#### Version 18.0.1.0.1 +#### UPDT + +- Updated the python logic how system administrators mail's are fetched in function mail_send_cron. diff --git a/odex30_base/cron_failure_notification/models/__init__.py b/odex30_base/cron_failure_notification/models/__init__.py new file mode 100755 index 0000000..8ae975f --- /dev/null +++ b/odex30_base/cron_failure_notification/models/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2025-TODAY Cybrosys Technologies( +# ). +# Author: MUHAMMED RISHAD (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# 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 (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################## +from . import failure_history +from . import ir_cron diff --git a/odex30_base/cron_failure_notification/models/failure_history.py b/odex30_base/cron_failure_notification/models/failure_history.py new file mode 100755 index 0000000..5216d2e --- /dev/null +++ b/odex30_base/cron_failure_notification/models/failure_history.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2025-TODAY Cybrosys Technologies( +# ). +# Author: MUHAMMED RISHAD (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# 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 (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################## +from odoo import fields, models + + +class FailureHistory(models.Model): + """Creates failure history to store the failed cron action details + as a record""" + _name = 'failure.history' + _inherit = ['mail.thread', 'mail.activity.mixin'] + _description = 'Failure History' + + name = fields.Char(string='Name', required=True, help="Failed cron action " + "name") + error = fields.Char(string='Error Details', help="Detailed description " + "about error") diff --git a/odex30_base/cron_failure_notification/models/ir_cron.py b/odex30_base/cron_failure_notification/models/ir_cron.py new file mode 100755 index 0000000..4805bb1 --- /dev/null +++ b/odex30_base/cron_failure_notification/models/ir_cron.py @@ -0,0 +1,116 @@ +# -*- coding: utf-8 -*- +# ############################################################################ +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2025-TODAY Cybrosys Technologies( +# ). +# Author: MUHAMMED RISHAD (odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# 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 (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################## +import base64 +import datetime +import logging +import time +from odoo import models, _ +from odoo.exceptions import ValidationError +from odoo.fields import _logger + + +class IrCron(models.Model): + """ Inherits ir cron for add a feature that sends mail to admin + each day, if any cron failed """ + _name = 'ir.cron' + _inherit = ['ir.cron', 'mail.thread'] + + + def _callback(self, cron_name, server_action_id): + """ Run the method associated to a given job. It takes care of logging + and exception handling. Note that the user running the server action + is the user calling this method. """ + self.ensure_one() + try: + if self.pool != self.pool.check_signaling(): + # the registry has changed, reload self in the new registry + self.env.reset() + self = self.env()[self._name] + + _logger.debug( + "cron.object.execute(%r, %d, '*', %r, %d)", + self.env.cr.dbname, + self._uid, + cron_name, + server_action_id, + ) + _logger.info('Job %r (%s) starting', cron_name, self.id) + start_time = time.time() + self.env['ir.actions.server'].browse(server_action_id).run() + self.env.flush_all() + end_time = time.time() + _logger.info('Job %r (%s) done in %.3fs', cron_name, self.id, + end_time - start_time) + if start_time and _logger.isEnabledFor(logging.DEBUG): + _logger.debug('Job %r (%s) server action #%s with uid %s ' + 'executed in %.3fs', + cron_name, self.id, server_action_id, + self.env.uid, end_time - start_time) + self.pool.signal_changes() + except Exception as exception: + self.pool.reset_changes() + _logger.exception('Job %r (%s) server action #%s failed', + cron_name, self.id, server_action_id) + if exception: + self.env['failure.history'].create({ + 'name': cron_name, + 'error': str(exception), + }) + raise ValidationError(_(str(exception))) + + def mail_send_cron(self): + """ If any cron's failed a notification email will send to admin """ + current_datetime = datetime.datetime.now() + yesterday_datetime = current_datetime - datetime.timedelta(days=1) + failure = self.env['failure.history'].search( + [('create_date', '>', yesterday_datetime), + ('create_date', '<', current_datetime)] + ) + if failure: + admin_mail = self.env.ref('base.group_erp_manager').users.mapped('login') + email_values = { + 'email_to': admin_mail[0] if len(admin_mail) == 1 + else ",".join(admin_mail) + } + + report_template_id = self.env['ir.actions.report']._render_qweb_pdf( + report_ref='cron_failure_notification.cron_fail_pdf_report', + res_ids=False, + ) + data_record = base64.b64encode(report_template_id[0]) + ir_values = { + 'name': "Scheduled Cron Job Failed Attachment.pdf", + 'type': 'binary', + 'datas': data_record, + 'store_fname': data_record, + 'mimetype': 'application/x-pdf', + } + data_id = self.env['ir.attachment'].create(ir_values) + + mail_template = self.env.ref( + 'cron_failure_notification.mail_template_cron_error') + mail_template.attachment_ids = [(6, 0, [data_id.id])] + mail_template.send_mail(self.id, email_values= email_values, + force_send=True) + mail_template.attachment_ids = [(3, data_id.id)] + return diff --git a/odex30_base/cron_failure_notification/report/ir_cron_failure_templates.xml b/odex30_base/cron_failure_notification/report/ir_cron_failure_templates.xml new file mode 100755 index 0000000..8f81742 --- /dev/null +++ b/odex30_base/cron_failure_notification/report/ir_cron_failure_templates.xml @@ -0,0 +1,50 @@ + + + + + diff --git a/odex30_base/cron_failure_notification/report/ir_cron_reports.xml b/odex30_base/cron_failure_notification/report/ir_cron_reports.xml new file mode 100755 index 0000000..abaf220 --- /dev/null +++ b/odex30_base/cron_failure_notification/report/ir_cron_reports.xml @@ -0,0 +1,13 @@ + + + + + Cron failure report + ir.cron + qweb-pdf + cron_failure_notification.report_logs_details + cron_failure_notification.report_logs_details + + report + + diff --git a/odex30_base/cron_failure_notification/security/ir.model.access.csv b/odex30_base/cron_failure_notification/security/ir.model.access.csv new file mode 100755 index 0000000..daeca37 --- /dev/null +++ b/odex30_base/cron_failure_notification/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_failure_history,access.failure.history,model_failure_history,base.group_user,1,1,1,1 diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/arrows-repeat.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/arrows-repeat.svg new file mode 100644 index 0000000..1d7efab --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/arrows-repeat.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/banner-1.png b/odex30_base/cron_failure_notification/static/description/assets/icons/banner-1.png new file mode 100644 index 0000000..c180db1 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/banner-1.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/banner-2.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/banner-2.svg new file mode 100644 index 0000000..e606d97 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/banner-2.svg @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/banner-bg.png b/odex30_base/cron_failure_notification/static/description/assets/icons/banner-bg.png new file mode 100644 index 0000000..a8238d3 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/banner-bg.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/banner-bg.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/banner-bg.svg new file mode 100644 index 0000000..b137810 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/banner-bg.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/banner-call.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/banner-call.svg new file mode 100644 index 0000000..96c687e --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/banner-call.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/banner-mail.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/banner-mail.svg new file mode 100644 index 0000000..cbf0d15 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/banner-mail.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/banner-pattern.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/banner-pattern.svg new file mode 100644 index 0000000..9c1c7e1 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/banner-pattern.svg @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/banner-promo.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/banner-promo.svg new file mode 100644 index 0000000..d52791b --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/banner-promo.svg @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/brand-pair.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/brand-pair.svg new file mode 100644 index 0000000..d8db7fc --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/brand-pair.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/check.png b/odex30_base/cron_failure_notification/static/description/assets/icons/check.png new file mode 100644 index 0000000..c8e85f5 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/check.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/chevron.png b/odex30_base/cron_failure_notification/static/description/assets/icons/chevron.png new file mode 100644 index 0000000..2089293 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/chevron.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/close-icon.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/close-icon.svg new file mode 100644 index 0000000..df8cce3 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/close-icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/cogs.png b/odex30_base/cron_failure_notification/static/description/assets/icons/cogs.png new file mode 100644 index 0000000..95d0bad Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/cogs.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/collabarate-icon.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/collabarate-icon.svg new file mode 100644 index 0000000..dd4e105 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/collabarate-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/consultation.png b/odex30_base/cron_failure_notification/static/description/assets/icons/consultation.png new file mode 100644 index 0000000..8319d4b Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/consultation.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/cybro-logo.png b/odex30_base/cron_failure_notification/static/description/assets/icons/cybro-logo.png new file mode 100644 index 0000000..ff4b782 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/cybro-logo.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/down.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/down.svg new file mode 100644 index 0000000..f21c362 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/ecom-black.png b/odex30_base/cron_failure_notification/static/description/assets/icons/ecom-black.png new file mode 100644 index 0000000..a9385ff Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/ecom-black.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/education-black.png b/odex30_base/cron_failure_notification/static/description/assets/icons/education-black.png new file mode 100644 index 0000000..3eb09b2 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/education-black.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/faq.png b/odex30_base/cron_failure_notification/static/description/assets/icons/faq.png new file mode 100644 index 0000000..4250b5b Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/faq.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/feature-icon.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/feature-icon.svg new file mode 100644 index 0000000..fa0ea68 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/feature-icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/feature.png b/odex30_base/cron_failure_notification/static/description/assets/icons/feature.png new file mode 100644 index 0000000..ac7a785 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/feature.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/gear.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/gear.svg new file mode 100644 index 0000000..0cc66b6 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/gear.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/hire-odoo.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/hire-odoo.svg new file mode 100644 index 0000000..e1ac089 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/hire-odoo.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/hotel-black.png b/odex30_base/cron_failure_notification/static/description/assets/icons/hotel-black.png new file mode 100644 index 0000000..130f613 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/hotel-black.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/license.png b/odex30_base/cron_failure_notification/static/description/assets/icons/license.png new file mode 100644 index 0000000..a586979 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/license.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/life-ring-icon.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/life-ring-icon.svg new file mode 100644 index 0000000..3ae6e1d --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/life-ring-icon.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/lifebuoy.png b/odex30_base/cron_failure_notification/static/description/assets/icons/lifebuoy.png new file mode 100644 index 0000000..658d56c Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/lifebuoy.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/mail.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/mail.svg new file mode 100644 index 0000000..1eedde6 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/mail.svg @@ -0,0 +1,3 @@ + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/manufacturing-black.png b/odex30_base/cron_failure_notification/static/description/assets/icons/manufacturing-black.png new file mode 100644 index 0000000..697eb0e Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/manufacturing-black.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/notes.png b/odex30_base/cron_failure_notification/static/description/assets/icons/notes.png new file mode 100644 index 0000000..ee5e954 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/notes.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/notification icon.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/notification icon.svg new file mode 100644 index 0000000..0531899 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/notification icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/odoo-consultancy.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/odoo-consultancy.svg new file mode 100644 index 0000000..e05f65b --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/odoo-consultancy.svg @@ -0,0 +1,4 @@ + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/odoo-licencing.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/odoo-licencing.svg new file mode 100644 index 0000000..2606c88 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/odoo-licencing.svg @@ -0,0 +1,3 @@ + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/odoo-logo.png b/odex30_base/cron_failure_notification/static/description/assets/icons/odoo-logo.png new file mode 100644 index 0000000..0e4d0eb Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/odoo-logo.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/patter.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/patter.svg new file mode 100644 index 0000000..25c9c0a --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/patter.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/pattern1.png b/odex30_base/cron_failure_notification/static/description/assets/icons/pattern1.png new file mode 100644 index 0000000..09ab0fb Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/pattern1.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/pos-black.png b/odex30_base/cron_failure_notification/static/description/assets/icons/pos-black.png new file mode 100644 index 0000000..97c0f90 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/pos-black.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/puzzle-piece-icon.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/puzzle-piece-icon.svg new file mode 100644 index 0000000..3e9ad93 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/puzzle-piece-icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/puzzle.png b/odex30_base/cron_failure_notification/static/description/assets/icons/puzzle.png new file mode 100644 index 0000000..65cf854 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/puzzle.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/replace-icon.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/replace-icon.svg new file mode 100644 index 0000000..d0e3a7a --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/replace-icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/restaurant-black.png b/odex30_base/cron_failure_notification/static/description/assets/icons/restaurant-black.png new file mode 100644 index 0000000..4a35eb9 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/restaurant-black.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/screenshot-main.png b/odex30_base/cron_failure_notification/static/description/assets/icons/screenshot-main.png new file mode 100644 index 0000000..575f8e6 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/screenshot-main.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/screenshot.png b/odex30_base/cron_failure_notification/static/description/assets/icons/screenshot.png new file mode 100644 index 0000000..cef2725 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/screenshot.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/service-black.png b/odex30_base/cron_failure_notification/static/description/assets/icons/service-black.png new file mode 100644 index 0000000..301ab51 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/service-black.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/skype-fill.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/skype-fill.svg new file mode 100644 index 0000000..c174236 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/skype-fill.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/skype.png b/odex30_base/cron_failure_notification/static/description/assets/icons/skype.png new file mode 100644 index 0000000..51b409f Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/skype.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/skype.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/skype.svg new file mode 100644 index 0000000..df3dad3 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/skype.svg @@ -0,0 +1,3 @@ + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/star-1.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/star-1.svg new file mode 100644 index 0000000..7e55ab1 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/star-1.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/star-2.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/star-2.svg new file mode 100644 index 0000000..5ae9f50 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/star-2.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/support.png b/odex30_base/cron_failure_notification/static/description/assets/icons/support.png new file mode 100644 index 0000000..4f18b8b Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/support.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/test-1 - Copy.png b/odex30_base/cron_failure_notification/static/description/assets/icons/test-1 - Copy.png new file mode 100644 index 0000000..f6a9026 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/test-1 - Copy.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/test-1.png b/odex30_base/cron_failure_notification/static/description/assets/icons/test-1.png new file mode 100644 index 0000000..0908add Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/test-1.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/test-2.png b/odex30_base/cron_failure_notification/static/description/assets/icons/test-2.png new file mode 100644 index 0000000..4671fe9 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/test-2.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/trading-black.png b/odex30_base/cron_failure_notification/static/description/assets/icons/trading-black.png new file mode 100644 index 0000000..9398ba2 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/trading-black.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/training.png b/odex30_base/cron_failure_notification/static/description/assets/icons/training.png new file mode 100644 index 0000000..884ca02 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/training.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/translate.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/translate.svg new file mode 100644 index 0000000..af9c8a1 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/translate.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/update.png b/odex30_base/cron_failure_notification/static/description/assets/icons/update.png new file mode 100644 index 0000000..ecbc5a0 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/update.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/user.png b/odex30_base/cron_failure_notification/static/description/assets/icons/user.png new file mode 100644 index 0000000..6ffb23d Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/user.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/video.png b/odex30_base/cron_failure_notification/static/description/assets/icons/video.png new file mode 100644 index 0000000..576705b Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/video.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/whatsapp.png b/odex30_base/cron_failure_notification/static/description/assets/icons/whatsapp.png new file mode 100644 index 0000000..d513a53 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/whatsapp.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/wrench-icon.svg b/odex30_base/cron_failure_notification/static/description/assets/icons/wrench-icon.svg new file mode 100644 index 0000000..174b5a4 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/icons/wrench-icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/icons/wrench.png b/odex30_base/cron_failure_notification/static/description/assets/icons/wrench.png new file mode 100644 index 0000000..6c04dea Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/icons/wrench.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/Cybrosys R.png b/odex30_base/cron_failure_notification/static/description/assets/misc/Cybrosys R.png new file mode 100644 index 0000000..da40580 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/misc/Cybrosys R.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/categories.png b/odex30_base/cron_failure_notification/static/description/assets/misc/categories.png new file mode 100644 index 0000000..bedf1e0 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/misc/categories.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/check-box.png b/odex30_base/cron_failure_notification/static/description/assets/misc/check-box.png new file mode 100644 index 0000000..42caf24 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/misc/check-box.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/compass.png b/odex30_base/cron_failure_notification/static/description/assets/misc/compass.png new file mode 100644 index 0000000..d5fed8f Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/misc/compass.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/corporate.png b/odex30_base/cron_failure_notification/static/description/assets/misc/corporate.png new file mode 100644 index 0000000..2eb13ed Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/misc/corporate.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/customer-support.png b/odex30_base/cron_failure_notification/static/description/assets/misc/customer-support.png new file mode 100644 index 0000000..79efc72 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/misc/customer-support.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/cybrosys-logo.png b/odex30_base/cron_failure_notification/static/description/assets/misc/cybrosys-logo.png new file mode 100644 index 0000000..cc3cc0c Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/misc/cybrosys-logo.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/email.svg b/odex30_base/cron_failure_notification/static/description/assets/misc/email.svg new file mode 100644 index 0000000..15291cd --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/misc/email.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/features.png b/odex30_base/cron_failure_notification/static/description/assets/misc/features.png new file mode 100644 index 0000000..b41769f Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/misc/features.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/logo.png b/odex30_base/cron_failure_notification/static/description/assets/misc/logo.png new file mode 100644 index 0000000..478462d Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/misc/logo.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/phone.svg b/odex30_base/cron_failure_notification/static/description/assets/misc/phone.svg new file mode 100644 index 0000000..b7bd7f2 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/misc/phone.svg @@ -0,0 +1,3 @@ + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/pictures.png b/odex30_base/cron_failure_notification/static/description/assets/misc/pictures.png new file mode 100644 index 0000000..56d255f Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/misc/pictures.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/pie-chart.png b/odex30_base/cron_failure_notification/static/description/assets/misc/pie-chart.png new file mode 100644 index 0000000..426e052 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/misc/pie-chart.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/right-arrow.png b/odex30_base/cron_failure_notification/static/description/assets/misc/right-arrow.png new file mode 100644 index 0000000..730984a Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/misc/right-arrow.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/star (1) 2.svg b/odex30_base/cron_failure_notification/static/description/assets/misc/star (1) 2.svg new file mode 100644 index 0000000..5ae9f50 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/misc/star (1) 2.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/star.png b/odex30_base/cron_failure_notification/static/description/assets/misc/star.png new file mode 100644 index 0000000..2eb9ab2 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/misc/star.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/support (1) 1.svg b/odex30_base/cron_failure_notification/static/description/assets/misc/support (1) 1.svg new file mode 100644 index 0000000..7d37a8f --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/misc/support (1) 1.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/support-email.svg b/odex30_base/cron_failure_notification/static/description/assets/misc/support-email.svg new file mode 100644 index 0000000..eb70370 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/misc/support-email.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/support.png b/odex30_base/cron_failure_notification/static/description/assets/misc/support.png new file mode 100644 index 0000000..4f18b8b Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/misc/support.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/tick-mark.svg b/odex30_base/cron_failure_notification/static/description/assets/misc/tick-mark.svg new file mode 100644 index 0000000..2dbb401 --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/misc/tick-mark.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/whatsapp 1.svg b/odex30_base/cron_failure_notification/static/description/assets/misc/whatsapp 1.svg new file mode 100644 index 0000000..0bfaf8f --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/misc/whatsapp 1.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/whatsapp.png b/odex30_base/cron_failure_notification/static/description/assets/misc/whatsapp.png new file mode 100644 index 0000000..d513a53 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/misc/whatsapp.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/misc/whatsapp.svg b/odex30_base/cron_failure_notification/static/description/assets/misc/whatsapp.svg new file mode 100644 index 0000000..b618aea --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/assets/misc/whatsapp.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/odex30_base/cron_failure_notification/static/description/assets/modules/k1.png b/odex30_base/cron_failure_notification/static/description/assets/modules/k1.png new file mode 100644 index 0000000..3a68fe8 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/modules/k1.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/modules/k2.png b/odex30_base/cron_failure_notification/static/description/assets/modules/k2.png new file mode 100644 index 0000000..251d81b Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/modules/k2.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/modules/k3.png b/odex30_base/cron_failure_notification/static/description/assets/modules/k3.png new file mode 100644 index 0000000..13e4ffc Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/modules/k3.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/modules/k4.png b/odex30_base/cron_failure_notification/static/description/assets/modules/k4.png new file mode 100644 index 0000000..ce5a551 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/modules/k4.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/modules/k5.png b/odex30_base/cron_failure_notification/static/description/assets/modules/k5.png new file mode 100644 index 0000000..f2ed46e Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/modules/k5.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/modules/k6.png b/odex30_base/cron_failure_notification/static/description/assets/modules/k6.png new file mode 100644 index 0000000..d03723c Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/modules/k6.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/screenshots/GIF.gif b/odex30_base/cron_failure_notification/static/description/assets/screenshots/GIF.gif new file mode 100644 index 0000000..e4a7048 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/screenshots/GIF.gif differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/screenshots/ss1.png b/odex30_base/cron_failure_notification/static/description/assets/screenshots/ss1.png new file mode 100644 index 0000000..182fd27 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/screenshots/ss1.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/screenshots/ss2.png b/odex30_base/cron_failure_notification/static/description/assets/screenshots/ss2.png new file mode 100644 index 0000000..f1e4e95 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/screenshots/ss2.png differ diff --git a/odex30_base/cron_failure_notification/static/description/assets/screenshots/ss3.png b/odex30_base/cron_failure_notification/static/description/assets/screenshots/ss3.png new file mode 100644 index 0000000..4093378 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/assets/screenshots/ss3.png differ diff --git a/odex30_base/cron_failure_notification/static/description/banner.png b/odex30_base/cron_failure_notification/static/description/banner.png new file mode 100644 index 0000000..ba5df27 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/banner.png differ diff --git a/odex30_base/cron_failure_notification/static/description/icon.png b/odex30_base/cron_failure_notification/static/description/icon.png new file mode 100644 index 0000000..7f2fb13 Binary files /dev/null and b/odex30_base/cron_failure_notification/static/description/icon.png differ diff --git a/odex30_base/cron_failure_notification/static/description/index.html b/odex30_base/cron_failure_notification/static/description/index.html new file mode 100644 index 0000000..f25b09b --- /dev/null +++ b/odex30_base/cron_failure_notification/static/description/index.html @@ -0,0 +1,976 @@ + + + + + + Cron Failure Notification + + + + + + + + + + +
    +
    + + + +
    +
    + Community +
    +
    + Enterprise +
    +
    + Odoo.sh +
    +
    +
    + +
    +
    +
    +
    +

    + Notify the Admin About Cron Failures Via Mail. +

    +

    Cron Failure Notification +

    +
    +
    + +
    + +
    + +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +

    Key + Highlights

    +
    +
    +
    +
    + +
    +
    + Failure History +
    +

    + Creates a failure history log for cron jobs that have failed.

    +
    +
    +
    +
    +
    + +
    +
    + Email Notification +
    +

    + Sends email notifications to the admin regarding cron job failures.

    +
    +
    +
    +
    +
    + +
    +
    + PDF Report +
    +

    + Email will include a report detailing the cron job failures as an attachment.

    +
    +
    +
    +
    + +
    +
    +
    + Cron Failure Notification +

    + Are you ready to make your business more + organized? +
    Improve now! +

    + +
    +
    + +
    +
    +
    + + + + +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +

    + Scheduled + + Email +

    +
    +
    +

    + A Cron action that sends the failed cron job history via email to the admin. +

    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    + Failure + + History +

    +
    +
    +

    + Access to the views of the stored failure history records. +

    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    + Failure + + Report +

    +
    +
    +

    + A PDF report displaying the details of various failed cron jobs throughout the day. +

    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +

    + Mail Notification

    +
    +
    +

    + Mail Notification containing details on failures sent to Admin on daily + basis. +

    +
    +
    +
    +
    +
    +
    +
    + +
    +

    + Failure History

    +
    +
    +

    + Failures that happens in cron, will be recorded as a history. +

    +
    +
    +
    +
    +
    +
    +
    + +
    +

    + Failure Report

    +
    +
    +

    + Creates Pdf Failure report, which is attached with the mail. +

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    + +
    + +
    +

    + The Cron Failure Notification module saves the failed scheduled + actions as history and sends out mail notification to the admin. +

    +
    +
    + +
    + +
    +

    + A scheduled action runs daily to retrieve the failed scheduled + actions history and sends an email if any failures are detected. +

    +
    +
    + +
    + +
    +

    + If you want to stay informed about failed scheduled actions + in your system, this module is for you. +

    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +

    + Latest Release 18.0.1.0.0 +

    + + 6th January, 2025 + +
    +
    +
    +
    +
    + Add +
    +
    +
    +
      +
    • + Initial Commit +
    • + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + +
    +

    + Related Products +

    + +
    + + +
    +

    + Our Services

    + +
    + +
    +
    + .... +
    +
    + +
    + + +
    +
    + + + + + + diff --git a/odex30_base/cron_failure_notification/views/failure_history_views.xml b/odex30_base/cron_failure_notification/views/failure_history_views.xml new file mode 100755 index 0000000..4119c53 --- /dev/null +++ b/odex30_base/cron_failure_notification/views/failure_history_views.xml @@ -0,0 +1,45 @@ + + + + + Failure History + ir.actions.act_window + failure.history + list,form + + + + failure.history.view.tree + failure.history + + + + + + + + + failure.history.view.form + failure.history + +
    + + + + + + + + + + + + + + +
    +
    + + +
    \ No newline at end of file diff --git a/odex30_base/cron_failure_notification/views/ir_cron_views.xml b/odex30_base/cron_failure_notification/views/ir_cron_views.xml new file mode 100755 index 0000000..b53d18c --- /dev/null +++ b/odex30_base/cron_failure_notification/views/ir_cron_views.xml @@ -0,0 +1,14 @@ + + + + + ir.cron.view.form.inherited.failure.notification + ir.cron + + + + + + + + \ No newline at end of file diff --git a/odex30_base/custom_background/COPYRIGHT b/odex30_base/custom_background/COPYRIGHT new file mode 100644 index 0000000..d1ddb51 --- /dev/null +++ b/odex30_base/custom_background/COPYRIGHT @@ -0,0 +1,18 @@ + +Most of the files are + + Copyright (c) 2018 Bizzappdev India + +and published under the Bizzappdev License, +as described in the LICENSE file. + +Some files may also contain contributions from third +parties. In this case the original copyright of +the contributions can be traced through the +history of the source version control system. + +When that is not the case, the files contain a prominent +notice stating the original copyright and applicable +license, or come with their own dedicated COPYRIGHT +and/or LICENSE file. + diff --git a/odex30_base/custom_background/LICENSE b/odex30_base/custom_background/LICENSE new file mode 100644 index 0000000..89cbe4b --- /dev/null +++ b/odex30_base/custom_background/LICENSE @@ -0,0 +1,72 @@ + +For copyright information, please see the COPYRIGHT file. + +This Odoo App is published under the Bizzappdev License v1.0, as included +below. + +******************************************************************************** + +Bizzappdev License v1.0 Copyright (C) 2018 Bizzappdev India + +By purchasing this Odoo App from Bizzappdev India, you agree to the +following: + +This license agreement (hereinafter Agreement) is an agreement +between you (the person or company who is being licensed to use the Software or +Documentation) and Bizzappdev India (hereinafter We/us/our). The +Agreement applies to the Odoo App where this license is added. + +1. By purchasing the Software you acknowledge that you have read this Agreement, +and that you agree to the content of the Agreement and its terms, and agree to +use the Software in compliance with this Agreement. + +2. The Agreement comes into legal force at the moment when you order our +Software from our site, download it from the Odoo App Store, or receive it +through email or on data medium at the our discretion. + +3. We are the copyright holder of the Software. The Software or a portion of it +is a copyrightable matter and is liable to protection by the law. Any activity +that infringes terms of this Agreement violates copyright law and will be +prosecuted according to the current law. We reserve the right to revoke the +license of any user who is holding an invalid license. + +4. This Agreement gives you the right to use only one copy of the Software on +one Odoo installation solely for your own personal or business use, subject to +all other terms of this Agreement. A separate License should be purchased for +each Odoo installation. Any distribution of the Software without our consent, +including noncommercial distribution is regarded as violation of this Agreement +and entails liability, according to the current law. + +5. You may not use any part of the code in whole or part in any other software +or product or website. + +6. You may not give, sell, distribute, sub-license, rent, lease or lend any +portion of the Software or Documentation to anyone. You may not place the +Software on a server so that it is accessible via a public network such as the +Internet for distribution purposes. + +7. You are bound to preserve the copyright information intact. + +8. We reserve the right to publish a selected list of users of our Software. + +9. We are not liable for prosecution arising from use of the Software against +law or for any illegal use. + +10. If you fail to use the Software in accordance with the terms and conditions +of this License Agreement, it constitutes a breach of the agreement, and your +license to use the Software is revoked. + +11. Bizzappdev reserves the right to change this license agreement at any time +and impose its clauses at any given time. + +12. It is allowed to change the +software according to your needs. But only in respect of the terms of this +license. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/odex30_base/custom_background/__init__.py b/odex30_base/custom_background/__init__.py new file mode 100644 index 0000000..09949f0 --- /dev/null +++ b/odex30_base/custom_background/__init__.py @@ -0,0 +1,2 @@ +# See LICENSE file for full copyright and licensing details. +from . import models diff --git a/odex30_base/custom_background/__manifest__.py b/odex30_base/custom_background/__manifest__.py new file mode 100644 index 0000000..8510bf2 --- /dev/null +++ b/odex30_base/custom_background/__manifest__.py @@ -0,0 +1,19 @@ +{ + "name": "Custom Background", + "version": "18.0.1.0.0", + "author": "BizzAppDev", + "website": "http://www.bizzappdev.com", + "category": "Extra Tools", + "depends": ["base", "web"], + "summary": "Custom Background", + "images": ['images/image.png'], + "data": [ + "security/ir.model.access.csv", + "views/ir_actions.xml", + "views/res_company_view.xml", + "views/report_template.xml", + ], + "installable": True, + "application": False, + "license": "Other proprietary", +} diff --git a/odex30_base/custom_background/i18n/nl.po b/odex30_base/custom_background/i18n/nl.po new file mode 100644 index 0000000..728ace3 --- /dev/null +++ b/odex30_base/custom_background/i18n/nl.po @@ -0,0 +1,511 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * custom_background +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-07-16 12:50+0000\n" +"PO-Revision-Date: 2021-07-18 11:44+0200\n" +"Last-Translator: Erwin van der Ploeg \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" +"Language: nl\n" +"X-Generator: Poedit 2.4.2\n" + +#. module: custom_background +#: model_terms:ir.ui.view,arch_db:custom_background.view_ir_action_inherit_form +msgid "" +"Expression:\n" +" If the option \"Expression\" is selected you " +"can\n" +" set custom background PDF's based on\n" +" expressions.\n" +"
    \n" +" For example if you want only a background on\n" +" every second page you could do:\n" +"
    \n" +" result=page%2==0\n" +"
    \n" +" If you want only a background on every uneven\n" +" page (for example page 1,3 ,5) you could do:\n" +"
    \n" +" result=page%2!=0\n" +"
    \n" +" Or if you only want a background starting from\n" +" page 2 on for example you could do:\n" +"
    \n" +" result=page>2" +msgstr "" +"Uitdrukking:\n" +" Als de optie “Expressie” is geselecteerd, kunt " +"u\n" +" Een aangepaste achtergrond-PDF’s instellen op " +"basis van\n" +" expressies.\n" +"
    \n" +" Als u bijvoorbeeld alleen een achtergrond op\n" +" elke tweede pagina wil, dan kunt u bijvoorbeeld " +"dit doen:\n" +"
    \n" +" result=page%2==0\n" +"
    \n" +" Als u alleen een achtergrond wilt op elke " +"oneven\n" +" pagina (bijvoorbeeld pagina 1,3 ,5) kunt u " +"doen:\n" +"
    \n" +" result=page%2!=0\n" +"
    \n" +" Of als u alleen een achtergrond wilt vanaf\n" +" pagina 2, dan kunt u bijvoorbeeld dit doen:\n" +"
    \n" +" result=page>2" + +#. module: custom_background +#: model_terms:ir.ui.view,arch_db:custom_background.view_ir_action_inherit_form +msgid "" +"First Page:\n" +" If the option \"First Page\" is chosen it will " +"not\n" +" look at any other configurations for the first\n" +" page of the PDF.\n" +"
    \n" +" If no \"Background PDF\" is set on the \"First\n" +" Page\" rule then it will set the background " +"PDF\n" +" from the \"Fixed Page\", \"Expression Page\" " +"or\n" +" \"Remaining Pages\"." +msgstr "" +"Eerste pagina:\n" +" Als de optie “Eerste pagina” is gekozen, dan " +"wortd\n" +" Niet naar andere instellingen gekeken dan " +"deze\n" +" Voor de eerste pagina van de pdf.\n" +"
    \n" +" Als er geen “Achtergrond PDF” is ingesteld op " +"de “Eerste\n" +" Pagina” regel dan zal het de achtergrond PDF " +"instellen\n" +" van de “Vaste pagina”, “Expressie pagina” of\n" +" “Overige pagina’s”." + +#. module: custom_background +#: model_terms:ir.ui.view,arch_db:custom_background.view_ir_action_inherit_form +msgid "" +"Fixed Pages:\n" +" If the option \"Fixed Pages\" is selected you " +"can\n" +" enter for which page you'd like to use the\n" +" \"Background PDF\".\n" +" For example: setting a custom background PDF " +"for\n" +" the third page of a report by entering \"3\" " +"in\n" +" the field \"Page Number\".\n" +"
    \n" +" If the entered page number is first and last\n" +" then it will set the background from \"First\n" +" Page\" and \"Last Page\" if we configured the " +"first\n" +" page and the last page otherwise it will use " +"the\n" +" \"Fixed Page\" configuration." +msgstr "" +"Vaste pagina’s:\n" +" Als de optie “Vaste pagina’s” is geselecteerd, " +"kunt u\n" +" Instellen voor welke pagina u de\n" +" “Achtergrond-PDF” wilt gebruiken.\n" +" Bijvoorbeeld: een aangepaste achtergrond-PDF " +"instellen voor\n" +" de derde pagina van een rapport door “3” in te " +"voeren in\n" +" het veld “Paginanummer”.\n" +"
    \n" +" Als het ingevoerde paginanummer de eerste en " +"de laatste is\n" +" dan zal het de achtergrond instellen van " +"“Eerste\n" +" Pagina” en “Laatste pagina” als we de eerste " +"hebben geconfigureerd,\n" +" anders gebruikt het de\n" +" Configuratie “Vaste pagina”." + +#. module: custom_background +#: model_terms:ir.ui.view,arch_db:custom_background.view_ir_action_inherit_form +msgid "" +"Last Page:\n" +" If the option \"Last Page\" is selected, it " +"will\n" +" not check for any other configurations for the\n" +" last page.\n" +" It will only set the last page background PDF\n" +" that you've applied.\n" +"
    \n" +" If there was no \"Background PDF\" set on the " +"last\n" +" page then it will set the background PDF from\n" +" the \"Fixed Page\", \"Expression Page\" or\n" +" \"Remaining Pages\".\n" +"
    " +msgstr "" +"Laatste pagina:\n" +" Als de optie “Laatste pagina” is geselecteerd, " +"wordt\n" +" niet gecontroleerd op andere instellingen voor " +"de\n" +" laatste pagina.\n" +" Het zal alleen de laatste pagina-achtergrond " +"PDF instellen\n" +" die u heeft ingesteld.\n" +"
    \n" +" Als er geen “Achtergrond PDF” was ingesteld op " +"de laatste\n" +" pagina, dan zal het de achtergrond-PDF " +"instellen van\n" +" de “Vaste pagina”, “Expressie pagina” of\n" +" “Overige pagina’s”.\n" +"
    " + +#. module: custom_background +#: model_terms:ir.ui.view,arch_db:custom_background.view_ir_action_inherit_form +msgid "" +"Remaining Pages:\n" +" If the option \"Remaining Pages\" is selected " +"the\n" +" module will apply the \"Background PDF\" set " +"on\n" +" this rule for any pages that have no rule.\n" +" You could use this for example if you have a\n" +" rule \"First Page\" set and then have a second\n" +" rule \"Remaining Pages\" it would apply this\n" +" background on page 2, 3, .. and any other page\n" +" you have not configured." +msgstr "" +"Overige pagina’s:\n" +" Als de optie “Overige pagina’s” is " +"geselecteerd, wordt de\n" +" “Achtergrond PDF” toegepast op\n" +" deze regel voor alle pagina’s die geen regel " +"hebben.\n" +" U kunt dit bijvoorbeeld gebruiken als u een\n" +" regel “Eerste pagina” instelt en dan een " +"tweede\n" +" regel “Overige pagina’s”. Het zou dan de\n" +" achtergrond op instellen op pagina 2, 3, .. en " +"elke andere pagina\n" +" Die u niet heeft geconfigureerd." + + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_ir_actions_report__background_ids +#: model_terms:ir.ui.view,arch_db:custom_background.view_ir_action_inherit_form +msgid "Background Configuration" +msgstr "Achtergrondconfiguratie" + +#. module: custom_background +#: model_terms:ir.ui.view,arch_db:custom_background.view_ir_action_inherit_form +msgid "Background Configuration Per Language" +msgstr "Achtergrondconfiguratie per taal" + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_ir_actions_report__custom_report_background_image +msgid "Background Image" +msgstr "Achtergrondafbeelding" + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_report_background_lang__background_pdf +#: model:ir.model.fields,field_description:custom_background.field_report_background_line__background_pdf +#: model_terms:ir.ui.view,arch_db:custom_background.res_company_view_inherit +#: model_terms:ir.ui.view,arch_db:custom_background.view_ir_action_inherit_form +msgid "Background PDF" +msgstr "Achtergrond PDF" + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_ir_actions_report__bg_per_lang_ids +#: model:ir.model.fields,field_description:custom_background.field_res_company__bg_per_lang_ids +msgid "Background Per Language" +msgstr "Achtergrond per taal" + +#. module: custom_background +#: model:ir.model,name:custom_background.model_res_company +msgid "Companies" +msgstr "Bedrijven" + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_report_background_lang__company_id +msgid "Company" +msgstr "Bedrijf" + +#. module: custom_background +#: model_terms:ir.ui.view,arch_db:custom_background.res_company_view_inherit +msgid "Configuration" +msgstr "Instellingen" + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_report_background_lang__create_uid +#: model:ir.model.fields,field_description:custom_background.field_report_background_line__create_uid +msgid "Created by" +msgstr "Aangemaakt door" + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_report_background_lang__create_date +#: model:ir.model.fields,field_description:custom_background.field_report_background_line__create_date +msgid "Created on" +msgstr "Aangemaakt op" + +#. module: custom_background +#: model_terms:ir.ui.view,arch_db:custom_background.res_company_view_inherit +msgid "Custom Background Image" +msgstr "Achtergrondafbeelding" + +#. module: custom_background +#: model_terms:ir.ui.view,arch_db:custom_background.res_company_view_inherit +msgid "Custom Background Image Per Language" +msgstr "Aangepaste achtergrondafbeelding per taal" + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_ir_actions_report__custom_report_background +#: model:ir.model.fields,field_description:custom_background.field_res_company__custom_report_background_image +msgid "Custom Report Background" +msgstr "Achtergrondafbeelding layouts" + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_ir_actions_report__custom_report_type +msgid "Custom Report Type" +msgstr "Afwijkende achtergrond" + +#. module: custom_background +#: model_terms:ir.ui.view,arch_db:custom_background.view_ir_action_inherit_form +msgid "Detailed algorithm (with their priorities):" +msgstr "Gedetailleerd algoritme (met hun prioriteiten):" + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_ir_actions_report__display_name +#: model:ir.model.fields,field_description:custom_background.field_report_background_lang__display_name +#: model:ir.model.fields,field_description:custom_background.field_report_background_line__display_name +#: model:ir.model.fields,field_description:custom_background.field_res_company__display_name +msgid "Display Name" +msgstr "Schermnaam" + +#. module: custom_background +#: model:ir.model.fields.selection,name:custom_background.selection__report_background_line__type__expression +msgid "Expression" +msgstr "Uitdrukking" + +#. module: custom_background +#: model_terms:ir.ui.view,arch_db:custom_background.view_ir_action_inherit_form +msgid "Extra Note" +msgstr "Extra opmerking" + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_report_background_line__fall_back_to_company +msgid "Fall Back To Company" +msgstr "Terugvallen op het bedrijf" + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_report_background_lang__file_name +#: model:ir.model.fields,field_description:custom_background.field_report_background_line__file_name +msgid "File Name" +msgstr "Bestandsnaam" + +#. module: custom_background +#: model:ir.model.fields.selection,name:custom_background.selection__report_background_line__type__first_page +msgid "First Page" +msgstr "Eerste pagina" + +#. module: custom_background +#: model:ir.model.fields.selection,name:custom_background.selection__report_background_line__type__fixed +msgid "Fixed Page" +msgstr "Vaste pagina" + +#. module: custom_background +#: model:ir.model.fields.selection,name:custom_background.selection__ir_actions_report__custom_report_type__company +msgid "From Company" +msgstr "Van bedrijf" + +#. module: custom_background +#: model:ir.model.fields.selection,name:custom_background.selection__ir_actions_report__custom_report_type__dynamic +msgid "From Report Dynamic" +msgstr "Van Rapport Dynamisch" + +#. module: custom_background +#: model:ir.model.fields.selection,name:custom_background.selection__ir_actions_report__custom_report_type__report +msgid "From Report Fixed" +msgstr "Van rapport opgelost" + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_ir_actions_report__id +#: model:ir.model.fields,field_description:custom_background.field_report_background_lang__id +#: model:ir.model.fields,field_description:custom_background.field_report_background_line__id +#: model:ir.model.fields,field_description:custom_background.field_res_company__id +msgid "ID" +msgstr "ID" + +#. module: custom_background +#: model_terms:ir.ui.view,arch_db:custom_background.view_ir_action_inherit_form +msgid "" +"If there are no \"Background Configuration\" rules\n" +" added for any line it will work as a normal Odoo\n" +" report and will not apply any background to the\n" +" report." +msgstr "" +"Als er geen regels voor de “Achtergrondconfiguratie” zijn\n" +" toegevoegd voor een regel, dan zal deze werken als " +"een normaal Odoo\n" +" rapport en wordt er geen achtergrond toegevoegd op " +"de\n" +" Rappoortage." + +#. module: custom_background +#: model_terms:ir.ui.view,arch_db:custom_background.view_ir_action_inherit_form +msgid "Interaction with the background configuration" +msgstr "Interactie met de achtergrondconfiguratie" + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_ir_actions_report__is_bg_per_lang +#: model:ir.model.fields,field_description:custom_background.field_res_company__is_bg_per_lang +msgid "Is Background Per Language" +msgstr "Instellen achtergrond per taal" + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_report_background_lang__lang_id +#: model:ir.model.fields,field_description:custom_background.field_report_background_line__lang_id +msgid "Language" +msgstr "Taal" + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_ir_actions_report____last_update +#: model:ir.model.fields,field_description:custom_background.field_report_background_lang____last_update +#: model:ir.model.fields,field_description:custom_background.field_report_background_line____last_update +#: model:ir.model.fields,field_description:custom_background.field_res_company____last_update +msgid "Last Modified on" +msgstr "Laatst gewijzigd op" + +#. module: custom_background +#: model:ir.model.fields.selection,name:custom_background.selection__report_background_line__type__last_page +msgid "Last Page" +msgstr "Laatste pagina" + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_report_background_lang__write_uid +#: model:ir.model.fields,field_description:custom_background.field_report_background_line__write_uid +msgid "Last Updated by" +msgstr "Laatst bijgewerkt door" + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_report_background_lang__write_date +#: model:ir.model.fields,field_description:custom_background.field_report_background_line__write_date +msgid "Last Updated on" +msgstr "Laatst bijgewerkt op" + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_report_background_line__page_expression +msgid "Page Expression" +msgstr "Pagina expressie" + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_report_background_line__page_number +msgid "Page Number" +msgstr "Paginanummer" + +#. module: custom_background +#: code:addons/custom_background/models/res_company.py:0 +#, python-format +msgid "" +"Please configure Custom Background Per Language beacuse 'Fall Back To Company' is set " +"in the dynamic type report level!" +msgstr "" +"Configureer a.u.b. aangepaste achtergrond per taal omdat 'Fall Back To Bedrijf' is " +"ingesteld op het rapportniveau dynamisch type!" + +#. module: custom_background +#: code:addons/custom_background/models/res_company.py:0 +#, python-format +msgid "" +"Please configure Custom Background Per Language beacuse 'From Company' type is set at " +"the Report level!" +msgstr "" +"Configureer aangepaste achtergrond per taal vanwege het type 'Van bedrijf' is ingesteld " +"op rapportniveau!" + +#. module: custom_background +#: code:addons/custom_background/models/report.py:0 +#, python-format +msgid "Please configure Custom Background Per Language for Dynamic type!" +msgstr "Configureer aangepaste achtergrond per taal voor dynamisch type!" + +#. module: custom_background +#: code:addons/custom_background/models/report.py:0 +#, python-format +msgid "Please configure Custom Background Per Language for Report type!" +msgstr "Configureer aangepaste achtergrond per taal voor rapporttype!" + +#. module: custom_background +#: code:addons/custom_background/models/report.py:0 +#, python-format +msgid "Please configure Custom Background Per Language in every company!" +msgstr "Configureer aangepaste achtergrond per taal in elk bedrijf!" + +#. module: custom_background +#: model:ir.model.fields.selection,name:custom_background.selection__report_background_line__type__remaining +msgid "Remaining pages" +msgstr "Overige pagina's" + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_report_background_lang__report_id +#: model:ir.model.fields,field_description:custom_background.field_report_background_line__report_id +msgid "Report" +msgstr "Rapport" + +#. module: custom_background +#: model:ir.model,name:custom_background.model_ir_actions_report +msgid "Report Action" +msgstr "Rapport actie" + +#. module: custom_background +#: model:ir.model,name:custom_background.model_report_background_line +msgid "Report Background Line" +msgstr "Achtergrondregel rapporteren" + +#. module: custom_background +#: model:ir.model,name:custom_background.model_report_background_lang +msgid "Report Background Line Per Language" +msgstr "Achtergrondregel per taal rapporteren" + +#. module: custom_background +#: model:ir.model.fields,field_description:custom_background.field_report_background_line__type +msgid "Type" +msgstr "Type" + +#. module: custom_background +#: code:addons/custom_background/models/report.py:0 +#, python-format +msgid "" +"Wkhtmltopdf failed (error code: %s). Memory limit too low or maximum file number of " +"subprocess reached. Message : %s" +msgstr "" +"Wkhtmltopdf fout (fout code: %s). Geheugenlimiet te laag of maximale bestandsnummer van " +"subproces bereikt. Bericht:%s" + +#. module: custom_background +#: code:addons/custom_background/models/report.py:0 +#, python-format +msgid "Wkhtmltopdf failed (error code: %s). Message: %s" +msgstr "Wkhtmltopdf fout (error code: %s). Bericht: %s" + +#. module: custom_background +#: model_terms:ir.ui.view,arch_db:custom_background.view_ir_action_inherit_form +msgid "" +"You can set the backgroud watermark in a report based on\n" +" the options set in the \"Background Configuration\" tab." +msgstr "" +"U kunt het achtergrondwatermerk in een rapport instellen op basis\n" +"van de opties die zijn ingesteld op het tabblad “Achtergrondconfiguratie”." diff --git a/odex30_base/custom_background/images/image.png b/odex30_base/custom_background/images/image.png new file mode 100644 index 0000000..18b79a7 Binary files /dev/null and b/odex30_base/custom_background/images/image.png differ diff --git a/odex30_base/custom_background/models/__init__.py b/odex30_base/custom_background/models/__init__.py new file mode 100644 index 0000000..d307bab --- /dev/null +++ b/odex30_base/custom_background/models/__init__.py @@ -0,0 +1,4 @@ +# See LICENSE file for full copyright and licensing details. +from . import report +from . import res_company +from . import report_background_lang diff --git a/odex30_base/custom_background/models/report.py b/odex30_base/custom_background/models/report.py new file mode 100644 index 0000000..d0bf3cc --- /dev/null +++ b/odex30_base/custom_background/models/report.py @@ -0,0 +1,649 @@ +# See LICENSE file for full copyright and licensing details. +import base64 +import logging +import os +import subprocess +import tempfile +from contextlib import closing + +from odoo.tools.pdf import PdfFileReader, PdfFileWriter +from reportlab.graphics.barcode import createBarcodeDrawing + +from odoo import api, fields, models +from odoo.exceptions import UserError +from odoo.tools.misc import find_in_path +from odoo.tools.safe_eval import safe_eval +from odoo.tools.translate import _ + +try: + createBarcodeDrawing( + "Code128", + value="foo", + format="png", + width=100, + height=100, + humanReadable=1, + ).asString("png") +except Exception: + pass + + +# -------------------------------------------------------------------------- +# Helpers +# -------------------------------------------------------------------------- +_logger = logging.getLogger(__name__) + + +def _get_wkhtmltopdf_bin(): + return find_in_path("wkhtmltopdf") + + +class ReportBackgroundLine(models.Model): + _name = "report.background.line" + _description = "Report Background Line" + + page_number = fields.Integer() + type = fields.Selection( + [ + ("fixed", "Fixed Page"), + ("expression", "Expression"), + ("first_page", "First Page"), + ("last_page", "Last Page"), + ("remaining", "Remaining pages"), + ] + ) + background_pdf = fields.Binary(string="Background PDF") + # New field. #22260 + file_name = fields.Char(string="File Name") + report_id = fields.Many2one("ir.actions.report", string="Report") + page_expression = fields.Char() + fall_back_to_company = fields.Boolean() + # New fields. #22260 + lang_id = fields.Many2one( + "res.lang", + string="Language", + ) + # Added new field #T5211 + company_id = fields.Many2one(comodel_name="res.company", string="Company") + + +class IrActionsReport(models.Model): + _inherit = "ir.actions.report" + + custom_report_background = fields.Boolean(string="Custom Report Background") + custom_report_background_image = fields.Binary(string="Background Image") + custom_report_type = fields.Selection( + [ + ("company", "From Company"), + ("report", "From Report Fixed"), + ("dynamic", "From Report Dynamic"), + ] + ) + + background_ids = fields.One2many( + "report.background.line", "report_id", "Background Configuration" + ) + # New fields. #22260 + bg_per_lang_ids = fields.One2many( + "report.background.lang", + "report_id", + string="Background Per Language", + ) + is_bg_per_lang = fields.Boolean( + string="Is Background Per Language", + ) + + def get_company_without_custom_bg(self): + """New method for search and get company in which custom bg per language is not + set. #22260""" + res_company_env = self.env["res.company"].search([]) + # Filtered company in which is_bg_per_lang is not set and + # attachment is not set. + company = res_company_env.filtered( + lambda c: not c.is_bg_per_lang or not c.bg_per_lang_ids + ) + return company + + @api.constrains( + "is_bg_per_lang", "bg_per_lang_ids", "custom_report_type", "background_ids" + ) + def _check_report_custom_bg_config(self): + """New constrains method for check custom bg per company is set or not when for + 'report' & 'dynamic' type. #22260""" + # If is_bg_per_lang is false then return. + if not self.is_bg_per_lang: + return + # If type is 'report' and custom bg per lang is not set then raise warning. + if self.custom_report_type == "report" and not self.bg_per_lang_ids: + raise UserError( + _("Please configure Custom Background Per Language for Report type!") + ) + # If type is 'dynamic' and custom bg per lang is not set then raise warning. + elif self.custom_report_type == "dynamic" and not self.background_ids: + raise UserError( + _("Please configure Custom Background Per Language for Dynamic type!") + ) + # Check type is dynamic and background_ids is set or not. + elif self.custom_report_type == "dynamic" and self.background_ids: + # Filter fall_back_to_company true records. + fbc = self.background_ids.filtered(lambda bg: bg.fall_back_to_company) + # If fbc and custom bg not set at company level then raise warning. + if fbc: + company = self.get_company_without_custom_bg() + # If any attachment not set in the any company then raise warning. + if company: + raise UserError( + _( + "Please configure Custom Background Per Language in every " + "company!" + ) + ) + # If type is 'company' or type is not set then search + # configuration in all company. + elif self.custom_report_type == "company" or not self.custom_report_type: + company = self.get_company_without_custom_bg() + # If any attachment not set in the any company then raise warning. + if company: + raise UserError( + _( + "Please configure Custom Background Per Language in every " + "company!" + ) + ) + + def _render_qweb_pdf(self, res_ids=None, data=None): + Model = self.env[self.model] + record_ids = Model.browse(res_ids) + company_id = False + if record_ids[:1]._name == "res.company": + company_id = record_ids[:1] + # Fix test cases error. #22107 + elif hasattr(record_ids[:1], "company_id"): + # If in record company is not set then consider current log in + # user's company. #22476 + company_id = record_ids[:1].company_id or self.env.user.company_id + else: + company_id = self.env.company + + # Add custom_bg_res_ids in context. #22260 + return super( + IrActionsReport, + self.with_context(custom_bg_res_ids=res_ids, background_company=company_id), + )._render_qweb_pdf(res_ids=res_ids, data=data) + + def add_pdf_watermarks(self, custom_background_data, page): + """create a temp file and set datas and added in report page. #T4209""" + temp_back_id, temp_back_path = tempfile.mkstemp( + suffix=".pdf", prefix="back_report.tmp." + ) + back_data = base64.b64decode(custom_background_data) + with closing(os.fdopen(temp_back_id, "wb")) as back_file: + back_file.write(back_data) + pdf_reader_watermark = PdfFileReader(temp_back_path, "rb") + watermark_page = pdf_reader_watermark.getPage(0) + watermark_page.mergePage(page) + return watermark_page + + def get_lang(self): + """New method for return language, if partner_id is available in model and + partner is set in that model, else set current logged in user's language. + #22260""" + res_record_ids = self._context.get("custom_bg_res_ids") + model = self.env[self.model] + record_ids = model.browse(res_record_ids) + lang_code = False + # If partner_id field in the model and partner is set in the model the consider + # partner's language. + # NOTE: Used "record_ids[-1]" to avoid loop, if use loop then always set last + # record partner's language. + if "partner_id" in model._fields and record_ids[-1].partner_id: + partner_lang = record_ids[-1].partner_id.lang + lang_code = partner_lang if partner_lang else "en_US" + else: + # If partner_id field is not in model or partner_id is not set then consider + # current user's language. + lang_code = self._context.get("lang") + return lang_code + + def get_bg_per_lang(self): + """New method for get custom background based on the partner languages for + report type and company type. #22260""" + company_background = self._context.get("background_company") + lang_code = self.get_lang() + # If custom_report_type is dynamic then set language related domains. + if self.custom_report_type == "dynamic": + # If is_bg_per_lang true then set lang_code related domain. + if self.is_bg_per_lang: + lang_domain = [ + ("lang_id.code", "=", lang_code), + ] + else: + # If is_bg_per_lang false then set lang_id related domain. + lang_domain = [ + ("lang_id", "=", False), + ] + return lang_domain + + # If custom_report_type is report then set report(self) id. + if self.custom_report_type == "report": + custom_bg_from = self + # If custom_report_type is company then set current company id from context. + if self.custom_report_type == "company" or not self.custom_report_type: + custom_bg_from = company_background + + # Filter records from report_background_lang model based on the languages. + # custom_bg_from: company_id or report_id(self). + custom_bg_lang = custom_bg_from.bg_per_lang_ids.filtered( + lambda l: l.lang_id.code == lang_code + ) + + # Set 1st custom background. + custom_background = custom_bg_lang[:1].background_pdf + return custom_background + + @api.model + def _run_wkhtmltopdf( + self, + bodies, + header=None, + footer=None, + landscape=False, + specific_paperformat_args=None, + set_viewport_size=False, + ): + """Execute wkhtmltopdf as a subprocess in order to convert html given + in input into a pdf document. + + :param bodies: The html bodies of the report, one per page. + :param header: The html header of the report containing all headers. + :param footer: The html footer of the report containing all footers. + :param landscape: Force the pdf to be rendered under a landscape + format. + :param specific_paperformat_args: dict of prioritized paperformat + arguments. + :param set_viewport_size: Enable a viewport sized '1024x1280' or + '1280x1024' depending of landscape arg. + :return: Content of the pdf as a string + """ + + # call default odoo standard function of paperformat #19896 + # https://github.com/odoo/odoo/blob/13.0/odoo/addons/base/models + # /ir_actions_report.py#L243 + paperformat_id = self.get_paperformat() + + # Build the base command args for wkhtmltopdf bin + command_args = self._build_wkhtmltopdf_args( + paperformat_id, + landscape, + specific_paperformat_args=specific_paperformat_args, + set_viewport_size=set_viewport_size, + ) + + files_command_args = [] + temporary_files = [] + if header: + head_file_fd, head_file_path = tempfile.mkstemp( + suffix=".html", prefix="report.header.tmp." + ) + with closing(os.fdopen(head_file_fd, "wb")) as head_file: + head_file.write(header) + temporary_files.append(head_file_path) + files_command_args.extend(["--header-html", head_file_path]) + if footer: + foot_file_fd, foot_file_path = tempfile.mkstemp( + suffix=".html", prefix="report.footer.tmp." + ) + with closing(os.fdopen(foot_file_fd, "wb")) as foot_file: + foot_file.write(footer) + temporary_files.append(foot_file_path) + files_command_args.extend(["--footer-html", foot_file_path]) + + paths = [] + for i, body in enumerate(bodies): + prefix = "%s%d." % ("report.body.tmp.", i) + body_file_fd, body_file_path = tempfile.mkstemp( + suffix=".html", prefix=prefix + ) + with closing(os.fdopen(body_file_fd, "wb")) as body_file: + body_file.write(body) + paths.append(body_file_path) + temporary_files.append(body_file_path) + + pdf_report_fd, pdf_report_path = tempfile.mkstemp( + suffix=".pdf", prefix="report.tmp." + ) + os.close(pdf_report_fd) + temporary_files.append(pdf_report_path) + try: + wkhtmltopdf = ( + [_get_wkhtmltopdf_bin()] + + command_args + + files_command_args + + paths + + [pdf_report_path] + ) + process = subprocess.Popen( + wkhtmltopdf, stdout=subprocess.PIPE, stderr=subprocess.PIPE + ) + out, err = process.communicate() + + if process.returncode not in [0, 1]: + if process.returncode == -11: + message = _( + "Wkhtmltopdf failed (error code: %s). Memory limit too low or " + "maximum file number of subprocess reached. Message : %s" + ) + else: + message = _("Wkhtmltopdf failed (error code: %s). Message: %s") + _logger.warning(message, process.returncode, err[-1000:]) + raise UserError(message % (str(process.returncode), err[-1000:])) + else: + if err: + _logger.warning("wkhtmltopdf: %s" % err) + # Dynamic Type. + if ( + self + and self.custom_report_background + and self.custom_report_type == "dynamic" + ): + temp_report_id, temp_report_path = tempfile.mkstemp( + suffix=".pdf", prefix="with_back_report.tmp." + ) + output = PdfFileWriter() + pdf_reader_content = PdfFileReader(pdf_report_path, "rb") + + # Call method for get domain related to the languages. #22260 + lang_domain = self.get_bg_per_lang() + + # Added lang_domain in all search methods. #22260 + first_page = self.background_ids.search( + lang_domain + + [ + ("type", "=", "first_page"), + ("report_id", "=", self.id), + ], + limit=1, + ) + last_page = self.background_ids.search( + lang_domain + + [ + ("type", "=", "last_page"), + ("report_id", "=", self.id), + ], + limit=1, + ) + fixed_pages = self.background_ids.search( + lang_domain + + [ + ("type", "=", "fixed"), + ("report_id", "=", self.id), + ] + ) + remaining_pages = self.background_ids.search( + lang_domain + + [ + ("type", "=", "remaining"), + ("report_id", "=", self.id), + ], + limit=1, + ) + expression = self.background_ids.search( + lang_domain + + [ + ("type", "=", "expression"), + ("report_id", "=", self.id), + ], + limit=1, + ) + + company_background = self._context.get("background_company") + company_background_img = ( + company_background.custom_report_background_image + ) + company_background_dynamic = company_background.background_ids + # Start. #22260 + if self.is_bg_per_lang: + lang_code = self.get_lang() + custom_bg_lang = company_background.bg_per_lang_ids.filtered( + lambda l: l.lang_id.code == lang_code + ) + # End. #22260 + for i in range(pdf_reader_content.getNumPages()): + watermark = "" + if first_page and i == 0: + if first_page.fall_back_to_company and company_background: + # Start. #22260 + # If is_bg_per_lang then get custom bg from the company. + if self.is_bg_per_lang: + watermark = custom_bg_lang[:1].background_pdf + else: + company_watermark = company_background_dynamic.filtered( + lambda a: a.type == "first_page" + ) + if company_watermark: + watermark = company_watermark.background_pdf + else: + watermark = company_background_img + # End. #22260 + # Fix page 1st issue. #22260 + elif first_page.background_pdf: + watermark = first_page.background_pdf + elif last_page and i == pdf_reader_content.getNumPages() - 1: + if last_page.fall_back_to_company and company_background: + # Start. #22260 + # If is_bg_per_lang then get custom bg from the company. + if self.is_bg_per_lang: + watermark = custom_bg_lang[:1].background_pdf + else: + company_watermark = company_background_dynamic.filtered( + lambda a: a.type == "last_page" + ) + if company_watermark: + watermark = company_watermark.background_pdf + else: + watermark = company_background_img + # End. #22260 + elif last_page.background_pdf: + watermark = last_page.background_pdf + elif i + 1 in fixed_pages.mapped("page_number"): + fixed_page = fixed_pages.search( + [ + ("page_number", "=", i + 1), + ("report_id", "=", self.id), + ], + limit=1, + ) + if ( + fixed_page + and fixed_page.fall_back_to_company + and company_background + ): + # Start. #22260 + # If is_bg_per_lang then get custom bg from the company. + if self.is_bg_per_lang: + watermark = custom_bg_lang[:1].background_pdf + else: + company_watermark = company_background_dynamic.filtered( + lambda a: a.type == "fixed" + and a.page_number == i + 1 + ) + if company_watermark: + watermark = company_watermark.background_pdf + else: + watermark = company_background_img + # End. #22260 + elif fixed_page and fixed_page.background_pdf: + watermark = fixed_page.background_pdf + elif expression and expression.page_expression: + eval_dict = {"page": i + 1} + safe_eval( + expression.page_expression, + eval_dict, + mode="exec", + nocopy=True, + ) + if ( + expression.fall_back_to_company + and company_background + and eval_dict.get("result", False) + ): + # Start. #22260 + # If is_bg_per_lang then get custom bg from the company. + if self.is_bg_per_lang: + watermark = custom_bg_lang[:1].background_pdf + else: + company_watermark = company_background_dynamic.filtered( + lambda a: a.type == "expression" + and a.page_expression + ) + if company_watermark: + company_eval_dict = {"page": i + 1} + safe_eval( + company_watermark.page_expression, + company_eval_dict, + mode="exec", + nocopy=True, + ) + if company_eval_dict.get("result", False): + watermark = company_watermark.background_pdf + else: + watermark = company_background_img + else: + watermark = company_background_img + # End. #22260 + elif ( + eval_dict.get("result", False) and expression.background_pdf + ): + watermark = expression.background_pdf + else: + if remaining_pages: + if ( + remaining_pages.fall_back_to_company + and company_background + ): + # Start. #22260 + # If is_bg_per_lang then get custom bg from + # the company. + if self.is_bg_per_lang: + watermark = custom_bg_lang[:1].background_pdf + else: + company_watermark = ( + company_background_dynamic.filtered( + lambda a: a.type == "remaining" + ) + ) + if company_watermark: + watermark = company_watermark.background_pdf + else: + watermark = company_background_img + # End. #22260 + elif remaining_pages.background_pdf: + watermark = remaining_pages.background_pdf + else: + if remaining_pages: + if ( + remaining_pages.fall_back_to_company + and company_background + ): + # Start. #22260 + # If is_bg_per_lang then get custom bg from the company. + if self.is_bg_per_lang: + watermark = custom_bg_lang[:1].background_pdf + else: + company_watermark = ( + company_background_dynamic.filtered( + lambda a: a.type == "remaining" + ) + ) + if company_watermark: + watermark = company_watermark.background_pdf + else: + watermark = company_background_img + # End. #22260 + elif remaining_pages.background_pdf: + watermark = remaining_pages.background_pdf + if watermark: + page = self.add_pdf_watermarks( + watermark, + pdf_reader_content.getPage(i), + ) + else: + page = pdf_reader_content.getPage(i) + output.addPage(page) + output.write(open(temp_report_path, "wb")) + pdf_report_path = temp_report_path + os.close(temp_report_id) + elif self.custom_report_background: + temp_back_id, temp_back_path = tempfile.mkstemp( + suffix=".pdf", prefix="back_report.tmp." + ) + custom_background = False + # From Report Type. + if ( + self + and self.custom_report_background + and self.custom_report_type == "report" + ): + # 222760 Starts.If background per lang is True then call method for + # get custom background based on different languages. + if self.is_bg_per_lang: + custom_background = self.get_bg_per_lang() + # 222760 Ends. + else: + custom_background = self.custom_report_background_image + # 222760 Ends. + # From Company Type. + if ( + self.custom_report_background + and not custom_background + and ( + self.custom_report_type == "company" + or not self.custom_report_type + ) + and self._context.get("background_company") # #19896 + ): + # report background will be displayed based on the current + # company #19896 + company_id = self._context.get("background_company") + # 222760 Starts. If background per lang is True then call method for + # get custom background from company based on different languages. + if self.is_bg_per_lang: + custom_background = self.get_bg_per_lang() + # 222760 Ends. + else: + custom_background = company_id.custom_report_background_image + # If background found from any type then set that to the report. + if custom_background: + back_data = base64.b64decode(custom_background) + with closing(os.fdopen(temp_back_id, "wb")) as back_file: + back_file.write(back_data) + temp_report_id, temp_report_path = tempfile.mkstemp( + suffix=".pdf", prefix="with_back_report.tmp." + ) + output = PdfFileWriter() + pdf_reader_content = PdfFileReader(pdf_report_path, "rb") + + for i in range(pdf_reader_content.getNumPages()): + page = pdf_reader_content.getPage(i) + pdf_reader_watermark = PdfFileReader(temp_back_path, "rb") + watermark = pdf_reader_watermark.getPage(0) + watermark.mergePage(page) + output.addPage(watermark) + output.write(open(temp_report_path, "wb")) + pdf_report_path = temp_report_path + os.close(temp_report_id) + except Exception as ex: + logging.info("Error while PDF Background %s" % ex) + raise + + with open(pdf_report_path, "rb") as pdf_document: + pdf_content = pdf_document.read() + + # Manual cleanup of the temporary files + for temporary_file in temporary_files: + try: + os.unlink(temporary_file) + except (OSError, IOError): + _logger.error("Error when trying to remove file %s" % temporary_file) + + return pdf_content diff --git a/odex30_base/custom_background/models/report_background_lang.py b/odex30_base/custom_background/models/report_background_lang.py new file mode 100644 index 0000000..c5b3b50 --- /dev/null +++ b/odex30_base/custom_background/models/report_background_lang.py @@ -0,0 +1,20 @@ +from odoo import fields, models + + +class ReportBackgroundLang(models.Model): + _name = "report.background.lang" + _description = "Report Background Line Per Language" + + # New fields. #22260 + lang_id = fields.Many2one( + "res.lang", + required=True, + string="Language", + ) + background_pdf = fields.Binary(string="Background PDF", required=True) + file_name = fields.Char(string="File Name") + report_id = fields.Many2one("ir.actions.report", string="Report") + company_id = fields.Many2one( + "res.company", + string="Company", + ) diff --git a/odex30_base/custom_background/models/res_company.py b/odex30_base/custom_background/models/res_company.py new file mode 100644 index 0000000..6cfa61b --- /dev/null +++ b/odex30_base/custom_background/models/res_company.py @@ -0,0 +1,74 @@ +# See LICENSE file for full copyright and licensing details. +from odoo import _, api, fields, models +from odoo.exceptions import UserError + + +class ResCompany(models.Model): + _inherit = "res.company" + + custom_report_background_image = fields.Binary(string="Custom Report Background") + # New field. #22260 + is_bg_per_lang = fields.Boolean( + string="Is Background Per Language", + ) + bg_per_lang_ids = fields.One2many( + "report.background.lang", + "company_id", + string="Background Per Language", + ) + + # Added new field #T5211 + is_dynamic_background = fields.Boolean( + string="Is Dynamic Background", + ) + background_ids = fields.One2many( + "report.background.line", "company_id", "Background Configuration" + ) + + @api.constrains( + "is_bg_per_lang", "bg_per_lang_ids", "is_dynamic_background", "background_ids" + ) + def _check_company_custom_bg_config(self): + """New constrains method for check custom bg per company is set or not when + 'From Company' type is set at ir_actions_report level. #22260""" + # Env. + report_env = self.env["ir.actions.report"] + # Search report based on the 'company' type and 'is_bg_per_lang' boolean. + report_ids = report_env.search( + [ + ("custom_report_type", "in", ["company", False]), + ("is_bg_per_lang", "=", True), + ] + ) + # Search dynamic reoprt. + dynamic_report_ids = report_env.search( + [ + ("custom_report_type", "=", "dynamic"), + ("is_bg_per_lang", "=", True), + ] + ) + is_fall_back_to_company = False + if dynamic_report_ids: + # Get report in which Fall back to company is true. + is_fall_back_to_company = dynamic_report_ids.mapped( + "background_ids" + ).filtered(lambda r: r.fall_back_to_company) + # If fall_back_to_company and custom bg per lang is not set then raise warning. + if is_fall_back_to_company and not ( + self.is_bg_per_lang and self.bg_per_lang_ids + ): + raise UserError( + _( + "Please configure Custom Background Per Language beacuse " + "'Fall Back To Company' is set in the dynamic type report level!" + ) + ) + # If any report with company type and custom bg per lang is not set at + # res_company level then raise warning. + if report_ids and not (self.is_bg_per_lang and self.bg_per_lang_ids): + raise UserError( + _( + "Please configure Custom Background Per Language beacuse " + "'From Company' type is set at the Report level!" + ) + ) diff --git a/odex30_base/custom_background/security/ir.model.access.csv b/odex30_base/custom_background/security/ir.model.access.csv new file mode 100644 index 0000000..8f8b55b --- /dev/null +++ b/odex30_base/custom_background/security/ir.model.access.csv @@ -0,0 +1,5 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_report_background_line,access_report_background_line,model_report_background_line,base.group_user,1,0,0,0 +access_report_background_lang_user,access_report_background_lang,model_report_background_lang,base.group_user,1,0,0,0 +access_report_background_line_system,access_report_background_line_system,model_report_background_line,base.group_system,1,1,1,1 +access_report_background_lang_admin,access_report_background_lang,model_report_background_lang,base.group_system,1,1,1,1 diff --git a/odex30_base/custom_background/static/description/icon.png b/odex30_base/custom_background/static/description/icon.png new file mode 100644 index 0000000..9ad73d7 Binary files /dev/null and b/odex30_base/custom_background/static/description/icon.png differ diff --git a/odex30_base/custom_background/static/description/images/BackgroundConfiguration.png b/odex30_base/custom_background/static/description/images/BackgroundConfiguration.png new file mode 100644 index 0000000..b9320de Binary files /dev/null and b/odex30_base/custom_background/static/description/images/BackgroundConfiguration.png differ diff --git a/odex30_base/custom_background/static/description/images/BackgroundConfigurationSelection.png b/odex30_base/custom_background/static/description/images/BackgroundConfigurationSelection.png new file mode 100644 index 0000000..976a4f4 Binary files /dev/null and b/odex30_base/custom_background/static/description/images/BackgroundConfigurationSelection.png differ diff --git a/odex30_base/custom_background/static/description/images/CreateBackgroundConfiguration.png b/odex30_base/custom_background/static/description/images/CreateBackgroundConfiguration.png new file mode 100644 index 0000000..7823044 Binary files /dev/null and b/odex30_base/custom_background/static/description/images/CreateBackgroundConfiguration.png differ diff --git a/odex30_base/custom_background/static/description/images/FixedBackgroundBasedOnLang.png b/odex30_base/custom_background/static/description/images/FixedBackgroundBasedOnLang.png new file mode 100644 index 0000000..e0f8330 Binary files /dev/null and b/odex30_base/custom_background/static/description/images/FixedBackgroundBasedOnLang.png differ diff --git a/odex30_base/custom_background/static/description/images/logo.png b/odex30_base/custom_background/static/description/images/logo.png new file mode 100644 index 0000000..5ea55e5 Binary files /dev/null and b/odex30_base/custom_background/static/description/images/logo.png differ diff --git a/odex30_base/custom_background/static/description/index.html b/odex30_base/custom_background/static/description/index.html new file mode 100644 index 0000000..f79c2b5 --- /dev/null +++ b/odex30_base/custom_background/static/description/index.html @@ -0,0 +1,168 @@ +
    +
    +
    + + + +
    +
    + + Custom Background + +
    +
    +
    +
    +
    + +

    + Contact With Us +

    +
    + contact@bizzappdev.com + +
    +
    +
    +
    + +
    +
    +
    +
    Module Custom Background facilitates is to set the Header and footer or watermark in the report based on predifined PDF configured. the predefined PDF will be used as background PDF in all the page of the report(QWeb-PDF). +
    +
    +
    +
    + +
    +
    +
    +
    + At level of the report you can configure that background pdf. You can configure based on company, language, or specifically for the report only. You can configure different PDF for First and last page as well as for page range. +
    +
    +
    +
    + +
    +
    +
    +
    +

    There are different options for configuration

    +
      +
    • Fixed background image from Company
    • +
    • Fixed background image from Report
    • +
    • Dynamic image from report
    • +
    • Background image from report based on language
    • +
    +
    +
    +
    +
    + +
    +
    +
    +
    + You can select custom reprot type based on your requirements +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + You can also configure Dynamic Background in your PDF as per your requirements +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + You can configure here Dynamic Background as per your requirements +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + You can configure Fixed Background Based on Langauge as per your requirements +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + Report Without Background +
    +
    + +
    +
    +
    +
    +
    + Report With Background +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + + + +
    + +
    +
    +

    Need Any Help ?

    + +

    Contact With Us

    + +
    +
    +
    +
    +
    +
    +
    diff --git a/odex30_base/custom_background/static/src/scss/report_qweb_pdf.scss b/odex30_base/custom_background/static/src/scss/report_qweb_pdf.scss new file mode 100644 index 0000000..83cc2eb --- /dev/null +++ b/odex30_base/custom_background/static/src/scss/report_qweb_pdf.scss @@ -0,0 +1,3 @@ +body { + background: transparent !important; +} diff --git a/odex30_base/custom_background/views/ir_actions.xml b/odex30_base/custom_background/views/ir_actions.xml new file mode 100644 index 0000000..5a55eac --- /dev/null +++ b/odex30_base/custom_background/views/ir_actions.xml @@ -0,0 +1,204 @@ + + + + + ir.actions.report.form + ir.actions.report + form + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + +
    + +

    Interaction with the background configuration

    +
    +

    + You can set the backgroud watermark in a report based on + the options set in the "Background Configuration" tab. +

    +

    + Detailed algorithm (with their priorities): +

      +
    1. + First Page: + If the option "First Page" is chosen it will not + look at any other configurations for the first + page of the PDF. +
      + If no "Background PDF" is set on the "First + Page" rule then it will set the background PDF + from the "Fixed Page", "Expression Page" or + "Remaining Pages". +
    2. +
    3. + Last Page: + If the option "Last Page" is selected, it will + not check for any other configurations for the + last page. + It will only set the last page background PDF + that you've applied. +
      + If there was no "Background PDF" set on the last + page then it will set the background PDF from + the "Fixed Page", "Expression Page" or + "Remaining Pages". +
      +
    4. +
    5. + Fixed Pages: + If the option "Fixed Pages" is selected you can + enter for which page you'd like to use the + "Background PDF". + For example: setting a custom background PDF for + the third page of a report by entering "3" in + the field "Page Number". +
      + If the entered page number is first and last + then it will set the background from "First + Page" and "Last Page" if we configured the first + page and the last page otherwise it will use the + "Fixed Page" configuration. +
    6. +
    7. + Expression: + If the option "Expression" is selected you can + set custom background PDF's based on + expressions. +
      + For example if you want only a background on + every second page you could do: +
      + result=page%2==0 +
      + If you want only a background on every uneven + page (for example page 1,3 ,5) you could do: +
      + result=page%2!=0 +
      + Or if you only want a background starting from + page 2 on for example you could do: +
      + result=page>2 +
    8. +
    9. + Remaining Pages: + If the option "Remaining Pages" is selected the + module will apply the "Background PDF" set on + this rule for any pages that have no rule. + You could use this for example if you have a + rule "First Page" set and then have a second + rule "Remaining Pages" it would apply this + background on page 2, 3, .. and any other page + you have not configured. +
    10. +
    + Extra Note +
  • + If there are no "Background Configuration" rules + added for any line it will work as a normal Odoo + report and will not apply any background to the + report. +
  • +

    +
    +
    + + + +
    + + + + + + + + + +
    + + + + +
    +
    +
    +
    +
    +
    +
    diff --git a/odex30_base/custom_background/views/report_template.xml b/odex30_base/custom_background/views/report_template.xml new file mode 100644 index 0000000..8278577 --- /dev/null +++ b/odex30_base/custom_background/views/report_template.xml @@ -0,0 +1,14 @@ + + + + + + + diff --git a/odex30_base/custom_background/views/res_company_view.xml b/odex30_base/custom_background/views/res_company_view.xml new file mode 100644 index 0000000..cee33c0 --- /dev/null +++ b/odex30_base/custom_background/views/res_company_view.xml @@ -0,0 +1,114 @@ + + + + + res.company.form + res.company + + + + + + + + + + + + + + +
    + + + + + + + + + +
    + + + + +
    +
    + + + + +
    + + + + + + + + + + + + + + + +
    + + + + + + + + +
    +
    +
    +
    +
    +
    +
    +
    diff --git a/odex30_base/data_chart/__init__.py b/odex30_base/data_chart/__init__.py new file mode 100644 index 0000000..5305644 --- /dev/null +++ b/odex30_base/data_chart/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import models \ No newline at end of file diff --git a/odex30_base/data_chart/__manifest__.py b/odex30_base/data_chart/__manifest__.py new file mode 100644 index 0000000..b3ce027 --- /dev/null +++ b/odex30_base/data_chart/__manifest__.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +{ + 'name': "data visualization", + 'version': '18.0.1.0.0', + + 'summary': """ + add data visualization in to odoo + this module is adding the ability to create and manage new table reports + for a spacific model or a query based on data items + """, + + 'category': 'Extra Tools', + 'author': "Expert Co. Ltd.", + 'website': "http://www.exp-sa.com", + # any module necessary for this one to work correctly + 'depends': ['web'], + + # always loaded + 'data': [ + 'security/groups.xml', + 'security/ir.model.access.csv', + 'views/views.xml', + 'views/data_chart_report_view.xml', + ], + 'assets': { + 'web.assets_backend': [ + 'data_chart/static/src/js/data_chart.js', + 'data_chart/static/src/js/jspdf_custom.js', + 'data_chart/static/src/xml/data_chart_templates.xml', + ], + }, + + +} diff --git a/odex30_base/data_chart/data/demo.xml b/odex30_base/data_chart/data/demo.xml new file mode 100644 index 0000000..e671b37 --- /dev/null +++ b/odex30_base/data_chart/data/demo.xml @@ -0,0 +1,44 @@ + + + + + Partners + Partners + model + + + + + city + working city + + + + + + Query Partners + Partners + query + select prt.name as name, prt.city as city from prt; + + + + city + working city + + + + + name + partner name + + + + + prt + + + + + + \ No newline at end of file diff --git a/odex30_base/data_chart/i18n/ar_SY.po b/odex30_base/data_chart/i18n/ar_SY.po new file mode 100644 index 0000000..056a567 --- /dev/null +++ b/odex30_base/data_chart/i18n/ar_SY.po @@ -0,0 +1,262 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * data_chart +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-06-15 11:38+0000\n" +"PO-Revision-Date: 2019-06-15 11: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: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_report_action_id +msgid "Action" +msgstr "الإجراء" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_report_report_names +msgid "Cols Names" +msgstr "أسماء اﻷعمدة" + +#. module: data_chart +#: model:ir.ui.view,arch_db:data_chart.data_chart_report_view_form +msgid "Create Menu" +msgstr "إنشاء القائمة" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_data_item_create_uid +#: model:ir.model.fields,field_description:data_chart.field_data_chart_model_create_uid +#: model:ir.model.fields,field_description:data_chart.field_data_chart_report_create_uid +#: model:ir.model.fields,field_description:data_chart.field_report_cols_names_create_uid +msgid "Created by" +msgstr "أنشئ بواسطة" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_data_item_create_date +#: model:ir.model.fields,field_description:data_chart.field_data_chart_model_create_date +#: model:ir.model.fields,field_description:data_chart.field_data_chart_report_create_date +#: model:ir.model.fields,field_description:data_chart.field_report_cols_names_create_date +msgid "Created on" +msgstr "أنشئ في" + +#. module: data_chart +#: model:ir.ui.menu,name:data_chart.data_chart_menu_root +msgid "Data Chart" +msgstr "مخطط البيانات" + +#. module: data_chart +#: model:ir.model,name:data_chart.model_report_cols_names +msgid "Data Chart Data Cols Names" +msgstr "Data Chart Data Cols Names" + +#. module: data_chart +#: model:ir.model,name:data_chart.model_data_chart_data_item +msgid "Data Chart Data Item" +msgstr "Data Chart Data Item" + +#. module: data_chart +#: model:ir.model,name:data_chart.model_data_chart_report +msgid "Data Chart Report" +msgstr "Data Chart Report" + +#. module: data_chart +#: model:ir.ui.view,arch_db:data_chart.data_chart_report_view_form +msgid "Data Items" +msgstr "وحدات بيانات" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_data_item_data_item +msgid "Data node" +msgstr "وحدة بيانات" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_basemodel_extend_custom_data_chart_display_name +#: model:ir.model.fields,field_description:data_chart.field_data_chart_data_item_display_name +#: model:ir.model.fields,field_description:data_chart.field_data_chart_model_display_name +#: model:ir.model.fields,field_description:data_chart.field_data_chart_report_display_name +#: model:ir.model.fields,field_description:data_chart.field_report_cols_names_d_name +#: model:ir.model.fields,field_description:data_chart.field_report_cols_names_display_name +msgid "Display Name" +msgstr "الاسم المعروض" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_report_footer +msgid "Footer" +msgstr "Footer" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_report_groups_ids +#: model:ir.ui.view,arch_db:data_chart.data_chart_report_view_form +msgid "Groups" +msgstr "المجموعات" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_report_header +msgid "Header" +msgstr "Header" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_basemodel_extend_custom_data_chart_id +#: model:ir.model.fields,field_description:data_chart.field_data_chart_data_item_id +#: model:ir.model.fields,field_description:data_chart.field_data_chart_model_id +#: model:ir.model.fields,field_description:data_chart.field_data_chart_report_id +#: model:ir.model.fields,field_description:data_chart.field_report_cols_names_id +msgid "ID" +msgstr "المعرف" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_basemodel_extend_custom_data_chart___last_update +#: model:ir.model.fields,field_description:data_chart.field_data_chart_data_item___last_update +#: model:ir.model.fields,field_description:data_chart.field_data_chart_model___last_update +#: model:ir.model.fields,field_description:data_chart.field_data_chart_report___last_update +#: model:ir.model.fields,field_description:data_chart.field_report_cols_names___last_update +msgid "Last Modified on" +msgstr "آخر تعديل في" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_data_item_write_uid +#: model:ir.model.fields,field_description:data_chart.field_data_chart_model_write_uid +#: model:ir.model.fields,field_description:data_chart.field_data_chart_report_write_uid +#: model:ir.model.fields,field_description:data_chart.field_report_cols_names_write_uid +msgid "Last Updated by" +msgstr "آخر تحديث بواسطة" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_data_item_write_date +#: model:ir.model.fields,field_description:data_chart.field_data_chart_model_write_date +#: model:ir.model.fields,field_description:data_chart.field_data_chart_report_write_date +#: model:ir.model.fields,field_description:data_chart.field_report_cols_names_write_date +msgid "Last Updated on" +msgstr "آخر تحديث في" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_report_menu_id +msgid "Menu" +msgstr "القائمة" + +#. module: data_chart +#: selection:data.chart.report,type:0 +#: model:ir.model.fields,field_description:data_chart.field_data_chart_model_model +#: model:ir.model.fields,field_description:data_chart.field_data_chart_report_model_id +msgid "Model" +msgstr "النموذج" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_report_data_items_ids +msgid "Models" +msgstr "نماذج" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_data_item_name +#: model:ir.model.fields,field_description:data_chart.field_data_chart_report_name +msgid "Name" +msgstr "اﻹسم" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_model_options +msgid "Options" +msgstr "خيارات" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_report_parent_menu_id +msgid "Parent Menu" +msgstr "القائمة الأصل" + +#. module: data_chart +#: selection:data.chart.report,type:0 +#: model:ir.model.fields,field_description:data_chart.field_data_chart_report_query +msgid "Query" +msgstr "Query" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_data_item_report_id +#: model:ir.model.fields,field_description:data_chart.field_report_cols_names_report_id +msgid "Report" +msgstr "التقرير" + +#. module: data_chart +#: model:ir.ui.view,arch_db:data_chart.data_chart_report_view_form +msgid "Report Columns Names" +msgstr "أسماء اﻷعمدة في التقرير" + +#. module: data_chart +#: model:ir.ui.view,arch_db:data_chart.data_chart_report_view_form +msgid "Report Data" +msgstr "Report Data" + +#. module: data_chart +#: model:ir.ui.menu,name:data_chart.data_chart_menu +msgid "Reports" +msgstr "التقارير" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_model_res_id +msgid "Res" +msgstr "Res" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_report_seq +msgid "Sequence" +msgstr "التسلسل" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_report_cols_names_t_name +msgid "Technical Name" +msgstr "الاسم التقني" + +#. module: data_chart +#: model:ir.ui.view,arch_db:data_chart.data_chart_report_view_form +msgid "Test Data" +msgstr "أختبار البيانات" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_report_title +msgid "Title" +msgstr "العنوان" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_report_type +msgid "Type" +msgstr "نوع الحساب الرئيس" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_model_user_id +msgid "User" +msgstr "المستخدم" + +#. module: data_chart +#: model:ir.model,name:data_chart.model_basemodel_extend_custom_data_chart +msgid "basemodel.extend_custom_data_chart" +msgstr "basemodel.extend_custom_data_chart" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_model_conditions +msgid "conditions" +msgstr "الشروط" + +#. module: data_chart +#: model:ir.actions.act_window,name:data_chart.data_chart_report_action +msgid "data.chart.report.action" +msgstr "data.chart.report.action" + +#. module: data_chart +#: model:ir.model,name:data_chart.model_data_chart_model +msgid "data_chart_model" +msgstr "data_chart_model" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_model_formats +msgid "formats" +msgstr "formats" + +#. module: data_chart +#: model:ir.model.fields,field_description:data_chart.field_data_chart_model_slice +msgid "slice" +msgstr "slice" diff --git a/odex30_base/data_chart/models/__init__.py b/odex30_base/data_chart/models/__init__.py new file mode 100644 index 0000000..066e62c --- /dev/null +++ b/odex30_base/data_chart/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + +from . import data_chart +from . import models_custom diff --git a/odex30_base/data_chart/models/data_chart.py b/odex30_base/data_chart/models/data_chart.py new file mode 100644 index 0000000..a06efab --- /dev/null +++ b/odex30_base/data_chart/models/data_chart.py @@ -0,0 +1,689 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Expert Co. Ltd. +# Copyright (C) 2018 (). +# +############################################################################## +import base64 + +from odoo import models, fields, api, _ + +import datetime + +from odoo.http import request +from itertools import groupby +import time +import sqlite3 +from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT +from odoo.exceptions import ValidationError + +import json + +sqllite_keys = ["ABORT", + "ACTION", + "ADD", + "AFTER", + "ALL", + "ALTER", + "ANALYZE", + "AND", + "AS", + "ASC", + "ATTACH", + "AUTOINCREMENT", + "BEFORE", + "BEGIN", + "BETWEEN", + "BY", + "CASCADE", + "CASE", + "CAST", + "CHECK", + "COLLATE", + "COLUMN", + "COMMIT", + "CONFLICT", + "CONSTRAINT", + "CREATE", + "CROSS", + "CURRENT", + "CURRENT_DATE", + "CURRENT_TIME", + "CURRENT_TIMESTAMP", + "DATABASE", + "DEFAULT", + "DEFERRABLE", + "DEFERRED", + "DELETE", + "DESC", + "DETACH", + "DISTINCT", + "DO", + "DROP", + "EACH", + "ELSE", + "END", + "ESCAPE", + "EXCEPT", + "EXCLUDE", + "EXCLUSIVE", + "EXISTS", + "EXPLAIN", + "FAIL", + "FILTER", + "FOLLOWING", + "FOR", + "FOREIGN", + "FROM", + "FULL", + "GLOB", + "GROUP", + "GROUPS", + "HAVING", + "IF", + "IGNORE", + "IMMEDIATE", + "IN", + "INDEX", + "INDEXED", + "INITIALLY", + "INNER", + "INSERT", + "INSTEAD", + "INTERSECT", + "INTO", + "IS", + "ISNULL", + "JOIN", + "KEY", + "LEFT", + "LIKE", + "LIMIT", + "MATCH", + "NATURAL", + "NO", + "NOT", + "NOTHING", + "NOTNULL", + "NULL", + "OF", + "OFFSET", + "ON", + "OR", + "ORDER", + "OTHERS", + "OUTER", + "OVER", + "PARTITION", + "PLAN", + "PRAGMA", + "PRECEDING", + "PRIMARY", + "QUERY", + "RAISE", + "RANGE", + "RECURSIVE", + "REFERENCES", + "REGEXP", + "REINDEX", + "RELEASE", + "RENAME", + "REPLACE", + "RESTRICT", + "RIGHT", + "ROLLBACK", + "ROW", + "ROWS", + "SAVEPOINT", + "SELECT", + "SET", + "TABLE", + "TEMP", + "TEMPORARY", + "THEN", + "TIES", + "TO", + "TRANSACTION", + "TRIGGER", + "UNBOUNDED", + "UNION", + "UNIQUE", + "UPDATE", + "USING", + "VACUUM", + "VALUES", + "VIEW", + "VIRTUAL", + "WHEN", + "WHERE", + "WINDOW", + "WITH", + "WITHOUT"] + + +class data_chart_report(models.Model): + _name = 'data.chart.report' + _description = 'Data Chart Report' + + name = fields.Char(string='Name', copy=False) + + title = fields.Text(string='Title', copy=False) + + type = fields.Selection( + selection=[('model', 'Model'), + ('query', 'Query')], + string='Type', copy=True) + + header = fields.Html(string='Header') + footer = fields.Html(string='Footer') + + seq = fields.Char(string='Sequence') + + menu_id = fields.Many2one(comodel_name='ir.ui.menu', string='Menu', copy=False) + + parent_menu_id = fields.Many2one(comodel_name='ir.ui.menu', string='Parent Menu') + + action_id = fields.Many2one(comodel_name='ir.actions.client', string='Action', copy=False) + + data_items_ids = fields.One2many(comodel_name='data_chart_data_item', + inverse_name='report_id', string='Models', copy=True) + + report_names = fields.One2many(comodel_name='report_cols_names', + inverse_name='report_id', string='Cols Names', copy=True) + + query = fields.Text(string='Query') + + model_id = fields.Many2one(comodel_name='ir.model', string='Model') + + groups_ids = fields.Many2many(comodel_name='res.groups', string='Groups', copy=True) + + def create_menu(self): + self.ensure_one() + if type == 'query': + self.get_data() + if self.menu_id: + self.menu_id.unlink() + if self.action_id: + self.action_id.unlink() + + if self.type == 'query': + action_id = self.env['ir.actions.client'].create({ + 'name': self.name, + 'tag': 'data_view', + 'context': { + 'model': 'data.chart.report', + 'active_id': self.id, + 'title': self.title, + 'create': False, + }, + 'target': 'current', + }) + else: + action_id = self.env['ir.actions.client'].create({ + 'name': self.name, + 'tag': 'data_view', + 'context': { + 'model': self.model_id.model, + 'active_id': self.id, + 'title': self.title, + 'create': False, + }, + 'target': 'current', + }) + + self.action_id = action_id.id + + menu_id = self.env['ir.ui.menu'].create({ + 'name': self.name, + 'parent_id': self.parent_menu_id and self.parent_menu_id.id or False, + 'action': 'ir.actions.client,%d' % (action_id,), + 'groups_id': [[6, 0, [x.id for x in self.groups_ids]]] + }) + + self.menu_id = menu_id.id + + def show_data(self): + if self.type == 'query': + return { + 'name': self.name, + 'type': 'ir.actions.client', + 'tag': 'data_chart', + 'context': { + 'model': 'data.chart.report', + 'active_id': self.id, + 'title': self.title, + 'admin_view': True, + }, + } + else: + return { + 'name': self.name, + 'tag': 'data_view', + 'context': { + 'model': self.model_id.model, + 'active_id': self.id, + 'title': self.title, + 'admin_view': True, + }, + 'type': 'ir.actions.client', + 'target': 'new', + } + + def get_data(self): + self.ensure_one() + # Create database connection to an in-memory database + + connectionObject = sqlite3.connect(":memory:") + + def display_name(model, field, value): + try: + # context = {'lang': user.lang} + # self.env = self.env(context=context) + data_items = self.data_items_ids.filtered(lambda x: x.name == model) + if data_items: + data_item = data_items[0] + + model_id = data_item.data_item + + model = model_id.model + if self.env[model]._fields[field].type == 'selection': + value = dict(self.env[model]._fields[field]._description_selection( + self.env))[value] + except: + return value + return value + + connectionObject.create_function("display_name", 3, display_name) + + connectionObject.row_factory = dict_factory + # Obtain a cursor object + + cursorObject = connectionObject.cursor() + + # Create a table in the in-memory database + + for data_item in self.data_items_ids: + model = table = False + + # if data_item.data_item.startswith('model_'): + # model = data_item.data_item.replace('model_', '', 1) + + #model_id = self.env['ir.model'].search([('model', '=', model)]) + model_id = data_item.data_item + model = model_id.model + fields = self.env['ir.model.fields'].search( + [('model_id', 'in', model_id.ids)]) + fields = fields.read(['name', 'field_description', 'ttype']) + + fields_types = {x['name']: x['ttype'] for x in fields} + cols = "" + cols_names = "" + for field in fields_types: + if field.upper() in sqllite_keys: + continue + if fields_types[field] in ['char', 'text', 'selection']: + cols += field + ' text , ' + cols_names += field + ' , ' + elif fields_types[field] in ['integer']: + cols += field + ' int , ' + cols_names += field + ' , ' + elif fields_types[field] in ['float', 'monetary']: + cols += field + ' REAL , ' + cols_names += field + ' , ' + elif fields_types[field] in ['date']: + cols += field + ' DATE , ' + cols_names += field + ' , ' + elif fields_types[field] in ['datetime']: + cols += field + ' datetime , ' + cols_names += field + ' , ' + elif fields_types[field] in ['many2one']: + cols += field + ' int , ' + cols_names += field + ' , ' + elif fields_types[field] in ['boolean']: + cols += field + ' boolean , ' + cols_names += field + ' , ' + createTable = "CREATE TABLE " + data_item.name + " (" + cols[0:-2] + " )" + + cursorObject.execute(createTable) + # insert the data + + data = self.env[model].with_context({'data_chart_search': True}).search([]) + for rec in data: + row = "" + readed = rec.with_context({'data_chart_search': False}).read()[0] + for item in cols_names[0:-3].split(' , '): + item_data = readed.get(item, False) + if item == 'name': + readed['name'] = rec.name_get()[0][1] + if item_data: + row += '"'+str(item_data)+'"' + " , " + if not item_data: + row += '" "' + " , " + + elif fields_types[item] == 'many2one': + if item_data: + row += str(item_data[0]) + " , " + else: + row += 'null' + " , " + elif fields_types[item] in ['char', 'text', 'selection']: + if item_data: + item_data = str(item_data).replace('"', '\'') + row += '"'+str(item_data)+'"' + " , " + if not item_data: + row += '" "' + " , " + + elif fields_types[item] in ['date', 'datetime']: + row += '"'+str(item_data)+'"' + " , " + elif fields_types[item] in ['boolean']: + if item_data: + row += str('1') + " , " + if not item_data: + row += str('0') + " , " + else: + if item_data: + row += str(item_data) + " , " + if not item_data: + row += 'null' + " , " + + insertValues = """INSERT INTO """ + data_item.name + \ + """( """ + cols_names[0:-3] + """ )""" + """ values(""" + row[0:-3] + """ )""" + cursorObject.execute(insertValues) + + queryTable = self.query + + queryResults = cursorObject.execute(queryTable) + + data = queryResults.fetchall() + + report_names = self.report_names + + #report_names = {x.d_name: x.t_name for x in report_names} + + report_names = {x.t_name: x.d_name for x in report_names} + new_data = [] + for rec in data: + new_rec = rec + for item in list(filter(lambda x: x in report_names, rec.keys())): + new_rec[report_names[item]] = rec[item] + del new_rec[item] + + new_data.append(new_rec) + + connectionObject.close() + return new_data + + +class data_chart_report_models(models.Model): + _name = 'data_chart_data_item' + _description = 'Data Chart Data Item' + + def _get_models_tables(self): + ir_model_relation = self.env['ir.model.relation'].search([]) + ir_model_relation = ir_model_relation.read(['name']) + ir_model_relation = [('rel'+'_'+x['name'], x['name']) for x in ir_model_relation] + + ir_model = self.env['ir.model'].search([]) + ir_model = ir_model.read(['model', 'name']) + ir_model = [('model'+'_'+x['model'], x['name']+'_'+x['model']) for x in ir_model] + + return ir_model_relation + ir_model + + data_item = fields.Many2one('ir.model', string='Data node') + + name = fields.Char(string='Name') + + report_id = fields.Many2one(comodel_name='data.chart.report', string='Report') + + +class report_cols_names(models.Model): + _name = 'report_cols_names' + _description = 'Data Chart Data Cols Names' + + t_name = fields.Char(string='Technical Name') + d_name = fields.Char(string='Display Name') + report_id = fields.Many2one(comodel_name='data.chart.report', string='Report') + + +class data_chart_model(models.Model): + _name = 'data_chart_model' + + model = fields.Char(string='Model') + user_id = fields.Many2one(comodel_name='res.users', string='User') + res_id = fields.Integer() + + options = fields.Text(string='Options') + slice = fields.Text(string='slice') + conditions = fields.Text(string='conditions') + formats = fields.Text(string='formats') + cols_types = fields.Text(string='Column Types') + + @api.model + def data_chart_details(self, model, res_id=False, with_default=False): + try: + return self._data_chart_details(model, res_id, with_default) + except: + raise ValidationError( + _('''ERROR IN REPORT CONFIGURATION ! ''')) + + @api.model + def _data_chart_details(self, model, res_id=False, with_default=False): + """ + get the list of dicts in sorted oreder to fit in data view + """ + uid = request.session.uid + exist = self.search([('user_id', '=', uid), ('model', '=', model), ('res_id', '=', res_id)]) + + if(with_default) or not exist: + exist = self.search( + [('user_id', '=', False), + ('model', '=', model), + ('res_id', '=', res_id)]) + + company_image = False + header = footer = False + report_names = {} + user = self.env['res.users'].search([('id', '=', uid)]) + if user: + company_image = ""+str(user.company_id.logo, 'utf-8', 'ignore')+"" + context = {'lang': user.lang} + self.env = self.env(context=context) + + if res_id and model == 'data.chart.report': + data_object = self.env[model].search( + [('id', '=', res_id)]) + data = data_object.get_data() + cols_types = self.get_data_types(data) + # for a dum reason + cols_types = json.dumps(cols_types) + header = data_object.header + footer = data_object.footer + + if exist: + return {'data': data, 'options': exist.options, + 'slice': exist.slice, 'conditions': exist.conditions, 'formats': exist.formats, + 'cols_types': exist.cols_types and exist.cols_types or cols_types, + 'header': header, 'footer': footer, 'company_image': company_image} + else: + return {'data': data, 'header': header, 'footer': footer, 'cols_types': cols_types, 'company_image': company_image} + + if res_id and model != 'data.chart.report': + data_object = self.env['data.chart.report'].search( + [('id', '=', res_id)]) + + data = self.env[model].search([]) + header = data_object.header + footer = data_object.footer + + report_names = data_object.report_names + + report_names = {x.t_name: x.d_name for x in report_names} + + else: + data = self.env[model].search([]) + + model_id = self.env['ir.model'].search([('model', '=', model)]) + fields = self.env['ir.model.fields'].search( + [('model_id', 'in', model_id.ids)]) + fields = fields.read(['name', 'field_description', 'ttype']) + + fields_names = {x['name']: x['field_description'] for x in fields} + + fields_types = {x['name']: x['ttype'] for x in fields} + + selectoin_fields = {} + for fff in self.env[model]._fields: + if self.env[model]._fields[fff].type == 'selection': + selectoin_fields[fff] = dict( + self.env[model]._fields[fff]._description_selection(self.env)) + + all_data = [] + cols_types = {} + + cols_in_report = [] + for field in fields_types: + if fields_types[field] in ['char', 'text', 'selection']: + cols_types[field in report_names and report_names[field] + or fields_names[field]] = {'type': 'string'} + cols_in_report.append(field) + elif fields_types[field] in ['integer', 'float', 'monetary']: + cols_types[field in report_names and report_names[field] + or fields_names[field]] = {'type': 'number'} + cols_in_report.append(field) + elif fields_types[field] in ['date']: + cols_types[field in report_names and report_names[field] + or fields_names[field]] = {'type': 'date string'} + cols_in_report.append(field) + elif fields_types[field] in ['datetime']: + cols_types[field in report_names and report_names[field] + or fields_names[field]] = {'type': 'datetime'} + cols_in_report.append(field) + elif fields_types[field] in ['many2one']: + cols_types[field in report_names and report_names[field] + or fields_names[field]] = {'type': 'string'} + cols_in_report.append(field) + + # all_data.append(cols_types) + # for a dum reason + + cols_types = json.dumps(cols_types) + for rec in data: + row = {} + readed = rec.read()[0] + for item in cols_in_report: + if item == 'name': + readed['name'] = rec.name_get()[0][1] + if fields_types[item] == 'many2one': + readed[item] = readed[item] and readed[item][1] or "" + if fields_types[item] == 'selection': + readed[item] = selectoin_fields[item].get(readed[item], "") + row[item in report_names and report_names[item] or fields_names[item]] = readed[item] + + all_data.append(row) + + if exist: + return {'data': all_data, 'options': exist.options, + 'slice': exist.slice, 'conditions': exist.conditions, + 'cols_types': exist.cols_types and exist.cols_types or cols_types, + 'formats': exist.formats, + 'header': header, 'footer': footer, + 'company_image': company_image} + else: + return {'data': all_data, 'company_image': company_image, + 'header': header, 'footer': footer, 'cols_types': cols_types} + + def get_key_type(self, key, data, index): + + if not data[index][key]: + if index + 1 < len(data): + return self.get_key_type(key, data, index + 1) + else: + return {} + # check if the data type is not string + if type(data[index][key]) in [int, float]: + return {'type': 'number'} + + # check date + try: + datetime.datetime.strptime(data[index][key], DEFAULT_SERVER_DATE_FORMAT) + return {'type': 'date string'} + except: + pass + + # check datetime + try: + datetime.datetime.strptime(data[index][key], DEFAULT_SERVER_DATETIME_FORMAT) + return {'type': 'datetime'} + except: + pass + + if data[index][key].isdigit(): + return {'type': 'number'} + + elif data[index][key] != 'null': + return {'type': 'string'} + else: + if index + 1 < len(data): + return self.get_key_type(key, data, index + 1) + else: + return {} + + def get_data_types(self, data): + types_dict = {} + for key in data[0]: + types_dict[key] = self.get_key_type(key, data, 0) + return types_dict + + @api.model + def save_options(self, model, res_id, options, slice, conditions, formats, cols_types): + uid = request.session.uid + exist = self.search([('user_id', '=', uid), ('model', '=', model), ('res_id', '=', res_id)]) + + if exist: + exist.options = options + exist.slice = slice + exist.conditions = conditions + exist.formats = formats + exist.cols_types = cols_types + else: + self.create({ + 'user_id': uid, + 'model': model, + 'res_id': res_id, + 'options': options, + 'slice': slice, + 'conditions': conditions, + 'formats': formats, + 'cols_types': cols_types, + }) + + @api.model + def set_default(self, model, res_id, options, slice, conditions, formats, cols_types): + exist = self.search( + [('user_id', '=', False), + ('model', '=', model), + ('res_id', '=', res_id)]) + if exist: + exist.options = options + exist.slice = slice + exist.conditions = conditions + exist.formats = formats + exist.cols_types = cols_types + else: + self.create({ + 'user_id': False, + 'model': model, + 'res_id': res_id, + 'options': options, + 'slice': slice, + 'conditions': conditions, + 'formats': formats, + 'cols_types': cols_types, + }) + + +def dict_factory(cursor, row): + d = {} + for idx, col in enumerate(cursor.description): + d[col[0]] = row[idx] + return d diff --git a/odex30_base/data_chart/models/models_custom.py b/odex30_base/data_chart/models/models_custom.py new file mode 100644 index 0000000..ece99c6 --- /dev/null +++ b/odex30_base/data_chart/models/models_custom.py @@ -0,0 +1,26 @@ +from odoo import models, fields, api, _ + + +class BaseModelExtend(models.BaseModel): + _name = 'basemodel.extend_custom_data_chart' + + def _register_hook(self): + + @api.model + @api.returns( + 'self', upgrade=lambda self, value, args, offset=0, limit=None, order=None, + count=False: value if count else self.browse(value), downgrade=lambda self, value, args, + offset=0, limit=None, order=None, count=False: value if count else value.ids) + def search(self, args, offset=0, limit=None, order=None, count=False): + context = dict(self.env.context) + if context.get('data_chart_search', False): + res = self._search([], offset=offset, limit=limit, order=order, count=count) + else: + res = self._search(args, offset=offset, limit=limit, order=order, count=count) + + return res if count else self.browse(res) + + +# ------------------------------------------------------- + models.BaseModel.search = search + return super(BaseModelExtend, self)._register_hook() diff --git a/odex30_base/data_chart/security/groups.xml b/odex30_base/data_chart/security/groups.xml new file mode 100644 index 0000000..60d27e1 --- /dev/null +++ b/odex30_base/data_chart/security/groups.xml @@ -0,0 +1,8 @@ + + + + + data visualization manager + + + diff --git a/odex30_base/data_chart/security/ir.model.access.csv b/odex30_base/data_chart/security/ir.model.access.csv new file mode 100644 index 0000000..8a3226e --- /dev/null +++ b/odex30_base/data_chart/security/ir.model.access.csv @@ -0,0 +1,19 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_data_chart_report,access_data_chart_report,model_data_chart_report,base.group_user,1,0,0,0 + +access_report_cols_names,access_report_cols_names,model_report_cols_names,base.group_user,1,0,0,0 + +access_data_chart_model,access_data_chart_model,model_data_chart_model,base.group_user,1,0,0,0 + +access_data_chart_data_item,access_data_chart_data_item,model_data_chart_data_item,base.group_user,1,0,0,0 + + +access_data_chart_report_manager,access_data_chart_report_manager,model_data_chart_report,data_chart.group_data_chart_manager,1,1,1,1 + +access_report_cols_names_manager,access_report_cols_names_manager,model_report_cols_names,data_chart.group_data_chart_manager,1,1,1,1 + +access_data_chart_model_manager,access_data_chart_model_manager,model_data_chart_model,data_chart.group_data_chart_manager,1,1,1,1 + +access_data_chart_data_item_manager,access_data_chart_data_item_manager,model_data_chart_data_item,data_chart.group_data_chart_manager,1,1,1,1 + + diff --git a/odex30_base/data_chart/static/description/all_fields.png b/odex30_base/data_chart/static/description/all_fields.png new file mode 100644 index 0000000..cfa75fb Binary files /dev/null and b/odex30_base/data_chart/static/description/all_fields.png differ diff --git a/odex30_base/data_chart/static/description/calcu.png b/odex30_base/data_chart/static/description/calcu.png new file mode 100644 index 0000000..f1df9e5 Binary files /dev/null and b/odex30_base/data_chart/static/description/calcu.png differ diff --git a/odex30_base/data_chart/static/description/conditional_format.png b/odex30_base/data_chart/static/description/conditional_format.png new file mode 100644 index 0000000..e65f8fc Binary files /dev/null and b/odex30_base/data_chart/static/description/conditional_format.png differ diff --git a/odex30_base/data_chart/static/description/format.png b/odex30_base/data_chart/static/description/format.png new file mode 100644 index 0000000..4cdb41b Binary files /dev/null and b/odex30_base/data_chart/static/description/format.png differ diff --git a/odex30_base/data_chart/static/description/icon.png b/odex30_base/data_chart/static/description/icon.png new file mode 100644 index 0000000..4141f52 Binary files /dev/null and b/odex30_base/data_chart/static/description/icon.png differ diff --git a/odex30_base/data_chart/static/description/index.html b/odex30_base/data_chart/static/description/index.html new file mode 100644 index 0000000..c98fbd7 --- /dev/null +++ b/odex30_base/data_chart/static/description/index.html @@ -0,0 +1,115 @@ +
    +
    +

    Make Aweasome Visualization Of Your Data

    +

    Get data from your models and custom make queries and + Turn + them into data pivot table with tree different layouta

    +
    + +

    + Create new report configuration. +

    +
    +
    + +

    + Test Data to see how the report will be shown. +

    +
    +
    + +

    + add the created report to the selected parent menu. +

    +
    +
    + +
    + + +
    +
    + +
    +
    +

    See What You Want

    +

    Select which Fields To See With The Ordering And Grouping You Want And More ...

    + +
    +

    + set the format of the selected fields. +

    + set the <b>format</b> of the selected fields. +
    + +
    +

    + set the format of the selected fields.. +

    + set the <b>format</b> of the selected fields. +
    + +
    +

    + add new computed Fields with the custom value you want. +

    + add new <b>computed Fields </b> with the <b>custom value</b> you want. +
    + +
    +

    + change the type of data rendered in the view. +

    + change the <b>type of data</b> rendered in the view. +
    + + +
    +

    + change the Layout of the view. +

    + change the <b>Layout</b> of the view. +
    + +
    +
      +
    • +

      + any employee can save his custom design settings. +

      +
    • + +
    • +

      + set default design settings by admin, So you can get back to it by original button. +

      +
    • + +
    +
    + + + + + +
    +
    + +
    +
    +

    Main Technology Used

    + + +

    + for any question about the usage +

    + +
    +
    + + +
    +
    \ No newline at end of file diff --git a/odex30_base/data_chart/static/description/options.png b/odex30_base/data_chart/static/description/options.png new file mode 100644 index 0000000..b4a467f Binary files /dev/null and b/odex30_base/data_chart/static/description/options.png differ diff --git a/odex30_base/data_chart/static/description/page1.png b/odex30_base/data_chart/static/description/page1.png new file mode 100644 index 0000000..7a70cc4 Binary files /dev/null and b/odex30_base/data_chart/static/description/page1.png differ diff --git a/odex30_base/data_chart/static/description/types.png b/odex30_base/data_chart/static/description/types.png new file mode 100644 index 0000000..038184a Binary files /dev/null and b/odex30_base/data_chart/static/description/types.png differ diff --git a/odex30_base/data_chart/static/description/webdatarocks.png b/odex30_base/data_chart/static/description/webdatarocks.png new file mode 100644 index 0000000..b69010d Binary files /dev/null and b/odex30_base/data_chart/static/description/webdatarocks.png differ diff --git a/odex30_base/data_chart/static/fonts/ae_AlMohanad.ttf b/odex30_base/data_chart/static/fonts/ae_AlMohanad.ttf new file mode 100644 index 0000000..bdd7360 Binary files /dev/null and b/odex30_base/data_chart/static/fonts/ae_AlMohanad.ttf differ diff --git a/odex30_base/data_chart/static/src/css/buttons.jqueryui.min.css b/odex30_base/data_chart/static/src/css/buttons.jqueryui.min.css new file mode 100644 index 0000000..436c430 --- /dev/null +++ b/odex30_base/data_chart/static/src/css/buttons.jqueryui.min.css @@ -0,0 +1 @@ +@keyframes dtb-spinner{100%{transform:rotate(360deg)}}@-o-keyframes dtb-spinner{100%{-o-transform:rotate(360deg);transform:rotate(360deg)}}@-ms-keyframes dtb-spinner{100%{-ms-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes dtb-spinner{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes dtb-spinner{100%{-moz-transform:rotate(360deg);transform:rotate(360deg)}}div.dt-button-info{position:fixed;top:50%;left:50%;width:400px;margin-top:-100px;margin-left:-200px;background-color:white;border:2px solid #111;box-shadow:3px 3px 8px rgba(0,0,0,0.3);border-radius:3px;text-align:center;z-index:21}div.dt-button-info h2{padding:0.5em;margin:0;font-weight:normal;border-bottom:1px solid #ddd;background-color:#f3f3f3}div.dt-button-info>div{padding:1em}div.dt-buttons{position:relative;float:left}div.dt-buttons .dt-button{margin-right:0}div.dt-buttons .dt-button span.ui-icon{display:inline-block;vertical-align:middle;margin-top:-2px}div.dt-buttons .dt-button:active{outline:none}div.dt-buttons .dt-button:hover>span{background-color:rgba(0,0,0,0.05)}div.dt-button-collection{position:absolute;top:0;left:0;width:150px;margin-top:3px;padding:8px 8px 4px 8px;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.4);background-color:#f3f3f3;background-color:rgba(255,255,255,0.3);overflow:hidden;z-index:2002;border-radius:5px;box-shadow:3px 3px 5px rgba(0,0,0,0.3);z-index:2002;-webkit-column-gap:8px;-moz-column-gap:8px;-ms-column-gap:8px;-o-column-gap:8px;column-gap:8px;-webkit-column-gap:0;-moz-column-gap:0;-ms-column-gap:0;-o-column-gap:0;column-gap:0}div.dt-button-collection .dt-button{position:relative;left:0;right:0;width:100%;display:block;float:none;margin-right:0;margin-bottom:4px}div.dt-button-collection .dt-button:hover>span{background-color:rgba(0,0,0,0.05)}div.dt-button-collection.fixed{position:fixed;top:50%;left:50%;margin-left:-75px;border-radius:0}div.dt-button-collection.fixed.two-column{margin-left:-150px}div.dt-button-collection.fixed.three-column{margin-left:-225px}div.dt-button-collection.fixed.four-column{margin-left:-300px}div.dt-button-collection>*{-webkit-column-break-inside:avoid;break-inside:avoid}div.dt-button-collection.two-column{width:300px;padding-bottom:1px;-webkit-column-count:2;-moz-column-count:2;-ms-column-count:2;-o-column-count:2;column-count:2}div.dt-button-collection.three-column{width:450px;padding-bottom:1px;-webkit-column-count:3;-moz-column-count:3;-ms-column-count:3;-o-column-count:3;column-count:3}div.dt-button-collection.four-column{width:600px;padding-bottom:1px;-webkit-column-count:4;-moz-column-count:4;-ms-column-count:4;-o-column-count:4;column-count:4}div.dt-button-collection .dt-button{border-radius:0}div.dt-button-background{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.7);background:-ms-radial-gradient(center, ellipse farthest-corner, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.7) 100%);background:-moz-radial-gradient(center, ellipse farthest-corner, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.7) 100%);background:-o-radial-gradient(center, ellipse farthest-corner, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.7) 100%);background:-webkit-gradient(radial, center center, 0, center center, 497, color-stop(0, rgba(0,0,0,0.3)), color-stop(1, rgba(0,0,0,0.7)));background:-webkit-radial-gradient(center, ellipse farthest-corner, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.7) 100%);background:radial-gradient(ellipse farthest-corner at center, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.7) 100%);z-index:2001}@media screen and (max-width: 640px){div.dt-buttons{float:none !important;text-align:center}}button.dt-button.processing,div.dt-button.processing,a.dt-button.processing{color:rgba(0,0,0,0.2)}button.dt-button.processing:after,div.dt-button.processing:after,a.dt-button.processing:after{position:absolute;top:50%;left:50%;width:16px;height:16px;margin:-8px 0 0 -8px;box-sizing:border-box;display:block;content:' ';border:2px solid #282828;border-radius:50%;border-left-color:transparent;border-right-color:transparent;animation:dtb-spinner 1500ms infinite linear;-o-animation:dtb-spinner 1500ms infinite linear;-ms-animation:dtb-spinner 1500ms infinite linear;-webkit-animation:dtb-spinner 1500ms infinite linear;-moz-animation:dtb-spinner 1500ms infinite linear} \ No newline at end of file diff --git a/odex30_base/data_chart/static/src/css/dataTables.jqueryui.min.css b/odex30_base/data_chart/static/src/css/dataTables.jqueryui.min.css new file mode 100644 index 0000000..6025963 --- /dev/null +++ b/odex30_base/data_chart/static/src/css/dataTables.jqueryui.min.css @@ -0,0 +1 @@ +table.dataTable{width:100%;margin:0 auto;clear:both;border-collapse:separate;border-spacing:0}table.dataTable thead th,table.dataTable tfoot th{font-weight:bold}table.dataTable thead th,table.dataTable thead td{padding:10px 18px}table.dataTable thead th:active,table.dataTable thead td:active{outline:none}table.dataTable tfoot th,table.dataTable tfoot td{padding:10px 18px 6px 18px}table.dataTable tbody tr{background-color:#ffffff}table.dataTable tbody tr.selected{background-color:#B0BED9}table.dataTable tbody th,table.dataTable tbody td{padding:8px 10px}table.dataTable.row-border tbody th,table.dataTable.row-border tbody td,table.dataTable.display tbody th,table.dataTable.display tbody td{border-top:1px solid #ddd}table.dataTable.row-border tbody tr:first-child th,table.dataTable.row-border tbody tr:first-child td,table.dataTable.display tbody tr:first-child th,table.dataTable.display tbody tr:first-child td{border-top:none}table.dataTable.cell-border tbody th,table.dataTable.cell-border tbody td{border-top:1px solid #ddd;border-right:1px solid #ddd}table.dataTable.cell-border tbody tr th:first-child,table.dataTable.cell-border tbody tr td:first-child{border-left:1px solid #ddd}table.dataTable.cell-border tbody tr:first-child th,table.dataTable.cell-border tbody tr:first-child td{border-top:none}table.dataTable.stripe tbody tr.odd,table.dataTable.display tbody tr.odd{background-color:#f9f9f9}table.dataTable.stripe tbody tr.odd.selected,table.dataTable.display tbody tr.odd.selected{background-color:#acbad4}table.dataTable.hover tbody tr:hover,table.dataTable.display tbody tr:hover{background-color:#f6f6f6}table.dataTable.hover tbody tr:hover.selected,table.dataTable.display tbody tr:hover.selected{background-color:#aab7d1}table.dataTable.order-column tbody tr>.sorting_1,table.dataTable.order-column tbody tr>.sorting_2,table.dataTable.order-column tbody tr>.sorting_3,table.dataTable.display tbody tr>.sorting_1,table.dataTable.display tbody tr>.sorting_2,table.dataTable.display tbody tr>.sorting_3{background-color:#fafafa}table.dataTable.order-column tbody tr.selected>.sorting_1,table.dataTable.order-column tbody tr.selected>.sorting_2,table.dataTable.order-column tbody tr.selected>.sorting_3,table.dataTable.display tbody tr.selected>.sorting_1,table.dataTable.display tbody tr.selected>.sorting_2,table.dataTable.display tbody tr.selected>.sorting_3{background-color:#acbad5}table.dataTable.display tbody tr.odd>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd>.sorting_1{background-color:#f1f1f1}table.dataTable.display tbody tr.odd>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd>.sorting_2{background-color:#f3f3f3}table.dataTable.display tbody tr.odd>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd>.sorting_3{background-color:whitesmoke}table.dataTable.display tbody tr.odd.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_1{background-color:#a6b4cd}table.dataTable.display tbody tr.odd.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_2{background-color:#a8b5cf}table.dataTable.display tbody tr.odd.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_3{background-color:#a9b7d1}table.dataTable.display tbody tr.even>.sorting_1,table.dataTable.order-column.stripe tbody tr.even>.sorting_1{background-color:#fafafa}table.dataTable.display tbody tr.even>.sorting_2,table.dataTable.order-column.stripe tbody tr.even>.sorting_2{background-color:#fcfcfc}table.dataTable.display tbody tr.even>.sorting_3,table.dataTable.order-column.stripe tbody tr.even>.sorting_3{background-color:#fefefe}table.dataTable.display tbody tr.even.selected>.sorting_1,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_1{background-color:#acbad5}table.dataTable.display tbody tr.even.selected>.sorting_2,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_2{background-color:#aebcd6}table.dataTable.display tbody tr.even.selected>.sorting_3,table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_3{background-color:#afbdd8}table.dataTable.display tbody tr:hover>.sorting_1,table.dataTable.order-column.hover tbody tr:hover>.sorting_1{background-color:#eaeaea}table.dataTable.display tbody tr:hover>.sorting_2,table.dataTable.order-column.hover tbody tr:hover>.sorting_2{background-color:#ececec}table.dataTable.display tbody tr:hover>.sorting_3,table.dataTable.order-column.hover tbody tr:hover>.sorting_3{background-color:#efefef}table.dataTable.display tbody tr:hover.selected>.sorting_1,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_1{background-color:#a2aec7}table.dataTable.display tbody tr:hover.selected>.sorting_2,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_2{background-color:#a3b0c9}table.dataTable.display tbody tr:hover.selected>.sorting_3,table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_3{background-color:#a5b2cb}table.dataTable.no-footer{border-bottom:1px solid #111}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}table.dataTable.compact thead th,table.dataTable.compact thead td{padding:4px 17px 4px 4px}table.dataTable.compact tfoot th,table.dataTable.compact tfoot td{padding:4px}table.dataTable.compact tbody th,table.dataTable.compact tbody td{padding:4px}table.dataTable th.dt-left,table.dataTable td.dt-left{text-align:left}table.dataTable th.dt-center,table.dataTable td.dt-center,table.dataTable td.dataTables_empty{text-align:center}table.dataTable th.dt-right,table.dataTable td.dt-right{text-align:right}table.dataTable th.dt-justify,table.dataTable td.dt-justify{text-align:justify}table.dataTable th.dt-nowrap,table.dataTable td.dt-nowrap{white-space:nowrap}table.dataTable thead th.dt-head-left,table.dataTable thead td.dt-head-left,table.dataTable tfoot th.dt-head-left,table.dataTable tfoot td.dt-head-left{text-align:left}table.dataTable thead th.dt-head-center,table.dataTable thead td.dt-head-center,table.dataTable tfoot th.dt-head-center,table.dataTable tfoot td.dt-head-center{text-align:center}table.dataTable thead th.dt-head-right,table.dataTable thead td.dt-head-right,table.dataTable tfoot th.dt-head-right,table.dataTable tfoot td.dt-head-right{text-align:right}table.dataTable thead th.dt-head-justify,table.dataTable thead td.dt-head-justify,table.dataTable tfoot th.dt-head-justify,table.dataTable tfoot td.dt-head-justify{text-align:justify}table.dataTable thead th.dt-head-nowrap,table.dataTable thead td.dt-head-nowrap,table.dataTable tfoot th.dt-head-nowrap,table.dataTable tfoot td.dt-head-nowrap{white-space:nowrap}table.dataTable tbody th.dt-body-left,table.dataTable tbody td.dt-body-left{text-align:left}table.dataTable tbody th.dt-body-center,table.dataTable tbody td.dt-body-center{text-align:center}table.dataTable tbody th.dt-body-right,table.dataTable tbody td.dt-body-right{text-align:right}table.dataTable tbody th.dt-body-justify,table.dataTable tbody td.dt-body-justify{text-align:justify}table.dataTable tbody th.dt-body-nowrap,table.dataTable tbody td.dt-body-nowrap{white-space:nowrap}table.dataTable,table.dataTable th,table.dataTable td{box-sizing:content-box}.dataTables_wrapper{position:relative;clear:both;*zoom:1;zoom:1}.dataTables_wrapper .dataTables_length{float:left}.dataTables_wrapper .dataTables_filter{float:right;text-align:right}.dataTables_wrapper .dataTables_filter input{margin-left:0.5em}.dataTables_wrapper .dataTables_info{clear:both;float:left;padding-top:0.755em}.dataTables_wrapper .dataTables_paginate{float:right;text-align:right;padding-top:0.25em}.dataTables_wrapper .dataTables_paginate .paginate_button{box-sizing:border-box;display:inline-block;min-width:1.5em;padding:0.5em 1em;margin-left:2px;text-align:center;text-decoration:none !important;cursor:pointer;*cursor:hand;color:#333 !important;border:1px solid transparent;border-radius:2px}.dataTables_wrapper .dataTables_paginate .paginate_button.current,.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover{color:#333 !important;border:1px solid #979797;background-color:white;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #fff), color-stop(100%, #dcdcdc));background:-webkit-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-moz-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-ms-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:-o-linear-gradient(top, #fff 0%, #dcdcdc 100%);background:linear-gradient(to bottom, #fff 0%, #dcdcdc 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button.disabled,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active{cursor:default;color:#666 !important;border:1px solid transparent;background:transparent;box-shadow:none}.dataTables_wrapper .dataTables_paginate .paginate_button:hover{color:white !important;border:1px solid #111;background-color:#585858;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));background:-webkit-linear-gradient(top, #585858 0%, #111 100%);background:-moz-linear-gradient(top, #585858 0%, #111 100%);background:-ms-linear-gradient(top, #585858 0%, #111 100%);background:-o-linear-gradient(top, #585858 0%, #111 100%);background:linear-gradient(to bottom, #585858 0%, #111 100%)}.dataTables_wrapper .dataTables_paginate .paginate_button:active{outline:none;background-color:#2b2b2b;background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));background:-webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:-o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);background:linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);box-shadow:inset 0 0 3px #111}.dataTables_wrapper .dataTables_paginate .ellipsis{padding:0 1em}.dataTables_wrapper .dataTables_processing{position:absolute;top:50%;left:50%;width:100%;height:40px;margin-left:-50%;margin-top:-25px;padding-top:20px;text-align:center;font-size:1.2em;background-color:white;background:-webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255,255,255,0)), color-stop(25%, rgba(255,255,255,0.9)), color-stop(75%, rgba(255,255,255,0.9)), color-stop(100%, rgba(255,255,255,0)));background:-webkit-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-moz-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-ms-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:-o-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);background:linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%)}.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter,.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_processing,.dataTables_wrapper .dataTables_paginate{color:#333}.dataTables_wrapper .dataTables_scroll{clear:both}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody{*margin-top:-1px;-webkit-overflow-scrolling:touch}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>th,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>td,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>th,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>td{vertical-align:middle}.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>th>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>thead>tr>td>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>th>div.dataTables_sizing,.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody>table>tbody>tr>td>div.dataTables_sizing{height:0;overflow:hidden;margin:0 !important;padding:0 !important}.dataTables_wrapper.no-footer .dataTables_scrollBody{border-bottom:1px solid #111}.dataTables_wrapper.no-footer div.dataTables_scrollHead table.dataTable,.dataTables_wrapper.no-footer div.dataTables_scrollBody>table{border-bottom:none}.dataTables_wrapper:after{visibility:hidden;display:block;content:"";clear:both;height:0}@media screen and (max-width: 767px){.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_paginate{float:none;text-align:center}.dataTables_wrapper .dataTables_paginate{margin-top:0.5em}}@media screen and (max-width: 640px){.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter{float:none;text-align:center}.dataTables_wrapper .dataTables_filter{margin-top:0.5em}}table.dataTable thead th div.DataTables_sort_wrapper{position:relative}table.dataTable thead th div.DataTables_sort_wrapper span{position:absolute;top:50%;margin-top:-8px;right:-18px}table.dataTable thead th.ui-state-default,table.dataTable tfoot th.ui-state-default{border-left-width:0}table.dataTable thead th.ui-state-default:first-child,table.dataTable tfoot th.ui-state-default:first-child{border-left-width:1px}.dataTables_wrapper .dataTables_paginate .fg-button{box-sizing:border-box;display:inline-block;min-width:1.5em;padding:0.5em;margin-left:2px;text-align:center;text-decoration:none !important;cursor:pointer;*cursor:hand;border:1px solid transparent}.dataTables_wrapper .dataTables_paginate .fg-button:active{outline:none}.dataTables_wrapper .dataTables_paginate .fg-button:first-child{border-top-left-radius:3px;border-bottom-left-radius:3px}.dataTables_wrapper .dataTables_paginate .fg-button:last-child{border-top-right-radius:3px;border-bottom-right-radius:3px}.dataTables_wrapper .ui-widget-header{font-weight:normal}.dataTables_wrapper .ui-toolbar{padding:8px}.dataTables_wrapper.no-footer .dataTables_scrollBody{border-bottom:none}.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_filter,.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_processing,.dataTables_wrapper .dataTables_paginate{color:inherit} \ No newline at end of file diff --git a/odex30_base/data_chart/static/src/css/datatables.min.css b/odex30_base/data_chart/static/src/css/datatables.min.css new file mode 100644 index 0000000..d0370e0 --- /dev/null +++ b/odex30_base/data_chart/static/src/css/datatables.min.css @@ -0,0 +1,18 @@ +/* + * This combined file was created by the DataTables downloader builder: + * https://datatables.net/download + * + * To rebuild or modify this file with the latest versions of the included + * software please visit: + * https://datatables.net/download/#bs/dt-1.10.18/b-1.5.4/b-html5-1.5.4 + * + * Included libraries: + * DataTables 1.10.18, Buttons 1.5.4, HTML5 export 1.5.4 + */ + + table.dataTable{clear:both;margin-top:6px !important;margin-bottom:6px !important;max-width:none !important;border-collapse:separate !important}table.dataTable td,table.dataTable th{-webkit-box-sizing:content-box;box-sizing:content-box}table.dataTable td.dataTables_empty,table.dataTable th.dataTables_empty{text-align:center}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}div.dataTables_wrapper div.dataTables_length label{font-weight:normal;text-align:left;white-space:nowrap}div.dataTables_wrapper div.dataTables_length select{width:75px;display:inline-block}div.dataTables_wrapper div.dataTables_filter{text-align:right}div.dataTables_wrapper div.dataTables_filter label{font-weight:normal;white-space:nowrap;text-align:left}div.dataTables_wrapper div.dataTables_filter input{margin-left:0.5em;display:inline-block;width:auto}div.dataTables_wrapper div.dataTables_info{padding-top:8px;white-space:nowrap}div.dataTables_wrapper div.dataTables_paginate{margin:0;white-space:nowrap;text-align:right}div.dataTables_wrapper div.dataTables_paginate ul.pagination{margin:2px 0;white-space:nowrap}div.dataTables_wrapper div.dataTables_processing{position:absolute;top:50%;left:50%;width:200px;margin-left:-100px;margin-top:-26px;text-align:center;padding:1em 0}table.dataTable thead>tr>th.sorting_asc,table.dataTable thead>tr>th.sorting_desc,table.dataTable thead>tr>th.sorting,table.dataTable thead>tr>td.sorting_asc,table.dataTable thead>tr>td.sorting_desc,table.dataTable thead>tr>td.sorting{padding-right:30px}table.dataTable thead>tr>th:active,table.dataTable thead>tr>td:active{outline:none}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc,table.dataTable thead .sorting_asc_disabled,table.dataTable thead .sorting_desc_disabled{cursor:pointer;position:relative}table.dataTable thead .sorting:after,table.dataTable thead .sorting_asc:after,table.dataTable thead .sorting_desc:after,table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:after{position:absolute;bottom:8px;right:8px;display:block;font-family:'Glyphicons Halflings';opacity:0.5}table.dataTable thead .sorting:after{opacity:0.2;content:"\e150"}table.dataTable thead .sorting_asc:after{content:"\e155"}table.dataTable thead .sorting_desc:after{content:"\e156"}table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:after{color:#eee}div.dataTables_scrollHead table.dataTable{margin-bottom:0 !important}div.dataTables_scrollBody>table{border-top:none;margin-top:0 !important;margin-bottom:0 !important}div.dataTables_scrollBody>table>thead .sorting:after,div.dataTables_scrollBody>table>thead .sorting_asc:after,div.dataTables_scrollBody>table>thead .sorting_desc:after{display:none}div.dataTables_scrollBody>table>tbody>tr:first-child>th,div.dataTables_scrollBody>table>tbody>tr:first-child>td{border-top:none}div.dataTables_scrollFoot>.dataTables_scrollFootInner{box-sizing:content-box}div.dataTables_scrollFoot>.dataTables_scrollFootInner>table{margin-top:0 !important;border-top:none}@media screen and (max-width: 767px){div.dataTables_wrapper div.dataTables_length,div.dataTables_wrapper div.dataTables_filter,div.dataTables_wrapper div.dataTables_info,div.dataTables_wrapper div.dataTables_paginate{text-align:center}}table.dataTable.table-condensed>thead>tr>th{padding-right:20px}table.dataTable.table-condensed .sorting:after,table.dataTable.table-condensed .sorting_asc:after,table.dataTable.table-condensed .sorting_desc:after{top:6px;right:6px}table.table-bordered.dataTable th,table.table-bordered.dataTable td{border-left-width:0}table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable td:last-child,table.table-bordered.dataTable td:last-child{border-right-width:0}table.table-bordered.dataTable tbody th,table.table-bordered.dataTable tbody td{border-bottom-width:0}div.dataTables_scrollHead table.table-bordered{border-bottom-width:0}div.table-responsive>div.dataTables_wrapper>div.row{margin:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^="col-"]:first-child{padding-left:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^="col-"]:last-child{padding-right:0} + + + @keyframes dtb-spinner{100%{transform:rotate(360deg)}}@-o-keyframes dtb-spinner{100%{-o-transform:rotate(360deg);transform:rotate(360deg)}}@-ms-keyframes dtb-spinner{100%{-ms-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes dtb-spinner{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes dtb-spinner{100%{-moz-transform:rotate(360deg);transform:rotate(360deg)}}div.dt-button-info{position:fixed;top:50%;left:50%;width:400px;margin-top:-100px;margin-left:-200px;background-color:white;border:2px solid #111;box-shadow:3px 3px 8px rgba(0,0,0,0.3);border-radius:3px;text-align:center;z-index:21}div.dt-button-info h2{padding:0.5em;margin:0;font-weight:normal;border-bottom:1px solid #ddd;background-color:#f3f3f3}div.dt-button-info>div{padding:1em}div.dt-button-collection-title{text-align:center;padding:0.3em 0 0.5em;font-size:0.9em}ul.dt-button-collection.dropdown-menu{display:block;z-index:2002;-webkit-column-gap:8px;-moz-column-gap:8px;-ms-column-gap:8px;-o-column-gap:8px;column-gap:8px}ul.dt-button-collection.dropdown-menu.fixed{position:fixed;top:50%;left:50%;margin-left:-75px;border-radius:0}ul.dt-button-collection.dropdown-menu.fixed.two-column{margin-left:-150px}ul.dt-button-collection.dropdown-menu.fixed.three-column{margin-left:-225px}ul.dt-button-collection.dropdown-menu.fixed.four-column{margin-left:-300px}ul.dt-button-collection.dropdown-menu>*{-webkit-column-break-inside:avoid;break-inside:avoid}ul.dt-button-collection.dropdown-menu.two-column{width:300px;padding-bottom:1px;-webkit-column-count:2;-moz-column-count:2;-ms-column-count:2;-o-column-count:2;column-count:2}ul.dt-button-collection.dropdown-menu.three-column{width:450px;padding-bottom:1px;-webkit-column-count:3;-moz-column-count:3;-ms-column-count:3;-o-column-count:3;column-count:3}ul.dt-button-collection.dropdown-menu.four-column{width:600px;padding-bottom:1px;-webkit-column-count:4;-moz-column-count:4;-ms-column-count:4;-o-column-count:4;column-count:4}ul.dt-button-collection.dropdown-menu .dt-button{border-radius:0}div.dt-button-background{position:fixed;top:0;left:0;width:100%;height:100%;z-index:2001}@media screen and (max-width: 767px){div.dt-buttons{float:none;width:100%;text-align:center;margin-bottom:0.5em}div.dt-buttons a.btn{float:none}}div.dt-buttons button.btn.processing,div.dt-buttons div.btn.processing,div.dt-buttons a.btn.processing{color:rgba(0,0,0,0.2)}div.dt-buttons button.btn.processing:after,div.dt-buttons div.btn.processing:after,div.dt-buttons a.btn.processing:after{position:absolute;top:50%;left:50%;width:16px;height:16px;margin:-8px 0 0 -8px;box-sizing:border-box;display:block;content:' ';border:2px solid #282828;border-radius:50%;border-left-color:transparent;border-right-color:transparent;animation:dtb-spinner 1500ms infinite linear;-o-animation:dtb-spinner 1500ms infinite linear;-ms-animation:dtb-spinner 1500ms infinite linear;-webkit-animation:dtb-spinner 1500ms infinite linear;-moz-animation:dtb-spinner 1500ms infinite linear} + + \ No newline at end of file diff --git a/odex30_base/data_chart/static/src/css/jquery-simple-tree-table.css b/odex30_base/data_chart/static/src/css/jquery-simple-tree-table.css new file mode 100644 index 0000000..103d3a4 --- /dev/null +++ b/odex30_base/data_chart/static/src/css/jquery-simple-tree-table.css @@ -0,0 +1 @@ +table.simple-tree-table span.tree-icon{display:inline-block;width:12px;margin:5px;padding:0 5px}table.simple-tree-table span.tree-closed,table.simple-tree-table span.tree-opened{background-color:#eee;text-align:center;cursor:pointer}table.simple-tree-table span.tree-icon.tree-opened:after{content:"-"}table.simple-tree-table span.tree-icon.tree-closed:after{content:"+"} \ No newline at end of file diff --git a/odex30_base/data_chart/static/src/css/themes/default-dark/32px.png b/odex30_base/data_chart/static/src/css/themes/default-dark/32px.png new file mode 100644 index 0000000..6039572 Binary files /dev/null and b/odex30_base/data_chart/static/src/css/themes/default-dark/32px.png differ diff --git a/odex30_base/data_chart/static/src/css/themes/default-dark/40px.png b/odex30_base/data_chart/static/src/css/themes/default-dark/40px.png new file mode 100644 index 0000000..aae89ad Binary files /dev/null and b/odex30_base/data_chart/static/src/css/themes/default-dark/40px.png differ diff --git a/odex30_base/data_chart/static/src/css/themes/default-dark/style.css b/odex30_base/data_chart/static/src/css/themes/default-dark/style.css new file mode 100644 index 0000000..d8dc188 --- /dev/null +++ b/odex30_base/data_chart/static/src/css/themes/default-dark/style.css @@ -0,0 +1,1146 @@ +/* jsTree default dark theme */ +.jstree-node, +.jstree-children, +.jstree-container-ul { + display: block; + margin: 0; + padding: 0; + list-style-type: none; + list-style-image: none; +} +.jstree-node { + white-space: nowrap; +} +.jstree-anchor { + display: inline-block; + color: black; + white-space: nowrap; + padding: 0 4px 0 1px; + margin: 0; + vertical-align: top; +} +.jstree-anchor:focus { + outline: 0; +} +.jstree-anchor, +.jstree-anchor:link, +.jstree-anchor:visited, +.jstree-anchor:hover, +.jstree-anchor:active { + text-decoration: none; + color: inherit; +} +.jstree-icon { + display: inline-block; + text-decoration: none; + margin: 0; + padding: 0; + vertical-align: top; + text-align: center; +} +.jstree-icon:empty { + display: inline-block; + text-decoration: none; + margin: 0; + padding: 0; + vertical-align: top; + text-align: center; +} +.jstree-ocl { + cursor: pointer; +} +.jstree-leaf > .jstree-ocl { + cursor: default; +} +.jstree .jstree-open > .jstree-children { + display: block; +} +.jstree .jstree-closed > .jstree-children, +.jstree .jstree-leaf > .jstree-children { + display: none; +} +.jstree-anchor > .jstree-themeicon { + margin-right: 2px; +} +.jstree-no-icons .jstree-themeicon, +.jstree-anchor > .jstree-themeicon-hidden { + display: none; +} +.jstree-hidden, +.jstree-node.jstree-hidden { + display: none; +} +.jstree-rtl .jstree-anchor { + padding: 0 1px 0 4px; +} +.jstree-rtl .jstree-anchor > .jstree-themeicon { + margin-left: 2px; + margin-right: 0; +} +.jstree-rtl .jstree-node { + margin-left: 0; +} +.jstree-rtl .jstree-container-ul > .jstree-node { + margin-right: 0; +} +.jstree-wholerow-ul { + position: relative; + display: inline-block; + min-width: 100%; +} +.jstree-wholerow-ul .jstree-leaf > .jstree-ocl { + cursor: pointer; +} +.jstree-wholerow-ul .jstree-anchor, +.jstree-wholerow-ul .jstree-icon { + position: relative; +} +.jstree-wholerow-ul .jstree-wholerow { + width: 100%; + cursor: pointer; + position: absolute; + left: 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.jstree-contextmenu .jstree-anchor { + -webkit-user-select: none; + /* disable selection/Copy of UIWebView */ + -webkit-touch-callout: none; + /* disable the IOS popup when long-press on a link */ +} +.vakata-context { + display: none; +} +.vakata-context, +.vakata-context ul { + margin: 0; + padding: 2px; + position: absolute; + background: #f5f5f5; + border: 1px solid #979797; + box-shadow: 2px 2px 2px #999999; +} +.vakata-context ul { + list-style: none; + left: 100%; + margin-top: -2.7em; + margin-left: -4px; +} +.vakata-context .vakata-context-right ul { + left: auto; + right: 100%; + margin-left: auto; + margin-right: -4px; +} +.vakata-context li { + list-style: none; +} +.vakata-context li > a { + display: block; + padding: 0 2em 0 2em; + text-decoration: none; + width: auto; + color: black; + white-space: nowrap; + line-height: 2.4em; + text-shadow: 1px 1px 0 white; + border-radius: 1px; +} +.vakata-context li > a:hover { + position: relative; + background-color: #e8eff7; + box-shadow: 0 0 2px #0a6aa1; +} +.vakata-context li > a.vakata-context-parent { + background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw=="); + background-position: right center; + background-repeat: no-repeat; +} +.vakata-context li > a:focus { + outline: 0; +} +.vakata-context .vakata-context-hover > a { + position: relative; + background-color: #e8eff7; + box-shadow: 0 0 2px #0a6aa1; +} +.vakata-context .vakata-context-separator > a, +.vakata-context .vakata-context-separator > a:hover { + background: white; + border: 0; + border-top: 1px solid #e2e3e3; + height: 1px; + min-height: 1px; + max-height: 1px; + padding: 0; + margin: 0 0 0 2.4em; + border-left: 1px solid #e0e0e0; + text-shadow: 0 0 0 transparent; + box-shadow: 0 0 0 transparent; + border-radius: 0; +} +.vakata-context .vakata-contextmenu-disabled a, +.vakata-context .vakata-contextmenu-disabled a:hover { + color: silver; + background-color: transparent; + border: 0; + box-shadow: 0 0 0; +} +.vakata-context .vakata-contextmenu-disabled > a > i { + filter: grayscale(100%); +} +.vakata-context li > a > i { + text-decoration: none; + display: inline-block; + width: 2.4em; + height: 2.4em; + background: transparent; + margin: 0 0 0 -2em; + vertical-align: top; + text-align: center; + line-height: 2.4em; +} +.vakata-context li > a > i:empty { + width: 2.4em; + line-height: 2.4em; +} +.vakata-context li > a .vakata-contextmenu-sep { + display: inline-block; + width: 1px; + height: 2.4em; + background: white; + margin: 0 0.5em 0 0; + border-left: 1px solid #e2e3e3; +} +.vakata-context .vakata-contextmenu-shortcut { + font-size: 0.8em; + color: silver; + opacity: 0.5; + display: none; +} +.vakata-context-rtl ul { + left: auto; + right: 100%; + margin-left: auto; + margin-right: -4px; +} +.vakata-context-rtl li > a.vakata-context-parent { + background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7"); + background-position: left center; + background-repeat: no-repeat; +} +.vakata-context-rtl .vakata-context-separator > a { + margin: 0 2.4em 0 0; + border-left: 0; + border-right: 1px solid #e2e3e3; +} +.vakata-context-rtl .vakata-context-left ul { + right: auto; + left: 100%; + margin-left: -4px; + margin-right: auto; +} +.vakata-context-rtl li > a > i { + margin: 0 -2em 0 0; +} +.vakata-context-rtl li > a .vakata-contextmenu-sep { + margin: 0 0 0 0.5em; + border-left-color: white; + background: #e2e3e3; +} +#jstree-marker { + position: absolute; + top: 0; + left: 0; + margin: -5px 0 0 0; + padding: 0; + border-right: 0; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid; + width: 0; + height: 0; + font-size: 0; + line-height: 0; +} +#jstree-dnd { + line-height: 16px; + margin: 0; + padding: 4px; +} +#jstree-dnd .jstree-icon, +#jstree-dnd .jstree-copy { + display: inline-block; + text-decoration: none; + margin: 0 2px 0 0; + padding: 0; + width: 16px; + height: 16px; +} +#jstree-dnd .jstree-ok { + background: green; +} +#jstree-dnd .jstree-er { + background: red; +} +#jstree-dnd .jstree-copy { + margin: 0 2px 0 2px; +} +.jstree-default-dark .jstree-node, +.jstree-default-dark .jstree-icon { + background-repeat: no-repeat; + background-color: transparent; +} +.jstree-default-dark .jstree-anchor, +.jstree-default-dark .jstree-animated, +.jstree-default-dark .jstree-wholerow { + transition: background-color 0.15s, box-shadow 0.15s; +} +.jstree-default-dark .jstree-hovered { + background: #555; + border-radius: 2px; + box-shadow: inset 0 0 1px #555; +} +.jstree-default-dark .jstree-context { + background: #555; + border-radius: 2px; + box-shadow: inset 0 0 1px #555; +} +.jstree-default-dark .jstree-clicked { + background: #5fa2db; + border-radius: 2px; + box-shadow: inset 0 0 1px #666666; +} +.jstree-default-dark .jstree-no-icons .jstree-anchor > .jstree-themeicon { + display: none; +} +.jstree-default-dark .jstree-disabled { + background: transparent; + color: #666666; +} +.jstree-default-dark .jstree-disabled.jstree-hovered { + background: transparent; + box-shadow: none; +} +.jstree-default-dark .jstree-disabled.jstree-clicked { + background: #333333; +} +.jstree-default-dark .jstree-disabled > .jstree-icon { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-dark .jstree-search { + font-style: italic; + color: #ffffff; + font-weight: bold; +} +.jstree-default-dark .jstree-no-checkboxes .jstree-checkbox { + display: none !important; +} +.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked { + background: transparent; + box-shadow: none; +} +.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered { + background: #555; +} +.jstree-default-dark.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked { + background: transparent; +} +.jstree-default-dark.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered { + background: #555; +} +.jstree-default-dark > .jstree-striped { + min-width: 100%; + display: inline-block; + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat; +} +.jstree-default-dark > .jstree-wholerow-ul .jstree-hovered, +.jstree-default-dark > .jstree-wholerow-ul .jstree-clicked { + background: transparent; + box-shadow: none; + border-radius: 0; +} +.jstree-default-dark .jstree-wholerow { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} +.jstree-default-dark .jstree-wholerow-hovered { + background: #555; +} +.jstree-default-dark .jstree-wholerow-clicked { + background: #5fa2db; + background: -webkit-linear-gradient(top, #5fa2db 0%, #5fa2db 100%); + background: linear-gradient(to bottom, #5fa2db 0%, #5fa2db 100%); +} +.jstree-default-dark .jstree-node { + min-height: 24px; + line-height: 24px; + margin-left: 24px; + min-width: 24px; +} +.jstree-default-dark .jstree-anchor { + line-height: 24px; + height: 24px; +} +.jstree-default-dark .jstree-icon { + width: 24px; + height: 24px; + line-height: 24px; +} +.jstree-default-dark .jstree-icon:empty { + width: 24px; + height: 24px; + line-height: 24px; +} +.jstree-default-dark.jstree-rtl .jstree-node { + margin-right: 24px; +} +.jstree-default-dark .jstree-wholerow { + height: 24px; +} +.jstree-default-dark .jstree-node, +.jstree-default-dark .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-dark .jstree-node { + background-position: -292px -4px; + background-repeat: repeat-y; +} +.jstree-default-dark .jstree-last { + background: transparent; +} +.jstree-default-dark .jstree-open > .jstree-ocl { + background-position: -132px -4px; +} +.jstree-default-dark .jstree-closed > .jstree-ocl { + background-position: -100px -4px; +} +.jstree-default-dark .jstree-leaf > .jstree-ocl { + background-position: -68px -4px; +} +.jstree-default-dark .jstree-themeicon { + background-position: -260px -4px; +} +.jstree-default-dark > .jstree-no-dots .jstree-node, +.jstree-default-dark > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -36px -4px; +} +.jstree-default-dark > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -4px -4px; +} +.jstree-default-dark .jstree-disabled { + background: transparent; +} +.jstree-default-dark .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-dark .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-dark .jstree-checkbox { + background-position: -164px -4px; +} +.jstree-default-dark .jstree-checkbox:hover { + background-position: -164px -36px; +} +.jstree-default-dark.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-dark .jstree-checked > .jstree-checkbox { + background-position: -228px -4px; +} +.jstree-default-dark.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-dark .jstree-checked > .jstree-checkbox:hover { + background-position: -228px -36px; +} +.jstree-default-dark .jstree-anchor > .jstree-undetermined { + background-position: -196px -4px; +} +.jstree-default-dark .jstree-anchor > .jstree-undetermined:hover { + background-position: -196px -36px; +} +.jstree-default-dark .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-dark > .jstree-striped { + background-size: auto 48px; +} +.jstree-default-dark.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-dark.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -132px -36px; +} +.jstree-default-dark.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -100px -36px; +} +.jstree-default-dark.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -68px -36px; +} +.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -36px -36px; +} +.jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -4px -36px; +} +.jstree-default-dark .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-dark > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-dark .jstree-file { + background: url("32px.png") -100px -68px no-repeat; +} +.jstree-default-dark .jstree-folder { + background: url("32px.png") -260px -4px no-repeat; +} +.jstree-default-dark > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-dark { + line-height: 24px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-dark .jstree-ok, +#jstree-dnd.jstree-default-dark .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-dark i { + background: transparent; + width: 24px; + height: 24px; + line-height: 24px; +} +#jstree-dnd.jstree-default-dark .jstree-ok { + background-position: -4px -68px; +} +#jstree-dnd.jstree-default-dark .jstree-er { + background-position: -36px -68px; +} +.jstree-default-dark .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-dark .jstree-ellipsis .jstree-anchor { + width: calc(100% - 29px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-dark.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); +} +.jstree-default-dark.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-small .jstree-node { + min-height: 18px; + line-height: 18px; + margin-left: 18px; + min-width: 18px; +} +.jstree-default-dark-small .jstree-anchor { + line-height: 18px; + height: 18px; +} +.jstree-default-dark-small .jstree-icon { + width: 18px; + height: 18px; + line-height: 18px; +} +.jstree-default-dark-small .jstree-icon:empty { + width: 18px; + height: 18px; + line-height: 18px; +} +.jstree-default-dark-small.jstree-rtl .jstree-node { + margin-right: 18px; +} +.jstree-default-dark-small .jstree-wholerow { + height: 18px; +} +.jstree-default-dark-small .jstree-node, +.jstree-default-dark-small .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-dark-small .jstree-node { + background-position: -295px -7px; + background-repeat: repeat-y; +} +.jstree-default-dark-small .jstree-last { + background: transparent; +} +.jstree-default-dark-small .jstree-open > .jstree-ocl { + background-position: -135px -7px; +} +.jstree-default-dark-small .jstree-closed > .jstree-ocl { + background-position: -103px -7px; +} +.jstree-default-dark-small .jstree-leaf > .jstree-ocl { + background-position: -71px -7px; +} +.jstree-default-dark-small .jstree-themeicon { + background-position: -263px -7px; +} +.jstree-default-dark-small > .jstree-no-dots .jstree-node, +.jstree-default-dark-small > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark-small > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -39px -7px; +} +.jstree-default-dark-small > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -7px -7px; +} +.jstree-default-dark-small .jstree-disabled { + background: transparent; +} +.jstree-default-dark-small .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-dark-small .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-dark-small .jstree-checkbox { + background-position: -167px -7px; +} +.jstree-default-dark-small .jstree-checkbox:hover { + background-position: -167px -39px; +} +.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-dark-small .jstree-checked > .jstree-checkbox { + background-position: -231px -7px; +} +.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-dark-small .jstree-checked > .jstree-checkbox:hover { + background-position: -231px -39px; +} +.jstree-default-dark-small .jstree-anchor > .jstree-undetermined { + background-position: -199px -7px; +} +.jstree-default-dark-small .jstree-anchor > .jstree-undetermined:hover { + background-position: -199px -39px; +} +.jstree-default-dark-small .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-dark-small > .jstree-striped { + background-size: auto 36px; +} +.jstree-default-dark-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-dark-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-small.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -135px -39px; +} +.jstree-default-dark-small.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -103px -39px; +} +.jstree-default-dark-small.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -71px -39px; +} +.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -39px -39px; +} +.jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -7px -39px; +} +.jstree-default-dark-small .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-dark-small > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-dark-small .jstree-file { + background: url("32px.png") -103px -71px no-repeat; +} +.jstree-default-dark-small .jstree-folder { + background: url("32px.png") -263px -7px no-repeat; +} +.jstree-default-dark-small > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-dark-small { + line-height: 18px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-dark-small .jstree-ok, +#jstree-dnd.jstree-default-dark-small .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-dark-small i { + background: transparent; + width: 18px; + height: 18px; + line-height: 18px; +} +#jstree-dnd.jstree-default-dark-small .jstree-ok { + background-position: -7px -71px; +} +#jstree-dnd.jstree-default-dark-small .jstree-er { + background-position: -39px -71px; +} +.jstree-default-dark-small .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-dark-small .jstree-ellipsis .jstree-anchor { + width: calc(100% - 23px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-dark-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); +} +.jstree-default-dark-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-large .jstree-node { + min-height: 32px; + line-height: 32px; + margin-left: 32px; + min-width: 32px; +} +.jstree-default-dark-large .jstree-anchor { + line-height: 32px; + height: 32px; +} +.jstree-default-dark-large .jstree-icon { + width: 32px; + height: 32px; + line-height: 32px; +} +.jstree-default-dark-large .jstree-icon:empty { + width: 32px; + height: 32px; + line-height: 32px; +} +.jstree-default-dark-large.jstree-rtl .jstree-node { + margin-right: 32px; +} +.jstree-default-dark-large .jstree-wholerow { + height: 32px; +} +.jstree-default-dark-large .jstree-node, +.jstree-default-dark-large .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-dark-large .jstree-node { + background-position: -288px 0px; + background-repeat: repeat-y; +} +.jstree-default-dark-large .jstree-last { + background: transparent; +} +.jstree-default-dark-large .jstree-open > .jstree-ocl { + background-position: -128px 0px; +} +.jstree-default-dark-large .jstree-closed > .jstree-ocl { + background-position: -96px 0px; +} +.jstree-default-dark-large .jstree-leaf > .jstree-ocl { + background-position: -64px 0px; +} +.jstree-default-dark-large .jstree-themeicon { + background-position: -256px 0px; +} +.jstree-default-dark-large > .jstree-no-dots .jstree-node, +.jstree-default-dark-large > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark-large > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -32px 0px; +} +.jstree-default-dark-large > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: 0px 0px; +} +.jstree-default-dark-large .jstree-disabled { + background: transparent; +} +.jstree-default-dark-large .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-dark-large .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-dark-large .jstree-checkbox { + background-position: -160px 0px; +} +.jstree-default-dark-large .jstree-checkbox:hover { + background-position: -160px -32px; +} +.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-dark-large .jstree-checked > .jstree-checkbox { + background-position: -224px 0px; +} +.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-dark-large .jstree-checked > .jstree-checkbox:hover { + background-position: -224px -32px; +} +.jstree-default-dark-large .jstree-anchor > .jstree-undetermined { + background-position: -192px 0px; +} +.jstree-default-dark-large .jstree-anchor > .jstree-undetermined:hover { + background-position: -192px -32px; +} +.jstree-default-dark-large .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-dark-large > .jstree-striped { + background-size: auto 64px; +} +.jstree-default-dark-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-dark-large.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-large.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -128px -32px; +} +.jstree-default-dark-large.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -96px -32px; +} +.jstree-default-dark-large.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -64px -32px; +} +.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -32px -32px; +} +.jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: 0px -32px; +} +.jstree-default-dark-large .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-dark-large > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-dark-large .jstree-file { + background: url("32px.png") -96px -64px no-repeat; +} +.jstree-default-dark-large .jstree-folder { + background: url("32px.png") -256px 0px no-repeat; +} +.jstree-default-dark-large > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-dark-large { + line-height: 32px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-dark-large .jstree-ok, +#jstree-dnd.jstree-default-dark-large .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-dark-large i { + background: transparent; + width: 32px; + height: 32px; + line-height: 32px; +} +#jstree-dnd.jstree-default-dark-large .jstree-ok { + background-position: 0px -64px; +} +#jstree-dnd.jstree-default-dark-large .jstree-er { + background-position: -32px -64px; +} +.jstree-default-dark-large .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-dark-large .jstree-ellipsis .jstree-anchor { + width: calc(100% - 37px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-dark-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); +} +.jstree-default-dark-large.jstree-rtl .jstree-last { + background: transparent; +} +@media (max-width: 768px) { + #jstree-dnd.jstree-dnd-responsive { + line-height: 40px; + font-weight: bold; + font-size: 1.1em; + text-shadow: 1px 1px white; + } + #jstree-dnd.jstree-dnd-responsive > i { + background: transparent; + width: 40px; + height: 40px; + } + #jstree-dnd.jstree-dnd-responsive > .jstree-ok { + background-image: url("40px.png"); + background-position: 0 -200px; + background-size: 120px 240px; + } + #jstree-dnd.jstree-dnd-responsive > .jstree-er { + background-image: url("40px.png"); + background-position: -40px -200px; + background-size: 120px 240px; + } + #jstree-marker.jstree-dnd-responsive { + border-left-width: 10px; + border-top-width: 10px; + border-bottom-width: 10px; + margin-top: -10px; + } +} +@media (max-width: 768px) { + .jstree-default-dark-responsive { + /* + .jstree-open > .jstree-ocl, + .jstree-closed > .jstree-ocl { border-radius:20px; background-color:white; } + */ + } + .jstree-default-dark-responsive .jstree-icon { + background-image: url("40px.png"); + } + .jstree-default-dark-responsive .jstree-node, + .jstree-default-dark-responsive .jstree-leaf > .jstree-ocl { + background: transparent; + } + .jstree-default-dark-responsive .jstree-node { + min-height: 40px; + line-height: 40px; + margin-left: 40px; + min-width: 40px; + white-space: nowrap; + } + .jstree-default-dark-responsive .jstree-anchor { + line-height: 40px; + height: 40px; + } + .jstree-default-dark-responsive .jstree-icon, + .jstree-default-dark-responsive .jstree-icon:empty { + width: 40px; + height: 40px; + line-height: 40px; + } + .jstree-default-dark-responsive > .jstree-container-ul > .jstree-node { + margin-left: 0; + } + .jstree-default-dark-responsive.jstree-rtl .jstree-node { + margin-left: 0; + margin-right: 40px; + background: transparent; + } + .jstree-default-dark-responsive.jstree-rtl .jstree-container-ul > .jstree-node { + margin-right: 0; + } + .jstree-default-dark-responsive .jstree-ocl, + .jstree-default-dark-responsive .jstree-themeicon, + .jstree-default-dark-responsive .jstree-checkbox { + background-size: 120px 240px; + } + .jstree-default-dark-responsive .jstree-leaf > .jstree-ocl, + .jstree-default-dark-responsive.jstree-rtl .jstree-leaf > .jstree-ocl { + background: transparent; + } + .jstree-default-dark-responsive .jstree-open > .jstree-ocl { + background-position: 0 0 !important; + } + .jstree-default-dark-responsive .jstree-closed > .jstree-ocl { + background-position: 0 -40px !important; + } + .jstree-default-dark-responsive.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -40px 0 !important; + } + .jstree-default-dark-responsive .jstree-themeicon { + background-position: -40px -40px; + } + .jstree-default-dark-responsive .jstree-checkbox, + .jstree-default-dark-responsive .jstree-checkbox:hover { + background-position: -40px -80px; + } + .jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, + .jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, + .jstree-default-dark-responsive .jstree-checked > .jstree-checkbox, + .jstree-default-dark-responsive .jstree-checked > .jstree-checkbox:hover { + background-position: 0 -80px; + } + .jstree-default-dark-responsive .jstree-anchor > .jstree-undetermined, + .jstree-default-dark-responsive .jstree-anchor > .jstree-undetermined:hover { + background-position: 0 -120px; + } + .jstree-default-dark-responsive .jstree-anchor { + font-weight: bold; + font-size: 1.1em; + text-shadow: 1px 1px white; + } + .jstree-default-dark-responsive > .jstree-striped { + background: transparent; + } + .jstree-default-dark-responsive .jstree-wholerow { + border-top: 1px solid #666; + border-bottom: 1px solid #000; + background: #333333; + height: 40px; + } + .jstree-default-dark-responsive .jstree-wholerow-hovered { + background: #555; + } + .jstree-default-dark-responsive .jstree-wholerow-clicked { + background: #5fa2db; + } + .jstree-default-dark-responsive .jstree-children .jstree-last > .jstree-wholerow { + box-shadow: inset 0 -6px 3px -5px #111111; + } + .jstree-default-dark-responsive .jstree-children .jstree-open > .jstree-wholerow { + box-shadow: inset 0 6px 3px -5px #111111; + border-top: 0; + } + .jstree-default-dark-responsive .jstree-children .jstree-open + .jstree-open { + box-shadow: none; + } + .jstree-default-dark-responsive .jstree-node, + .jstree-default-dark-responsive .jstree-icon, + .jstree-default-dark-responsive .jstree-node > .jstree-ocl, + .jstree-default-dark-responsive .jstree-themeicon, + .jstree-default-dark-responsive .jstree-checkbox { + background-image: url("40px.png"); + background-size: 120px 240px; + } + .jstree-default-dark-responsive .jstree-node { + background-position: -80px 0; + background-repeat: repeat-y; + } + .jstree-default-dark-responsive .jstree-last { + background: transparent; + } + .jstree-default-dark-responsive .jstree-leaf > .jstree-ocl { + background-position: -40px -120px; + } + .jstree-default-dark-responsive .jstree-last > .jstree-ocl { + background-position: -40px -160px; + } + .jstree-default-dark-responsive .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; + } + .jstree-default-dark-responsive .jstree-file { + background: url("40px.png") 0 -160px no-repeat; + background-size: 120px 240px; + } + .jstree-default-dark-responsive .jstree-folder { + background: url("40px.png") -40px -40px no-repeat; + background-size: 120px 240px; + } + .jstree-default-dark-responsive > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; + } +} +.jstree-default-dark { + background: #333; +} +.jstree-default-dark .jstree-anchor { + color: #999; + text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.5); +} +.jstree-default-dark .jstree-clicked, +.jstree-default-dark .jstree-checked { + color: white; +} +.jstree-default-dark .jstree-hovered { + color: white; +} +#jstree-marker.jstree-default-dark { + border-left-color: #999; + background: transparent; +} +.jstree-default-dark .jstree-anchor > .jstree-icon { + opacity: 0.75; +} +.jstree-default-dark .jstree-clicked > .jstree-icon, +.jstree-default-dark .jstree-hovered > .jstree-icon, +.jstree-default-dark .jstree-checked > .jstree-icon { + opacity: 1; +} +.jstree-default-dark.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); +} +.jstree-default-dark.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); +} +.jstree-default-dark-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-dark-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); +} +.jstree-default-dark-large.jstree-rtl .jstree-last { + background: transparent; +} diff --git a/odex30_base/data_chart/static/src/css/themes/default-dark/style.min.css b/odex30_base/data_chart/static/src/css/themes/default-dark/style.min.css new file mode 100644 index 0000000..fb1d236 --- /dev/null +++ b/odex30_base/data_chart/static/src/css/themes/default-dark/style.min.css @@ -0,0 +1 @@ +.jstree-node,.jstree-children,.jstree-container-ul{display:block;margin:0;padding:0;list-style-type:none;list-style-image:none}.jstree-node{white-space:nowrap}.jstree-anchor{display:inline-block;color:black;white-space:nowrap;padding:0 4px 0 1px;margin:0;vertical-align:top}.jstree-anchor:focus{outline:0}.jstree-anchor,.jstree-anchor:link,.jstree-anchor:visited,.jstree-anchor:hover,.jstree-anchor:active{text-decoration:none;color:inherit}.jstree-icon{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-icon:empty{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-ocl{cursor:pointer}.jstree-leaf>.jstree-ocl{cursor:default}.jstree .jstree-open>.jstree-children{display:block}.jstree .jstree-closed>.jstree-children,.jstree .jstree-leaf>.jstree-children{display:none}.jstree-anchor>.jstree-themeicon{margin-right:2px}.jstree-no-icons .jstree-themeicon,.jstree-anchor>.jstree-themeicon-hidden{display:none}.jstree-hidden,.jstree-node.jstree-hidden{display:none}.jstree-rtl .jstree-anchor{padding:0 1px 0 4px}.jstree-rtl .jstree-anchor>.jstree-themeicon{margin-left:2px;margin-right:0}.jstree-rtl .jstree-node{margin-left:0}.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-wholerow-ul{position:relative;display:inline-block;min-width:100%}.jstree-wholerow-ul .jstree-leaf>.jstree-ocl{cursor:pointer}.jstree-wholerow-ul .jstree-anchor,.jstree-wholerow-ul .jstree-icon{position:relative}.jstree-wholerow-ul .jstree-wholerow{width:100%;cursor:pointer;position:absolute;left:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.jstree-contextmenu .jstree-anchor{-webkit-user-select:none;-webkit-touch-callout:none}.vakata-context{display:none}.vakata-context,.vakata-context ul{margin:0;padding:2px;position:absolute;background:#f5f5f5;border:1px solid #979797;box-shadow:2px 2px 2px #999999}.vakata-context ul{list-style:none;left:100%;margin-top:-2.7em;margin-left:-4px}.vakata-context .vakata-context-right ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context li{list-style:none}.vakata-context li>a{display:block;padding:0 2em 0 2em;text-decoration:none;width:auto;color:black;white-space:nowrap;line-height:2.4em;text-shadow:1px 1px 0 white;border-radius:1px}.vakata-context li>a:hover{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw==");background-position:right center;background-repeat:no-repeat}.vakata-context li>a:focus{outline:0}.vakata-context .vakata-context-hover>a{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context .vakata-context-separator>a,.vakata-context .vakata-context-separator>a:hover{background:white;border:0;border-top:1px solid #e2e3e3;height:1px;min-height:1px;max-height:1px;padding:0;margin:0 0 0 2.4em;border-left:1px solid #e0e0e0;text-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent;border-radius:0}.vakata-context .vakata-contextmenu-disabled a,.vakata-context .vakata-contextmenu-disabled a:hover{color:silver;background-color:transparent;border:0;box-shadow:0 0 0}.vakata-context .vakata-contextmenu-disabled>a>i{filter:grayscale(100%)}.vakata-context li>a>i{text-decoration:none;display:inline-block;width:2.4em;height:2.4em;background:transparent;margin:0 0 0 -2em;vertical-align:top;text-align:center;line-height:2.4em}.vakata-context li>a>i:empty{width:2.4em;line-height:2.4em}.vakata-context li>a .vakata-contextmenu-sep{display:inline-block;width:1px;height:2.4em;background:white;margin:0 .5em 0 0;border-left:1px solid #e2e3e3}.vakata-context .vakata-contextmenu-shortcut{font-size:.8em;color:silver;opacity:.5;display:none}.vakata-context-rtl ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context-rtl li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7");background-position:left center;background-repeat:no-repeat}.vakata-context-rtl .vakata-context-separator>a{margin:0 2.4em 0 0;border-left:0;border-right:1px solid #e2e3e3}.vakata-context-rtl .vakata-context-left ul{right:auto;left:100%;margin-left:-4px;margin-right:auto}.vakata-context-rtl li>a>i{margin:0 -2em 0 0}.vakata-context-rtl li>a .vakata-contextmenu-sep{margin:0 0 0 .5em;border-left-color:white;background:#e2e3e3}#jstree-marker{position:absolute;top:0;left:0;margin:-5px 0 0 0;padding:0;border-right:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid;width:0;height:0;font-size:0;line-height:0}#jstree-dnd{line-height:16px;margin:0;padding:4px}#jstree-dnd .jstree-icon,#jstree-dnd .jstree-copy{display:inline-block;text-decoration:none;margin:0 2px 0 0;padding:0;width:16px;height:16px}#jstree-dnd .jstree-ok{background:green}#jstree-dnd .jstree-er{background:red}#jstree-dnd .jstree-copy{margin:0 2px 0 2px}.jstree-default-dark .jstree-node,.jstree-default-dark .jstree-icon{background-repeat:no-repeat;background-color:transparent}.jstree-default-dark .jstree-anchor,.jstree-default-dark .jstree-animated,.jstree-default-dark .jstree-wholerow{transition:background-color .15s,box-shadow .15s}.jstree-default-dark .jstree-hovered{background:#555;border-radius:2px;box-shadow:inset 0 0 1px #555}.jstree-default-dark .jstree-context{background:#555;border-radius:2px;box-shadow:inset 0 0 1px #555}.jstree-default-dark .jstree-clicked{background:#5fa2db;border-radius:2px;box-shadow:inset 0 0 1px #666666}.jstree-default-dark .jstree-no-icons .jstree-anchor>.jstree-themeicon{display:none}.jstree-default-dark .jstree-disabled{background:transparent;color:#666666}.jstree-default-dark .jstree-disabled.jstree-hovered{background:transparent;box-shadow:none}.jstree-default-dark .jstree-disabled.jstree-clicked{background:#333333}.jstree-default-dark .jstree-disabled>.jstree-icon{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark .jstree-search{font-style:italic;color:#ffffff;font-weight:bold}.jstree-default-dark .jstree-no-checkboxes .jstree-checkbox{display:none !important}.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked{background:transparent;box-shadow:none}.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered{background:#555}.jstree-default-dark.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked{background:transparent}.jstree-default-dark.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered{background:#555}.jstree-default-dark>.jstree-striped{min-width:100%;display:inline-block;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat}.jstree-default-dark>.jstree-wholerow-ul .jstree-hovered,.jstree-default-dark>.jstree-wholerow-ul .jstree-clicked{background:transparent;box-shadow:none;border-radius:0}.jstree-default-dark .jstree-wholerow{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.jstree-default-dark .jstree-wholerow-hovered{background:#555}.jstree-default-dark .jstree-wholerow-clicked{background:#5fa2db;background:-webkit-linear-gradient(top, #5fa2db 0, #5fa2db 100%);background:linear-gradient(to bottom, #5fa2db 0, #5fa2db 100%)}.jstree-default-dark .jstree-node{min-height:24px;line-height:24px;margin-left:24px;min-width:24px}.jstree-default-dark .jstree-anchor{line-height:24px;height:24px}.jstree-default-dark .jstree-icon{width:24px;height:24px;line-height:24px}.jstree-default-dark .jstree-icon:empty{width:24px;height:24px;line-height:24px}.jstree-default-dark.jstree-rtl .jstree-node{margin-right:24px}.jstree-default-dark .jstree-wholerow{height:24px}.jstree-default-dark .jstree-node,.jstree-default-dark .jstree-icon{background-image:url("32px.png")}.jstree-default-dark .jstree-node{background-position:-292px -4px;background-repeat:repeat-y}.jstree-default-dark .jstree-last{background:transparent}.jstree-default-dark .jstree-open>.jstree-ocl{background-position:-132px -4px}.jstree-default-dark .jstree-closed>.jstree-ocl{background-position:-100px -4px}.jstree-default-dark .jstree-leaf>.jstree-ocl{background-position:-68px -4px}.jstree-default-dark .jstree-themeicon{background-position:-260px -4px}.jstree-default-dark>.jstree-no-dots .jstree-node,.jstree-default-dark>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -4px}.jstree-default-dark>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -4px}.jstree-default-dark .jstree-disabled{background:transparent}.jstree-default-dark .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-dark .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-dark .jstree-checkbox{background-position:-164px -4px}.jstree-default-dark .jstree-checkbox:hover{background-position:-164px -36px}.jstree-default-dark.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark .jstree-checked>.jstree-checkbox{background-position:-228px -4px}.jstree-default-dark.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark .jstree-checked>.jstree-checkbox:hover{background-position:-228px -36px}.jstree-default-dark .jstree-anchor>.jstree-undetermined{background-position:-196px -4px}.jstree-default-dark .jstree-anchor>.jstree-undetermined:hover{background-position:-196px -36px}.jstree-default-dark .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark>.jstree-striped{background-size:auto 48px}.jstree-default-dark.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-dark.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark.jstree-rtl .jstree-open>.jstree-ocl{background-position:-132px -36px}.jstree-default-dark.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-100px -36px}.jstree-default-dark.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-68px -36px}.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -36px}.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -36px}.jstree-default-dark .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-dark .jstree-file{background:url("32px.png") -100px -68px no-repeat}.jstree-default-dark .jstree-folder{background:url("32px.png") -260px -4px no-repeat}.jstree-default-dark>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-dark{line-height:24px;padding:0 4px}#jstree-dnd.jstree-default-dark .jstree-ok,#jstree-dnd.jstree-default-dark .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-dark i{background:transparent;width:24px;height:24px;line-height:24px}#jstree-dnd.jstree-default-dark .jstree-ok{background-position:-4px -68px}#jstree-dnd.jstree-default-dark .jstree-er{background-position:-36px -68px}.jstree-default-dark .jstree-ellipsis{overflow:hidden}.jstree-default-dark .jstree-ellipsis .jstree-anchor{width:calc(100% - 29px);text-overflow:ellipsis;overflow:hidden}.jstree-default-dark.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==")}.jstree-default-dark.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-small .jstree-node{min-height:18px;line-height:18px;margin-left:18px;min-width:18px}.jstree-default-dark-small .jstree-anchor{line-height:18px;height:18px}.jstree-default-dark-small .jstree-icon{width:18px;height:18px;line-height:18px}.jstree-default-dark-small .jstree-icon:empty{width:18px;height:18px;line-height:18px}.jstree-default-dark-small.jstree-rtl .jstree-node{margin-right:18px}.jstree-default-dark-small .jstree-wholerow{height:18px}.jstree-default-dark-small .jstree-node,.jstree-default-dark-small .jstree-icon{background-image:url("32px.png")}.jstree-default-dark-small .jstree-node{background-position:-295px -7px;background-repeat:repeat-y}.jstree-default-dark-small .jstree-last{background:transparent}.jstree-default-dark-small .jstree-open>.jstree-ocl{background-position:-135px -7px}.jstree-default-dark-small .jstree-closed>.jstree-ocl{background-position:-103px -7px}.jstree-default-dark-small .jstree-leaf>.jstree-ocl{background-position:-71px -7px}.jstree-default-dark-small .jstree-themeicon{background-position:-263px -7px}.jstree-default-dark-small>.jstree-no-dots .jstree-node,.jstree-default-dark-small>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-small>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -7px}.jstree-default-dark-small>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -7px}.jstree-default-dark-small .jstree-disabled{background:transparent}.jstree-default-dark-small .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-dark-small .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-dark-small .jstree-checkbox{background-position:-167px -7px}.jstree-default-dark-small .jstree-checkbox:hover{background-position:-167px -39px}.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark-small .jstree-checked>.jstree-checkbox{background-position:-231px -7px}.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark-small .jstree-checked>.jstree-checkbox:hover{background-position:-231px -39px}.jstree-default-dark-small .jstree-anchor>.jstree-undetermined{background-position:-199px -7px}.jstree-default-dark-small .jstree-anchor>.jstree-undetermined:hover{background-position:-199px -39px}.jstree-default-dark-small .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark-small>.jstree-striped{background-size:auto 36px}.jstree-default-dark-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-dark-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-small.jstree-rtl .jstree-open>.jstree-ocl{background-position:-135px -39px}.jstree-default-dark-small.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-103px -39px}.jstree-default-dark-small.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-71px -39px}.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -39px}.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -39px}.jstree-default-dark-small .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark-small>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-dark-small .jstree-file{background:url("32px.png") -103px -71px no-repeat}.jstree-default-dark-small .jstree-folder{background:url("32px.png") -263px -7px no-repeat}.jstree-default-dark-small>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-dark-small{line-height:18px;padding:0 4px}#jstree-dnd.jstree-default-dark-small .jstree-ok,#jstree-dnd.jstree-default-dark-small .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-dark-small i{background:transparent;width:18px;height:18px;line-height:18px}#jstree-dnd.jstree-default-dark-small .jstree-ok{background-position:-7px -71px}#jstree-dnd.jstree-default-dark-small .jstree-er{background-position:-39px -71px}.jstree-default-dark-small .jstree-ellipsis{overflow:hidden}.jstree-default-dark-small .jstree-ellipsis .jstree-anchor{width:calc(100% - 23px);text-overflow:ellipsis;overflow:hidden}.jstree-default-dark-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==")}.jstree-default-dark-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-large .jstree-node{min-height:32px;line-height:32px;margin-left:32px;min-width:32px}.jstree-default-dark-large .jstree-anchor{line-height:32px;height:32px}.jstree-default-dark-large .jstree-icon{width:32px;height:32px;line-height:32px}.jstree-default-dark-large .jstree-icon:empty{width:32px;height:32px;line-height:32px}.jstree-default-dark-large.jstree-rtl .jstree-node{margin-right:32px}.jstree-default-dark-large .jstree-wholerow{height:32px}.jstree-default-dark-large .jstree-node,.jstree-default-dark-large .jstree-icon{background-image:url("32px.png")}.jstree-default-dark-large .jstree-node{background-position:-288px 0;background-repeat:repeat-y}.jstree-default-dark-large .jstree-last{background:transparent}.jstree-default-dark-large .jstree-open>.jstree-ocl{background-position:-128px 0}.jstree-default-dark-large .jstree-closed>.jstree-ocl{background-position:-96px 0}.jstree-default-dark-large .jstree-leaf>.jstree-ocl{background-position:-64px 0}.jstree-default-dark-large .jstree-themeicon{background-position:-256px 0}.jstree-default-dark-large>.jstree-no-dots .jstree-node,.jstree-default-dark-large>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-large>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px 0}.jstree-default-dark-large>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 0}.jstree-default-dark-large .jstree-disabled{background:transparent}.jstree-default-dark-large .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-dark-large .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-dark-large .jstree-checkbox{background-position:-160px 0}.jstree-default-dark-large .jstree-checkbox:hover{background-position:-160px -32px}.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark-large .jstree-checked>.jstree-checkbox{background-position:-224px 0}.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark-large .jstree-checked>.jstree-checkbox:hover{background-position:-224px -32px}.jstree-default-dark-large .jstree-anchor>.jstree-undetermined{background-position:-192px 0}.jstree-default-dark-large .jstree-anchor>.jstree-undetermined:hover{background-position:-192px -32px}.jstree-default-dark-large .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark-large>.jstree-striped{background-size:auto 64px}.jstree-default-dark-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-dark-large.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-large.jstree-rtl .jstree-open>.jstree-ocl{background-position:-128px -32px}.jstree-default-dark-large.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-96px -32px}.jstree-default-dark-large.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-64px -32px}.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px -32px}.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 -32px}.jstree-default-dark-large .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark-large>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-dark-large .jstree-file{background:url("32px.png") -96px -64px no-repeat}.jstree-default-dark-large .jstree-folder{background:url("32px.png") -256px 0 no-repeat}.jstree-default-dark-large>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-dark-large{line-height:32px;padding:0 4px}#jstree-dnd.jstree-default-dark-large .jstree-ok,#jstree-dnd.jstree-default-dark-large .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-dark-large i{background:transparent;width:32px;height:32px;line-height:32px}#jstree-dnd.jstree-default-dark-large .jstree-ok{background-position:0 -64px}#jstree-dnd.jstree-default-dark-large .jstree-er{background-position:-32px -64px}.jstree-default-dark-large .jstree-ellipsis{overflow:hidden}.jstree-default-dark-large .jstree-ellipsis .jstree-anchor{width:calc(100% - 37px);text-overflow:ellipsis;overflow:hidden}.jstree-default-dark-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==")}.jstree-default-dark-large.jstree-rtl .jstree-last{background:transparent}@media (max-width:768px){#jstree-dnd.jstree-dnd-responsive{line-height:40px;font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}#jstree-dnd.jstree-dnd-responsive>i{background:transparent;width:40px;height:40px}#jstree-dnd.jstree-dnd-responsive>.jstree-ok{background-image:url("40px.png");background-position:0 -200px;background-size:120px 240px}#jstree-dnd.jstree-dnd-responsive>.jstree-er{background-image:url("40px.png");background-position:-40px -200px;background-size:120px 240px}#jstree-marker.jstree-dnd-responsive{border-left-width:10px;border-top-width:10px;border-bottom-width:10px;margin-top:-10px}}@media (max-width:768px){.jstree-default-dark-responsive .jstree-icon{background-image:url("40px.png")}.jstree-default-dark-responsive .jstree-node,.jstree-default-dark-responsive .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-responsive .jstree-node{min-height:40px;line-height:40px;margin-left:40px;min-width:40px;white-space:nowrap}.jstree-default-dark-responsive .jstree-anchor{line-height:40px;height:40px}.jstree-default-dark-responsive .jstree-icon,.jstree-default-dark-responsive .jstree-icon:empty{width:40px;height:40px;line-height:40px}.jstree-default-dark-responsive>.jstree-container-ul>.jstree-node{margin-left:0}.jstree-default-dark-responsive.jstree-rtl .jstree-node{margin-left:0;margin-right:40px;background:transparent}.jstree-default-dark-responsive.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-default-dark-responsive .jstree-ocl,.jstree-default-dark-responsive .jstree-themeicon,.jstree-default-dark-responsive .jstree-checkbox{background-size:120px 240px}.jstree-default-dark-responsive .jstree-leaf>.jstree-ocl,.jstree-default-dark-responsive.jstree-rtl .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-responsive .jstree-open>.jstree-ocl{background-position:0 0 !important}.jstree-default-dark-responsive .jstree-closed>.jstree-ocl{background-position:0 -40px !important}.jstree-default-dark-responsive.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-40px 0 !important}.jstree-default-dark-responsive .jstree-themeicon{background-position:-40px -40px}.jstree-default-dark-responsive .jstree-checkbox,.jstree-default-dark-responsive .jstree-checkbox:hover{background-position:-40px -80px}.jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark-responsive .jstree-checked>.jstree-checkbox,.jstree-default-dark-responsive .jstree-checked>.jstree-checkbox:hover{background-position:0 -80px}.jstree-default-dark-responsive .jstree-anchor>.jstree-undetermined,.jstree-default-dark-responsive .jstree-anchor>.jstree-undetermined:hover{background-position:0 -120px}.jstree-default-dark-responsive .jstree-anchor{font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}.jstree-default-dark-responsive>.jstree-striped{background:transparent}.jstree-default-dark-responsive .jstree-wholerow{border-top:1px solid #666;border-bottom:1px solid #000;background:#333333;height:40px}.jstree-default-dark-responsive .jstree-wholerow-hovered{background:#555}.jstree-default-dark-responsive .jstree-wholerow-clicked{background:#5fa2db}.jstree-default-dark-responsive .jstree-children .jstree-last>.jstree-wholerow{box-shadow:inset 0 -6px 3px -5px #111111}.jstree-default-dark-responsive .jstree-children .jstree-open>.jstree-wholerow{box-shadow:inset 0 6px 3px -5px #111111;border-top:0}.jstree-default-dark-responsive .jstree-children .jstree-open+.jstree-open{box-shadow:none}.jstree-default-dark-responsive .jstree-node,.jstree-default-dark-responsive .jstree-icon,.jstree-default-dark-responsive .jstree-node>.jstree-ocl,.jstree-default-dark-responsive .jstree-themeicon,.jstree-default-dark-responsive .jstree-checkbox{background-image:url("40px.png");background-size:120px 240px}.jstree-default-dark-responsive .jstree-node{background-position:-80px 0;background-repeat:repeat-y}.jstree-default-dark-responsive .jstree-last{background:transparent}.jstree-default-dark-responsive .jstree-leaf>.jstree-ocl{background-position:-40px -120px}.jstree-default-dark-responsive .jstree-last>.jstree-ocl{background-position:-40px -160px}.jstree-default-dark-responsive .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark-responsive .jstree-file{background:url("40px.png") 0 -160px no-repeat;background-size:120px 240px}.jstree-default-dark-responsive .jstree-folder{background:url("40px.png") -40px -40px no-repeat;background-size:120px 240px}.jstree-default-dark-responsive>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}}.jstree-default-dark{background:#333}.jstree-default-dark .jstree-anchor{color:#999;text-shadow:1px 1px 0 rgba(0,0,0,0.5)}.jstree-default-dark .jstree-clicked,.jstree-default-dark .jstree-checked{color:white}.jstree-default-dark .jstree-hovered{color:white}#jstree-marker.jstree-default-dark{border-left-color:#999;background:transparent}.jstree-default-dark .jstree-anchor>.jstree-icon{opacity:.75}.jstree-default-dark .jstree-clicked>.jstree-icon,.jstree-default-dark .jstree-hovered>.jstree-icon,.jstree-default-dark .jstree-checked>.jstree-icon{opacity:1}.jstree-default-dark.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==")}.jstree-default-dark.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==")}.jstree-default-dark-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-dark-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==")}.jstree-default-dark-large.jstree-rtl .jstree-last{background:transparent} \ No newline at end of file diff --git a/odex30_base/data_chart/static/src/css/themes/default-dark/throbber.gif b/odex30_base/data_chart/static/src/css/themes/default-dark/throbber.gif new file mode 100644 index 0000000..c6a1c85 Binary files /dev/null and b/odex30_base/data_chart/static/src/css/themes/default-dark/throbber.gif differ diff --git a/odex30_base/data_chart/static/src/css/themes/default/32px.png b/odex30_base/data_chart/static/src/css/themes/default/32px.png new file mode 100644 index 0000000..4357b91 Binary files /dev/null and b/odex30_base/data_chart/static/src/css/themes/default/32px.png differ diff --git a/odex30_base/data_chart/static/src/css/themes/default/40px.png b/odex30_base/data_chart/static/src/css/themes/default/40px.png new file mode 100644 index 0000000..d025522 Binary files /dev/null and b/odex30_base/data_chart/static/src/css/themes/default/40px.png differ diff --git a/odex30_base/data_chart/static/src/css/themes/default/style.css b/odex30_base/data_chart/static/src/css/themes/default/style.css new file mode 100644 index 0000000..0703168 --- /dev/null +++ b/odex30_base/data_chart/static/src/css/themes/default/style.css @@ -0,0 +1,1102 @@ +/* jsTree default theme */ +.jstree-node, +.jstree-children, +.jstree-container-ul { + display: block; + margin: 0; + padding: 0; + list-style-type: none; + list-style-image: none; +} +.jstree-node { + white-space: nowrap; +} +.jstree-anchor { + display: inline-block; + color: black; + white-space: nowrap; + padding: 0 4px 0 1px; + margin: 0; + vertical-align: top; +} +.jstree-anchor:focus { + outline: 0; +} +.jstree-anchor, +.jstree-anchor:link, +.jstree-anchor:visited, +.jstree-anchor:hover, +.jstree-anchor:active { + text-decoration: none; + color: inherit; +} +.jstree-icon { + display: inline-block; + text-decoration: none; + margin: 0; + padding: 0; + vertical-align: top; + text-align: center; +} +.jstree-icon:empty { + display: inline-block; + text-decoration: none; + margin: 0; + padding: 0; + vertical-align: top; + text-align: center; +} +.jstree-ocl { + cursor: pointer; +} +.jstree-leaf > .jstree-ocl { + cursor: default; +} +.jstree .jstree-open > .jstree-children { + display: block; +} +.jstree .jstree-closed > .jstree-children, +.jstree .jstree-leaf > .jstree-children { + display: none; +} +.jstree-anchor > .jstree-themeicon { + margin-right: 2px; +} +.jstree-no-icons .jstree-themeicon, +.jstree-anchor > .jstree-themeicon-hidden { + display: none; +} +.jstree-hidden, +.jstree-node.jstree-hidden { + display: none; +} +.jstree-rtl .jstree-anchor { + padding: 0 1px 0 4px; +} +.jstree-rtl .jstree-anchor > .jstree-themeicon { + margin-left: 2px; + margin-right: 0; +} +.jstree-rtl .jstree-node { + margin-left: 0; +} +.jstree-rtl .jstree-container-ul > .jstree-node { + margin-right: 0; +} +.jstree-wholerow-ul { + position: relative; + display: inline-block; + min-width: 100%; +} +.jstree-wholerow-ul .jstree-leaf > .jstree-ocl { + cursor: pointer; +} +.jstree-wholerow-ul .jstree-anchor, +.jstree-wholerow-ul .jstree-icon { + position: relative; +} +.jstree-wholerow-ul .jstree-wholerow { + width: 100%; + cursor: pointer; + position: absolute; + left: 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.jstree-contextmenu .jstree-anchor { + -webkit-user-select: none; + /* disable selection/Copy of UIWebView */ + -webkit-touch-callout: none; + /* disable the IOS popup when long-press on a link */ +} +.vakata-context { + display: none; +} +.vakata-context, +.vakata-context ul { + margin: 0; + padding: 2px; + position: absolute; + background: #f5f5f5; + border: 1px solid #979797; + box-shadow: 2px 2px 2px #999999; +} +.vakata-context ul { + list-style: none; + left: 100%; + margin-top: -2.7em; + margin-left: -4px; +} +.vakata-context .vakata-context-right ul { + left: auto; + right: 100%; + margin-left: auto; + margin-right: -4px; +} +.vakata-context li { + list-style: none; +} +.vakata-context li > a { + display: block; + padding: 0 2em 0 2em; + text-decoration: none; + width: auto; + color: black; + white-space: nowrap; + line-height: 2.4em; + text-shadow: 1px 1px 0 white; + border-radius: 1px; +} +.vakata-context li > a:hover { + position: relative; + background-color: #e8eff7; + box-shadow: 0 0 2px #0a6aa1; +} +.vakata-context li > a.vakata-context-parent { + background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw=="); + background-position: right center; + background-repeat: no-repeat; +} +.vakata-context li > a:focus { + outline: 0; +} +.vakata-context .vakata-context-hover > a { + position: relative; + background-color: #e8eff7; + box-shadow: 0 0 2px #0a6aa1; +} +.vakata-context .vakata-context-separator > a, +.vakata-context .vakata-context-separator > a:hover { + background: white; + border: 0; + border-top: 1px solid #e2e3e3; + height: 1px; + min-height: 1px; + max-height: 1px; + padding: 0; + margin: 0 0 0 2.4em; + border-left: 1px solid #e0e0e0; + text-shadow: 0 0 0 transparent; + box-shadow: 0 0 0 transparent; + border-radius: 0; +} +.vakata-context .vakata-contextmenu-disabled a, +.vakata-context .vakata-contextmenu-disabled a:hover { + color: silver; + background-color: transparent; + border: 0; + box-shadow: 0 0 0; +} +.vakata-context .vakata-contextmenu-disabled > a > i { + filter: grayscale(100%); +} +.vakata-context li > a > i { + text-decoration: none; + display: inline-block; + width: 2.4em; + height: 2.4em; + background: transparent; + margin: 0 0 0 -2em; + vertical-align: top; + text-align: center; + line-height: 2.4em; +} +.vakata-context li > a > i:empty { + width: 2.4em; + line-height: 2.4em; +} +.vakata-context li > a .vakata-contextmenu-sep { + display: inline-block; + width: 1px; + height: 2.4em; + background: white; + margin: 0 0.5em 0 0; + border-left: 1px solid #e2e3e3; +} +.vakata-context .vakata-contextmenu-shortcut { + font-size: 0.8em; + color: silver; + opacity: 0.5; + display: none; +} +.vakata-context-rtl ul { + left: auto; + right: 100%; + margin-left: auto; + margin-right: -4px; +} +.vakata-context-rtl li > a.vakata-context-parent { + background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7"); + background-position: left center; + background-repeat: no-repeat; +} +.vakata-context-rtl .vakata-context-separator > a { + margin: 0 2.4em 0 0; + border-left: 0; + border-right: 1px solid #e2e3e3; +} +.vakata-context-rtl .vakata-context-left ul { + right: auto; + left: 100%; + margin-left: -4px; + margin-right: auto; +} +.vakata-context-rtl li > a > i { + margin: 0 -2em 0 0; +} +.vakata-context-rtl li > a .vakata-contextmenu-sep { + margin: 0 0 0 0.5em; + border-left-color: white; + background: #e2e3e3; +} +#jstree-marker { + position: absolute; + top: 0; + left: 0; + margin: -5px 0 0 0; + padding: 0; + border-right: 0; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid; + width: 0; + height: 0; + font-size: 0; + line-height: 0; +} +#jstree-dnd { + line-height: 16px; + margin: 0; + padding: 4px; +} +#jstree-dnd .jstree-icon, +#jstree-dnd .jstree-copy { + display: inline-block; + text-decoration: none; + margin: 0 2px 0 0; + padding: 0; + width: 16px; + height: 16px; +} +#jstree-dnd .jstree-ok { + background: green; +} +#jstree-dnd .jstree-er { + background: red; +} +#jstree-dnd .jstree-copy { + margin: 0 2px 0 2px; +} +.jstree-default .jstree-node, +.jstree-default .jstree-icon { + background-repeat: no-repeat; + background-color: transparent; +} +.jstree-default .jstree-anchor, +.jstree-default .jstree-animated, +.jstree-default .jstree-wholerow { + transition: background-color 0.15s, box-shadow 0.15s; +} +.jstree-default .jstree-hovered { + background: #e7f4f9; + border-radius: 2px; + box-shadow: inset 0 0 1px #cccccc; +} +.jstree-default .jstree-context { + background: #e7f4f9; + border-radius: 2px; + box-shadow: inset 0 0 1px #cccccc; +} +.jstree-default .jstree-clicked { + background: #beebff; + border-radius: 2px; + box-shadow: inset 0 0 1px #999999; +} +.jstree-default .jstree-no-icons .jstree-anchor > .jstree-themeicon { + display: none; +} +.jstree-default .jstree-disabled { + background: transparent; + color: #666666; +} +.jstree-default .jstree-disabled.jstree-hovered { + background: transparent; + box-shadow: none; +} +.jstree-default .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default .jstree-disabled > .jstree-icon { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default .jstree-search { + font-style: italic; + color: #8b0000; + font-weight: bold; +} +.jstree-default .jstree-no-checkboxes .jstree-checkbox { + display: none !important; +} +.jstree-default.jstree-checkbox-no-clicked .jstree-clicked { + background: transparent; + box-shadow: none; +} +.jstree-default.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered { + background: #e7f4f9; +} +.jstree-default.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked { + background: transparent; +} +.jstree-default.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered { + background: #e7f4f9; +} +.jstree-default > .jstree-striped { + min-width: 100%; + display: inline-block; + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat; +} +.jstree-default > .jstree-wholerow-ul .jstree-hovered, +.jstree-default > .jstree-wholerow-ul .jstree-clicked { + background: transparent; + box-shadow: none; + border-radius: 0; +} +.jstree-default .jstree-wholerow { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} +.jstree-default .jstree-wholerow-hovered { + background: #e7f4f9; +} +.jstree-default .jstree-wholerow-clicked { + background: #beebff; + background: -webkit-linear-gradient(top, #beebff 0%, #a8e4ff 100%); + background: linear-gradient(to bottom, #beebff 0%, #a8e4ff 100%); +} +.jstree-default .jstree-node { + min-height: 24px; + line-height: 24px; + margin-left: 24px; + min-width: 24px; +} +.jstree-default .jstree-anchor { + line-height: 24px; + height: 24px; +} +.jstree-default .jstree-icon { + width: 24px; + height: 24px; + line-height: 24px; +} +.jstree-default .jstree-icon:empty { + width: 24px; + height: 24px; + line-height: 24px; +} +.jstree-default.jstree-rtl .jstree-node { + margin-right: 24px; +} +.jstree-default .jstree-wholerow { + height: 24px; +} +.jstree-default .jstree-node, +.jstree-default .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default .jstree-node { + background-position: -292px -4px; + background-repeat: repeat-y; +} +.jstree-default .jstree-last { + background: transparent; +} +.jstree-default .jstree-open > .jstree-ocl { + background-position: -132px -4px; +} +.jstree-default .jstree-closed > .jstree-ocl { + background-position: -100px -4px; +} +.jstree-default .jstree-leaf > .jstree-ocl { + background-position: -68px -4px; +} +.jstree-default .jstree-themeicon { + background-position: -260px -4px; +} +.jstree-default > .jstree-no-dots .jstree-node, +.jstree-default > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -36px -4px; +} +.jstree-default > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -4px -4px; +} +.jstree-default .jstree-disabled { + background: transparent; +} +.jstree-default .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default .jstree-checkbox { + background-position: -164px -4px; +} +.jstree-default .jstree-checkbox:hover { + background-position: -164px -36px; +} +.jstree-default.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default .jstree-checked > .jstree-checkbox { + background-position: -228px -4px; +} +.jstree-default.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default .jstree-checked > .jstree-checkbox:hover { + background-position: -228px -36px; +} +.jstree-default .jstree-anchor > .jstree-undetermined { + background-position: -196px -4px; +} +.jstree-default .jstree-anchor > .jstree-undetermined:hover { + background-position: -196px -36px; +} +.jstree-default .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default > .jstree-striped { + background-size: auto 48px; +} +.jstree-default.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -132px -36px; +} +.jstree-default.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -100px -36px; +} +.jstree-default.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -68px -36px; +} +.jstree-default.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -36px -36px; +} +.jstree-default.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -4px -36px; +} +.jstree-default .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default .jstree-file { + background: url("32px.png") -100px -68px no-repeat; +} +.jstree-default .jstree-folder { + background: url("32px.png") -260px -4px no-repeat; +} +.jstree-default > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default { + line-height: 24px; + padding: 0 4px; +} +#jstree-dnd.jstree-default .jstree-ok, +#jstree-dnd.jstree-default .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default i { + background: transparent; + width: 24px; + height: 24px; + line-height: 24px; +} +#jstree-dnd.jstree-default .jstree-ok { + background-position: -4px -68px; +} +#jstree-dnd.jstree-default .jstree-er { + background-position: -36px -68px; +} +.jstree-default .jstree-ellipsis { + overflow: hidden; +} +.jstree-default .jstree-ellipsis .jstree-anchor { + width: calc(100% - 29px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); +} +.jstree-default.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-small .jstree-node { + min-height: 18px; + line-height: 18px; + margin-left: 18px; + min-width: 18px; +} +.jstree-default-small .jstree-anchor { + line-height: 18px; + height: 18px; +} +.jstree-default-small .jstree-icon { + width: 18px; + height: 18px; + line-height: 18px; +} +.jstree-default-small .jstree-icon:empty { + width: 18px; + height: 18px; + line-height: 18px; +} +.jstree-default-small.jstree-rtl .jstree-node { + margin-right: 18px; +} +.jstree-default-small .jstree-wholerow { + height: 18px; +} +.jstree-default-small .jstree-node, +.jstree-default-small .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-small .jstree-node { + background-position: -295px -7px; + background-repeat: repeat-y; +} +.jstree-default-small .jstree-last { + background: transparent; +} +.jstree-default-small .jstree-open > .jstree-ocl { + background-position: -135px -7px; +} +.jstree-default-small .jstree-closed > .jstree-ocl { + background-position: -103px -7px; +} +.jstree-default-small .jstree-leaf > .jstree-ocl { + background-position: -71px -7px; +} +.jstree-default-small .jstree-themeicon { + background-position: -263px -7px; +} +.jstree-default-small > .jstree-no-dots .jstree-node, +.jstree-default-small > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-small > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -39px -7px; +} +.jstree-default-small > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -7px -7px; +} +.jstree-default-small .jstree-disabled { + background: transparent; +} +.jstree-default-small .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-small .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-small .jstree-checkbox { + background-position: -167px -7px; +} +.jstree-default-small .jstree-checkbox:hover { + background-position: -167px -39px; +} +.jstree-default-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-small .jstree-checked > .jstree-checkbox { + background-position: -231px -7px; +} +.jstree-default-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-small .jstree-checked > .jstree-checkbox:hover { + background-position: -231px -39px; +} +.jstree-default-small .jstree-anchor > .jstree-undetermined { + background-position: -199px -7px; +} +.jstree-default-small .jstree-anchor > .jstree-undetermined:hover { + background-position: -199px -39px; +} +.jstree-default-small .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-small > .jstree-striped { + background-size: auto 36px; +} +.jstree-default-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-small.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -135px -39px; +} +.jstree-default-small.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -103px -39px; +} +.jstree-default-small.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -71px -39px; +} +.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -39px -39px; +} +.jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: -7px -39px; +} +.jstree-default-small .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-small > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-small .jstree-file { + background: url("32px.png") -103px -71px no-repeat; +} +.jstree-default-small .jstree-folder { + background: url("32px.png") -263px -7px no-repeat; +} +.jstree-default-small > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-small { + line-height: 18px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-small .jstree-ok, +#jstree-dnd.jstree-default-small .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-small i { + background: transparent; + width: 18px; + height: 18px; + line-height: 18px; +} +#jstree-dnd.jstree-default-small .jstree-ok { + background-position: -7px -71px; +} +#jstree-dnd.jstree-default-small .jstree-er { + background-position: -39px -71px; +} +.jstree-default-small .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-small .jstree-ellipsis .jstree-anchor { + width: calc(100% - 23px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-small.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); +} +.jstree-default-small.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-large .jstree-node { + min-height: 32px; + line-height: 32px; + margin-left: 32px; + min-width: 32px; +} +.jstree-default-large .jstree-anchor { + line-height: 32px; + height: 32px; +} +.jstree-default-large .jstree-icon { + width: 32px; + height: 32px; + line-height: 32px; +} +.jstree-default-large .jstree-icon:empty { + width: 32px; + height: 32px; + line-height: 32px; +} +.jstree-default-large.jstree-rtl .jstree-node { + margin-right: 32px; +} +.jstree-default-large .jstree-wholerow { + height: 32px; +} +.jstree-default-large .jstree-node, +.jstree-default-large .jstree-icon { + background-image: url("32px.png"); +} +.jstree-default-large .jstree-node { + background-position: -288px 0px; + background-repeat: repeat-y; +} +.jstree-default-large .jstree-last { + background: transparent; +} +.jstree-default-large .jstree-open > .jstree-ocl { + background-position: -128px 0px; +} +.jstree-default-large .jstree-closed > .jstree-ocl { + background-position: -96px 0px; +} +.jstree-default-large .jstree-leaf > .jstree-ocl { + background-position: -64px 0px; +} +.jstree-default-large .jstree-themeicon { + background-position: -256px 0px; +} +.jstree-default-large > .jstree-no-dots .jstree-node, +.jstree-default-large > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-large > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -32px 0px; +} +.jstree-default-large > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: 0px 0px; +} +.jstree-default-large .jstree-disabled { + background: transparent; +} +.jstree-default-large .jstree-disabled.jstree-hovered { + background: transparent; +} +.jstree-default-large .jstree-disabled.jstree-clicked { + background: #efefef; +} +.jstree-default-large .jstree-checkbox { + background-position: -160px 0px; +} +.jstree-default-large .jstree-checkbox:hover { + background-position: -160px -32px; +} +.jstree-default-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, +.jstree-default-large .jstree-checked > .jstree-checkbox { + background-position: -224px 0px; +} +.jstree-default-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, +.jstree-default-large .jstree-checked > .jstree-checkbox:hover { + background-position: -224px -32px; +} +.jstree-default-large .jstree-anchor > .jstree-undetermined { + background-position: -192px 0px; +} +.jstree-default-large .jstree-anchor > .jstree-undetermined:hover { + background-position: -192px -32px; +} +.jstree-default-large .jstree-checkbox-disabled { + opacity: 0.8; + filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); + /* Firefox 10+ */ + filter: gray; + /* IE6-9 */ + -webkit-filter: grayscale(100%); + /* Chrome 19+ & Safari 6+ */ +} +.jstree-default-large > .jstree-striped { + background-size: auto 64px; +} +.jstree-default-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); + background-position: 100% 1px; + background-repeat: repeat-y; +} +.jstree-default-large.jstree-rtl .jstree-last { + background: transparent; +} +.jstree-default-large.jstree-rtl .jstree-open > .jstree-ocl { + background-position: -128px -32px; +} +.jstree-default-large.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -96px -32px; +} +.jstree-default-large.jstree-rtl .jstree-leaf > .jstree-ocl { + background-position: -64px -32px; +} +.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-node, +.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { + background: transparent; +} +.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { + background-position: -32px -32px; +} +.jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { + background-position: 0px -32px; +} +.jstree-default-large .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; +} +.jstree-default-large > .jstree-container-ul .jstree-loading > .jstree-ocl { + background: url("throbber.gif") center center no-repeat; +} +.jstree-default-large .jstree-file { + background: url("32px.png") -96px -64px no-repeat; +} +.jstree-default-large .jstree-folder { + background: url("32px.png") -256px 0px no-repeat; +} +.jstree-default-large > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; +} +#jstree-dnd.jstree-default-large { + line-height: 32px; + padding: 0 4px; +} +#jstree-dnd.jstree-default-large .jstree-ok, +#jstree-dnd.jstree-default-large .jstree-er { + background-image: url("32px.png"); + background-repeat: no-repeat; + background-color: transparent; +} +#jstree-dnd.jstree-default-large i { + background: transparent; + width: 32px; + height: 32px; + line-height: 32px; +} +#jstree-dnd.jstree-default-large .jstree-ok { + background-position: 0px -64px; +} +#jstree-dnd.jstree-default-large .jstree-er { + background-position: -32px -64px; +} +.jstree-default-large .jstree-ellipsis { + overflow: hidden; +} +.jstree-default-large .jstree-ellipsis .jstree-anchor { + width: calc(100% - 37px); + text-overflow: ellipsis; + overflow: hidden; +} +.jstree-default-large.jstree-rtl .jstree-node { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); +} +.jstree-default-large.jstree-rtl .jstree-last { + background: transparent; +} +@media (max-width: 768px) { + #jstree-dnd.jstree-dnd-responsive { + line-height: 40px; + font-weight: bold; + font-size: 1.1em; + text-shadow: 1px 1px white; + } + #jstree-dnd.jstree-dnd-responsive > i { + background: transparent; + width: 40px; + height: 40px; + } + #jstree-dnd.jstree-dnd-responsive > .jstree-ok { + background-image: url("40px.png"); + background-position: 0 -200px; + background-size: 120px 240px; + } + #jstree-dnd.jstree-dnd-responsive > .jstree-er { + background-image: url("40px.png"); + background-position: -40px -200px; + background-size: 120px 240px; + } + #jstree-marker.jstree-dnd-responsive { + border-left-width: 10px; + border-top-width: 10px; + border-bottom-width: 10px; + margin-top: -10px; + } +} +@media (max-width: 768px) { + .jstree-default-responsive { + /* + .jstree-open > .jstree-ocl, + .jstree-closed > .jstree-ocl { border-radius:20px; background-color:white; } + */ + } + .jstree-default-responsive .jstree-icon { + background-image: url("40px.png"); + } + .jstree-default-responsive .jstree-node, + .jstree-default-responsive .jstree-leaf > .jstree-ocl { + background: transparent; + } + .jstree-default-responsive .jstree-node { + min-height: 40px; + line-height: 40px; + margin-left: 40px; + min-width: 40px; + white-space: nowrap; + } + .jstree-default-responsive .jstree-anchor { + line-height: 40px; + height: 40px; + } + .jstree-default-responsive .jstree-icon, + .jstree-default-responsive .jstree-icon:empty { + width: 40px; + height: 40px; + line-height: 40px; + } + .jstree-default-responsive > .jstree-container-ul > .jstree-node { + margin-left: 0; + } + .jstree-default-responsive.jstree-rtl .jstree-node { + margin-left: 0; + margin-right: 40px; + background: transparent; + } + .jstree-default-responsive.jstree-rtl .jstree-container-ul > .jstree-node { + margin-right: 0; + } + .jstree-default-responsive .jstree-ocl, + .jstree-default-responsive .jstree-themeicon, + .jstree-default-responsive .jstree-checkbox { + background-size: 120px 240px; + } + .jstree-default-responsive .jstree-leaf > .jstree-ocl, + .jstree-default-responsive.jstree-rtl .jstree-leaf > .jstree-ocl { + background: transparent; + } + .jstree-default-responsive .jstree-open > .jstree-ocl { + background-position: 0 0 !important; + } + .jstree-default-responsive .jstree-closed > .jstree-ocl { + background-position: 0 -40px !important; + } + .jstree-default-responsive.jstree-rtl .jstree-closed > .jstree-ocl { + background-position: -40px 0 !important; + } + .jstree-default-responsive .jstree-themeicon { + background-position: -40px -40px; + } + .jstree-default-responsive .jstree-checkbox, + .jstree-default-responsive .jstree-checkbox:hover { + background-position: -40px -80px; + } + .jstree-default-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, + .jstree-default-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, + .jstree-default-responsive .jstree-checked > .jstree-checkbox, + .jstree-default-responsive .jstree-checked > .jstree-checkbox:hover { + background-position: 0 -80px; + } + .jstree-default-responsive .jstree-anchor > .jstree-undetermined, + .jstree-default-responsive .jstree-anchor > .jstree-undetermined:hover { + background-position: 0 -120px; + } + .jstree-default-responsive .jstree-anchor { + font-weight: bold; + font-size: 1.1em; + text-shadow: 1px 1px white; + } + .jstree-default-responsive > .jstree-striped { + background: transparent; + } + .jstree-default-responsive .jstree-wholerow { + border-top: 1px solid rgba(255, 255, 255, 0.7); + border-bottom: 1px solid rgba(64, 64, 64, 0.2); + background: #ebebeb; + height: 40px; + } + .jstree-default-responsive .jstree-wholerow-hovered { + background: #e7f4f9; + } + .jstree-default-responsive .jstree-wholerow-clicked { + background: #beebff; + } + .jstree-default-responsive .jstree-children .jstree-last > .jstree-wholerow { + box-shadow: inset 0 -6px 3px -5px #666666; + } + .jstree-default-responsive .jstree-children .jstree-open > .jstree-wholerow { + box-shadow: inset 0 6px 3px -5px #666666; + border-top: 0; + } + .jstree-default-responsive .jstree-children .jstree-open + .jstree-open { + box-shadow: none; + } + .jstree-default-responsive .jstree-node, + .jstree-default-responsive .jstree-icon, + .jstree-default-responsive .jstree-node > .jstree-ocl, + .jstree-default-responsive .jstree-themeicon, + .jstree-default-responsive .jstree-checkbox { + background-image: url("40px.png"); + background-size: 120px 240px; + } + .jstree-default-responsive .jstree-node { + background-position: -80px 0; + background-repeat: repeat-y; + } + .jstree-default-responsive .jstree-last { + background: transparent; + } + .jstree-default-responsive .jstree-leaf > .jstree-ocl { + background-position: -40px -120px; + } + .jstree-default-responsive .jstree-last > .jstree-ocl { + background-position: -40px -160px; + } + .jstree-default-responsive .jstree-themeicon-custom { + background-color: transparent; + background-image: none; + background-position: 0 0; + } + .jstree-default-responsive .jstree-file { + background: url("40px.png") 0 -160px no-repeat; + background-size: 120px 240px; + } + .jstree-default-responsive .jstree-folder { + background: url("40px.png") -40px -40px no-repeat; + background-size: 120px 240px; + } + .jstree-default-responsive > .jstree-container-ul > .jstree-node { + margin-left: 0; + margin-right: 0; + } +} diff --git a/odex30_base/data_chart/static/src/css/themes/default/style.min.css b/odex30_base/data_chart/static/src/css/themes/default/style.min.css new file mode 100644 index 0000000..93f80e9 --- /dev/null +++ b/odex30_base/data_chart/static/src/css/themes/default/style.min.css @@ -0,0 +1 @@ +.jstree-node,.jstree-children,.jstree-container-ul{display:block;margin:0;padding:0;list-style-type:none;list-style-image:none}.jstree-node{white-space:nowrap}.jstree-anchor{display:inline-block;color:black;white-space:nowrap;padding:0 4px 0 1px;margin:0;vertical-align:top}.jstree-anchor:focus{outline:0}.jstree-anchor,.jstree-anchor:link,.jstree-anchor:visited,.jstree-anchor:hover,.jstree-anchor:active{text-decoration:none;color:inherit}.jstree-icon{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-icon:empty{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-ocl{cursor:pointer}.jstree-leaf>.jstree-ocl{cursor:default}.jstree .jstree-open>.jstree-children{display:block}.jstree .jstree-closed>.jstree-children,.jstree .jstree-leaf>.jstree-children{display:none}.jstree-anchor>.jstree-themeicon{margin-right:2px}.jstree-no-icons .jstree-themeicon,.jstree-anchor>.jstree-themeicon-hidden{display:none}.jstree-hidden,.jstree-node.jstree-hidden{display:none}.jstree-rtl .jstree-anchor{padding:0 1px 0 4px}.jstree-rtl .jstree-anchor>.jstree-themeicon{margin-left:2px;margin-right:0}.jstree-rtl .jstree-node{margin-left:0}.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-wholerow-ul{position:relative;display:inline-block;min-width:100%}.jstree-wholerow-ul .jstree-leaf>.jstree-ocl{cursor:pointer}.jstree-wholerow-ul .jstree-anchor,.jstree-wholerow-ul .jstree-icon{position:relative}.jstree-wholerow-ul .jstree-wholerow{width:100%;cursor:pointer;position:absolute;left:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.jstree-contextmenu .jstree-anchor{-webkit-user-select:none;-webkit-touch-callout:none}.vakata-context{display:none}.vakata-context,.vakata-context ul{margin:0;padding:2px;position:absolute;background:#f5f5f5;border:1px solid #979797;box-shadow:2px 2px 2px #999999}.vakata-context ul{list-style:none;left:100%;margin-top:-2.7em;margin-left:-4px}.vakata-context .vakata-context-right ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context li{list-style:none}.vakata-context li>a{display:block;padding:0 2em 0 2em;text-decoration:none;width:auto;color:black;white-space:nowrap;line-height:2.4em;text-shadow:1px 1px 0 white;border-radius:1px}.vakata-context li>a:hover{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw==");background-position:right center;background-repeat:no-repeat}.vakata-context li>a:focus{outline:0}.vakata-context .vakata-context-hover>a{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context .vakata-context-separator>a,.vakata-context .vakata-context-separator>a:hover{background:white;border:0;border-top:1px solid #e2e3e3;height:1px;min-height:1px;max-height:1px;padding:0;margin:0 0 0 2.4em;border-left:1px solid #e0e0e0;text-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent;border-radius:0}.vakata-context .vakata-contextmenu-disabled a,.vakata-context .vakata-contextmenu-disabled a:hover{color:silver;background-color:transparent;border:0;box-shadow:0 0 0}.vakata-context .vakata-contextmenu-disabled>a>i{filter:grayscale(100%)}.vakata-context li>a>i{text-decoration:none;display:inline-block;width:2.4em;height:2.4em;background:transparent;margin:0 0 0 -2em;vertical-align:top;text-align:center;line-height:2.4em}.vakata-context li>a>i:empty{width:2.4em;line-height:2.4em}.vakata-context li>a .vakata-contextmenu-sep{display:inline-block;width:1px;height:2.4em;background:white;margin:0 .5em 0 0;border-left:1px solid #e2e3e3}.vakata-context .vakata-contextmenu-shortcut{font-size:.8em;color:silver;opacity:.5;display:none}.vakata-context-rtl ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context-rtl li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7");background-position:left center;background-repeat:no-repeat}.vakata-context-rtl .vakata-context-separator>a{margin:0 2.4em 0 0;border-left:0;border-right:1px solid #e2e3e3}.vakata-context-rtl .vakata-context-left ul{right:auto;left:100%;margin-left:-4px;margin-right:auto}.vakata-context-rtl li>a>i{margin:0 -2em 0 0}.vakata-context-rtl li>a .vakata-contextmenu-sep{margin:0 0 0 .5em;border-left-color:white;background:#e2e3e3}#jstree-marker{position:absolute;top:0;left:0;margin:-5px 0 0 0;padding:0;border-right:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid;width:0;height:0;font-size:0;line-height:0}#jstree-dnd{line-height:16px;margin:0;padding:4px}#jstree-dnd .jstree-icon,#jstree-dnd .jstree-copy{display:inline-block;text-decoration:none;margin:0 2px 0 0;padding:0;width:16px;height:16px}#jstree-dnd .jstree-ok{background:green}#jstree-dnd .jstree-er{background:red}#jstree-dnd .jstree-copy{margin:0 2px 0 2px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-repeat:no-repeat;background-color:transparent}.jstree-default .jstree-anchor,.jstree-default .jstree-animated,.jstree-default .jstree-wholerow{transition:background-color .15s,box-shadow .15s}.jstree-default .jstree-hovered{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #cccccc}.jstree-default .jstree-context{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #cccccc}.jstree-default .jstree-clicked{background:#beebff;border-radius:2px;box-shadow:inset 0 0 1px #999999}.jstree-default .jstree-no-icons .jstree-anchor>.jstree-themeicon{display:none}.jstree-default .jstree-disabled{background:transparent;color:#666666}.jstree-default .jstree-disabled.jstree-hovered{background:transparent;box-shadow:none}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-disabled>.jstree-icon{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default .jstree-search{font-style:italic;color:#8b0000;font-weight:bold}.jstree-default .jstree-no-checkboxes .jstree-checkbox{display:none !important}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked{background:transparent;box-shadow:none}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered{background:#e7f4f9}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked{background:transparent}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered{background:#e7f4f9}.jstree-default>.jstree-striped{min-width:100%;display:inline-block;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat}.jstree-default>.jstree-wholerow-ul .jstree-hovered,.jstree-default>.jstree-wholerow-ul .jstree-clicked{background:transparent;box-shadow:none;border-radius:0}.jstree-default .jstree-wholerow{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.jstree-default .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default .jstree-wholerow-clicked{background:#beebff;background:-webkit-linear-gradient(top, #beebff 0, #a8e4ff 100%);background:linear-gradient(to bottom, #beebff 0, #a8e4ff 100%)}.jstree-default .jstree-node{min-height:24px;line-height:24px;margin-left:24px;min-width:24px}.jstree-default .jstree-anchor{line-height:24px;height:24px}.jstree-default .jstree-icon{width:24px;height:24px;line-height:24px}.jstree-default .jstree-icon:empty{width:24px;height:24px;line-height:24px}.jstree-default.jstree-rtl .jstree-node{margin-right:24px}.jstree-default .jstree-wholerow{height:24px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-image:url("32px.png")}.jstree-default .jstree-node{background-position:-292px -4px;background-repeat:repeat-y}.jstree-default .jstree-last{background:transparent}.jstree-default .jstree-open>.jstree-ocl{background-position:-132px -4px}.jstree-default .jstree-closed>.jstree-ocl{background-position:-100px -4px}.jstree-default .jstree-leaf>.jstree-ocl{background-position:-68px -4px}.jstree-default .jstree-themeicon{background-position:-260px -4px}.jstree-default>.jstree-no-dots .jstree-node,.jstree-default>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -4px}.jstree-default>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -4px}.jstree-default .jstree-disabled{background:transparent}.jstree-default .jstree-disabled.jstree-hovered{background:transparent}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-checkbox{background-position:-164px -4px}.jstree-default .jstree-checkbox:hover{background-position:-164px -36px}.jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default .jstree-checked>.jstree-checkbox{background-position:-228px -4px}.jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default .jstree-checked>.jstree-checkbox:hover{background-position:-228px -36px}.jstree-default .jstree-anchor>.jstree-undetermined{background-position:-196px -4px}.jstree-default .jstree-anchor>.jstree-undetermined:hover{background-position:-196px -36px}.jstree-default .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default>.jstree-striped{background-size:auto 48px}.jstree-default.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default.jstree-rtl .jstree-last{background:transparent}.jstree-default.jstree-rtl .jstree-open>.jstree-ocl{background-position:-132px -36px}.jstree-default.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-100px -36px}.jstree-default.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-68px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -36px}.jstree-default .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default .jstree-file{background:url("32px.png") -100px -68px no-repeat}.jstree-default .jstree-folder{background:url("32px.png") -260px -4px no-repeat}.jstree-default>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default{line-height:24px;padding:0 4px}#jstree-dnd.jstree-default .jstree-ok,#jstree-dnd.jstree-default .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default i{background:transparent;width:24px;height:24px;line-height:24px}#jstree-dnd.jstree-default .jstree-ok{background-position:-4px -68px}#jstree-dnd.jstree-default .jstree-er{background-position:-36px -68px}.jstree-default .jstree-ellipsis{overflow:hidden}.jstree-default .jstree-ellipsis .jstree-anchor{width:calc(100% - 29px);text-overflow:ellipsis;overflow:hidden}.jstree-default.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==")}.jstree-default.jstree-rtl .jstree-last{background:transparent}.jstree-default-small .jstree-node{min-height:18px;line-height:18px;margin-left:18px;min-width:18px}.jstree-default-small .jstree-anchor{line-height:18px;height:18px}.jstree-default-small .jstree-icon{width:18px;height:18px;line-height:18px}.jstree-default-small .jstree-icon:empty{width:18px;height:18px;line-height:18px}.jstree-default-small.jstree-rtl .jstree-node{margin-right:18px}.jstree-default-small .jstree-wholerow{height:18px}.jstree-default-small .jstree-node,.jstree-default-small .jstree-icon{background-image:url("32px.png")}.jstree-default-small .jstree-node{background-position:-295px -7px;background-repeat:repeat-y}.jstree-default-small .jstree-last{background:transparent}.jstree-default-small .jstree-open>.jstree-ocl{background-position:-135px -7px}.jstree-default-small .jstree-closed>.jstree-ocl{background-position:-103px -7px}.jstree-default-small .jstree-leaf>.jstree-ocl{background-position:-71px -7px}.jstree-default-small .jstree-themeicon{background-position:-263px -7px}.jstree-default-small>.jstree-no-dots .jstree-node,.jstree-default-small>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-small>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -7px}.jstree-default-small>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -7px}.jstree-default-small .jstree-disabled{background:transparent}.jstree-default-small .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-small .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-small .jstree-checkbox{background-position:-167px -7px}.jstree-default-small .jstree-checkbox:hover{background-position:-167px -39px}.jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-small .jstree-checked>.jstree-checkbox{background-position:-231px -7px}.jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-small .jstree-checked>.jstree-checkbox:hover{background-position:-231px -39px}.jstree-default-small .jstree-anchor>.jstree-undetermined{background-position:-199px -7px}.jstree-default-small .jstree-anchor>.jstree-undetermined:hover{background-position:-199px -39px}.jstree-default-small .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-small>.jstree-striped{background-size:auto 36px}.jstree-default-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-small.jstree-rtl .jstree-open>.jstree-ocl{background-position:-135px -39px}.jstree-default-small.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-103px -39px}.jstree-default-small.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-71px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -39px}.jstree-default-small .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-small>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-small .jstree-file{background:url("32px.png") -103px -71px no-repeat}.jstree-default-small .jstree-folder{background:url("32px.png") -263px -7px no-repeat}.jstree-default-small>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-small{line-height:18px;padding:0 4px}#jstree-dnd.jstree-default-small .jstree-ok,#jstree-dnd.jstree-default-small .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-small i{background:transparent;width:18px;height:18px;line-height:18px}#jstree-dnd.jstree-default-small .jstree-ok{background-position:-7px -71px}#jstree-dnd.jstree-default-small .jstree-er{background-position:-39px -71px}.jstree-default-small .jstree-ellipsis{overflow:hidden}.jstree-default-small .jstree-ellipsis .jstree-anchor{width:calc(100% - 23px);text-overflow:ellipsis;overflow:hidden}.jstree-default-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==")}.jstree-default-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-large .jstree-node{min-height:32px;line-height:32px;margin-left:32px;min-width:32px}.jstree-default-large .jstree-anchor{line-height:32px;height:32px}.jstree-default-large .jstree-icon{width:32px;height:32px;line-height:32px}.jstree-default-large .jstree-icon:empty{width:32px;height:32px;line-height:32px}.jstree-default-large.jstree-rtl .jstree-node{margin-right:32px}.jstree-default-large .jstree-wholerow{height:32px}.jstree-default-large .jstree-node,.jstree-default-large .jstree-icon{background-image:url("32px.png")}.jstree-default-large .jstree-node{background-position:-288px 0;background-repeat:repeat-y}.jstree-default-large .jstree-last{background:transparent}.jstree-default-large .jstree-open>.jstree-ocl{background-position:-128px 0}.jstree-default-large .jstree-closed>.jstree-ocl{background-position:-96px 0}.jstree-default-large .jstree-leaf>.jstree-ocl{background-position:-64px 0}.jstree-default-large .jstree-themeicon{background-position:-256px 0}.jstree-default-large>.jstree-no-dots .jstree-node,.jstree-default-large>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-large>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px 0}.jstree-default-large>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 0}.jstree-default-large .jstree-disabled{background:transparent}.jstree-default-large .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-large .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-large .jstree-checkbox{background-position:-160px 0}.jstree-default-large .jstree-checkbox:hover{background-position:-160px -32px}.jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-large .jstree-checked>.jstree-checkbox{background-position:-224px 0}.jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-large .jstree-checked>.jstree-checkbox:hover{background-position:-224px -32px}.jstree-default-large .jstree-anchor>.jstree-undetermined{background-position:-192px 0}.jstree-default-large .jstree-anchor>.jstree-undetermined:hover{background-position:-192px -32px}.jstree-default-large .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-large>.jstree-striped{background-size:auto 64px}.jstree-default-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-large.jstree-rtl .jstree-last{background:transparent}.jstree-default-large.jstree-rtl .jstree-open>.jstree-ocl{background-position:-128px -32px}.jstree-default-large.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-96px -32px}.jstree-default-large.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-64px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 -32px}.jstree-default-large .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-large>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-large .jstree-file{background:url("32px.png") -96px -64px no-repeat}.jstree-default-large .jstree-folder{background:url("32px.png") -256px 0 no-repeat}.jstree-default-large>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-large{line-height:32px;padding:0 4px}#jstree-dnd.jstree-default-large .jstree-ok,#jstree-dnd.jstree-default-large .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-large i{background:transparent;width:32px;height:32px;line-height:32px}#jstree-dnd.jstree-default-large .jstree-ok{background-position:0 -64px}#jstree-dnd.jstree-default-large .jstree-er{background-position:-32px -64px}.jstree-default-large .jstree-ellipsis{overflow:hidden}.jstree-default-large .jstree-ellipsis .jstree-anchor{width:calc(100% - 37px);text-overflow:ellipsis;overflow:hidden}.jstree-default-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==")}.jstree-default-large.jstree-rtl .jstree-last{background:transparent}@media (max-width:768px){#jstree-dnd.jstree-dnd-responsive{line-height:40px;font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}#jstree-dnd.jstree-dnd-responsive>i{background:transparent;width:40px;height:40px}#jstree-dnd.jstree-dnd-responsive>.jstree-ok{background-image:url("40px.png");background-position:0 -200px;background-size:120px 240px}#jstree-dnd.jstree-dnd-responsive>.jstree-er{background-image:url("40px.png");background-position:-40px -200px;background-size:120px 240px}#jstree-marker.jstree-dnd-responsive{border-left-width:10px;border-top-width:10px;border-bottom-width:10px;margin-top:-10px}}@media (max-width:768px){.jstree-default-responsive .jstree-icon{background-image:url("40px.png")}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-responsive .jstree-node{min-height:40px;line-height:40px;margin-left:40px;min-width:40px;white-space:nowrap}.jstree-default-responsive .jstree-anchor{line-height:40px;height:40px}.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-icon:empty{width:40px;height:40px;line-height:40px}.jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0}.jstree-default-responsive.jstree-rtl .jstree-node{margin-left:0;margin-right:40px;background:transparent}.jstree-default-responsive.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-default-responsive .jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-size:120px 240px}.jstree-default-responsive .jstree-leaf>.jstree-ocl,.jstree-default-responsive.jstree-rtl .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-responsive .jstree-open>.jstree-ocl{background-position:0 0 !important}.jstree-default-responsive .jstree-closed>.jstree-ocl{background-position:0 -40px !important}.jstree-default-responsive.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-40px 0 !important}.jstree-default-responsive .jstree-themeicon{background-position:-40px -40px}.jstree-default-responsive .jstree-checkbox,.jstree-default-responsive .jstree-checkbox:hover{background-position:-40px -80px}.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-responsive .jstree-checked>.jstree-checkbox,.jstree-default-responsive .jstree-checked>.jstree-checkbox:hover{background-position:0 -80px}.jstree-default-responsive .jstree-anchor>.jstree-undetermined,.jstree-default-responsive .jstree-anchor>.jstree-undetermined:hover{background-position:0 -120px}.jstree-default-responsive .jstree-anchor{font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}.jstree-default-responsive>.jstree-striped{background:transparent}.jstree-default-responsive .jstree-wholerow{border-top:1px solid rgba(255,255,255,0.7);border-bottom:1px solid rgba(64,64,64,0.2);background:#ebebeb;height:40px}.jstree-default-responsive .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default-responsive .jstree-wholerow-clicked{background:#beebff}.jstree-default-responsive .jstree-children .jstree-last>.jstree-wholerow{box-shadow:inset 0 -6px 3px -5px #666666}.jstree-default-responsive .jstree-children .jstree-open>.jstree-wholerow{box-shadow:inset 0 6px 3px -5px #666666;border-top:0}.jstree-default-responsive .jstree-children .jstree-open+.jstree-open{box-shadow:none}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-node>.jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-image:url("40px.png");background-size:120px 240px}.jstree-default-responsive .jstree-node{background-position:-80px 0;background-repeat:repeat-y}.jstree-default-responsive .jstree-last{background:transparent}.jstree-default-responsive .jstree-leaf>.jstree-ocl{background-position:-40px -120px}.jstree-default-responsive .jstree-last>.jstree-ocl{background-position:-40px -160px}.jstree-default-responsive .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-responsive .jstree-file{background:url("40px.png") 0 -160px no-repeat;background-size:120px 240px}.jstree-default-responsive .jstree-folder{background:url("40px.png") -40px -40px no-repeat;background-size:120px 240px}.jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}} \ No newline at end of file diff --git a/odex30_base/data_chart/static/src/css/themes/default/throbber.gif b/odex30_base/data_chart/static/src/css/themes/default/throbber.gif new file mode 100644 index 0000000..64c8eeb Binary files /dev/null and b/odex30_base/data_chart/static/src/css/themes/default/throbber.gif differ diff --git a/odex30_base/data_chart/static/src/css/wdr.css b/odex30_base/data_chart/static/src/css/wdr.css new file mode 100644 index 0000000..ccd1e89 --- /dev/null +++ b/odex30_base/data_chart/static/src/css/wdr.css @@ -0,0 +1,71 @@ +img.centered { + margin: auto !important; + padding-bottom: 10px; + color: transparent !important; + width: 22px; + height: 22px; + display: flex; + align-items: center; + font-size: 12px; + position: relative; + bottom: 4px; + left: 6px; +} + +button { + border: 1px solid #0598df; + background: #fff; + color: #0598df; + text-transform: uppercase; + cursor: pointer; + margin: 5px 0; + display: inline-block; + -webkit-transition: all .3s; + transition: all .3s; + font-weight: normal; + padding: 10px 10px; + font-size: 14px; +} + +.classic { + width: 120px; +} + +.flat { + width: 120px; +} + +.compact { + width: 120px; +} + +.hdrs-on { + width: 149px; + padding-left: 10px; +} + +.hdrs-off { + width: 140px; + padding-left: 15px; +} + +.wdr-colorpick-popup { + bottom: 20px; +} + +.wdr-colorpick-popup.wdr-arrow-down { + bottom: 20px; +} + +ul.wdr-ui-element.wdr-ui.wdr-ui-list { + top: 0px !important; +} + +#wdr-toolbar-wrapper #wdr-printing-radio { + margin-left: 14px; + } + + #wdr-drillthrough-view > div.wdr-ui-element.wdr-ui.wdr-details-container > span > b{ + unicode-bidi:embed; + } + \ No newline at end of file diff --git a/odex30_base/data_chart/static/src/css/wdr_rtl.css b/odex30_base/data_chart/static/src/css/wdr_rtl.css new file mode 100644 index 0000000..b994324 --- /dev/null +++ b/odex30_base/data_chart/static/src/css/wdr_rtl.css @@ -0,0 +1,21 @@ +#wdr-toolbar-wrapper{ + direction: ltr; +} + + +#wdr-toolbar{ + direction: ltr; +} + + +#wdr-filter-view{ + direction: ltr; +} + +.wdr-cell.wdr-header.wdr-header-c.wdr-v-sort.wdr-filter-header.wdr-ui-element.wdr-draggable { + direction: ltr; +} + +div#wdr-fields-view { + direction: ltr; +} \ No newline at end of file diff --git a/odex30_base/data_chart/static/src/css/website_rtl.css b/odex30_base/data_chart/static/src/css/website_rtl.css new file mode 100644 index 0000000..85347c6 --- /dev/null +++ b/odex30_base/data_chart/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/odex30_base/data_chart/static/src/fonts/Amiri-Regular.ttf b/odex30_base/data_chart/static/src/fonts/Amiri-Regular.ttf new file mode 100644 index 0000000..4d3f842 Binary files /dev/null and b/odex30_base/data_chart/static/src/fonts/Amiri-Regular.ttf differ diff --git a/odex30_base/data_chart/static/src/img/icons8-clear-filters-64.png b/odex30_base/data_chart/static/src/img/icons8-clear-filters-64.png new file mode 100644 index 0000000..ca0ec33 Binary files /dev/null and b/odex30_base/data_chart/static/src/img/icons8-clear-filters-64.png differ diff --git a/odex30_base/data_chart/static/src/img/icons8-data-48.png b/odex30_base/data_chart/static/src/img/icons8-data-48.png new file mode 100644 index 0000000..d213d33 Binary files /dev/null and b/odex30_base/data_chart/static/src/img/icons8-data-48.png differ diff --git a/odex30_base/data_chart/static/src/img/icons8-reset-64.png b/odex30_base/data_chart/static/src/img/icons8-reset-64.png new file mode 100644 index 0000000..410a859 Binary files /dev/null and b/odex30_base/data_chart/static/src/img/icons8-reset-64.png differ diff --git a/odex30_base/data_chart/static/src/img/user-cog-solid.svg b/odex30_base/data_chart/static/src/img/user-cog-solid.svg new file mode 100644 index 0000000..62ae6cf --- /dev/null +++ b/odex30_base/data_chart/static/src/img/user-cog-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/odex30_base/data_chart/static/src/js/data_chart.js b/odex30_base/data_chart/static/src/js/data_chart.js new file mode 100644 index 0000000..a7dbe8c --- /dev/null +++ b/odex30_base/data_chart/static/src/js/data_chart.js @@ -0,0 +1,289 @@ +import { Component, onMounted, onWillStart, useRef, useState } from "@odoo/owl"; +import { registry } from "@web/core/registry"; +import { useService } from "@web/core/utils/hooks"; +import { _t } from "@web/core/l10n/translation"; +import { jsonrpc } from "@web/core/network/rpc_service"; + +class DataChart extends Component { + static template = "data_chart.data_chart_temp"; + static props = { + action: Object, + context: { type: Object, optional: true }, + }; + + setup() { + this.rpc = useService("rpc"); + this.chartRef = useRef("chart"); + this.state = useState({ + isLoaded: false, + }); + + this.pivot = null; + this.params = this.props.action; + + onWillStart(async () => { + await this.loadData(); + }); + + onMounted(() => { + this.initializeChart(); + }); + } + + async loadData(withDefault = false) { + try { + const result = await this.rpc("/web/dataset/call_kw", { + model: "data_chart_model", + method: "data_chart_details", + args: [ + this.params.context?.model, + this.params.context?.active_id, + withDefault + ], + kwargs: {}, + }); + + this.processData(result); + } catch (error) { + console.error("Error loading data chart:", error); + alert("ERROR IN REPORT CONFIGURATION!"); + } + } + + processData(result) { + const data = result.data; + let options, slice, conditions, formats, colsTypes, header = "", footer = ""; + + if (result.options) { + options = JSON.parse(result.options); + } + if (result.slice) { + slice = JSON.parse(result.slice); + } + if (result.conditions) { + conditions = JSON.parse(result.conditions); + } + if (result.formats) { + formats = JSON.parse(result.formats); + } + if (result.cols_types) { + colsTypes = JSON.parse(result.cols_types); + } + if (result.header) { + header = result.header; + } + if (result.footer) { + footer = result.footer; + } + + this.chartData = { + data, + options, + slice, + conditions, + formats, + colsTypes, + header, + footer, + companyImage: result.company_image, + }; + + this.state.isLoaded = true; + } + + initializeChart() { + if (!this.state.isLoaded || !this.chartRef.el) { + return; + } + + const { data, options, slice, conditions, formats, colsTypes } = this.chartData; + + this.pivot = new WebDataRocks({ + beforetoolbarcreated: this.customizeToolbar.bind(this), + container: this.chartRef.el, + toolbar: true, + report: { + dataSource: { + data: [colsTypes].concat(data) + }, + slice: slice, + options: options, + conditions: conditions, + formats: formats, + }, + }); + + this.setupExportOverride(); + this.setTitle(); + this.pivot.modelParams = this.params; + this.pivot.parentComponent = this; + this.pivot.backgroundImage = this.chartData.companyImage; + this.pivot.colsTypes = colsTypes; + this.pivot.originalData = data; + } + + setupExportOverride() { + const oldExport = this.pivot.exportTo; + this.pivot.exportTo = (type, options = {}, callback) => { + options.header = `
    company${this.chartData.header}
    `; + options.footer = `${this.chartData.footer}`; + oldExport.call(this.pivot, type, options, callback); + }; + } + + setTitle() { + if (this.params.context?.title) { + this.pivot.setOptions({ + grid: { + title: this.params.context.title + } + }); + } + } + + async setDefault() { + const options = JSON.stringify(this.pivot.getOptions()); + const slice = JSON.stringify(this.pivot.getReport().slice); + const conditions = JSON.stringify(this.pivot.getReport().conditions); + const formats = JSON.stringify(this.pivot.getReport().formats); + const colsTypes = JSON.stringify(this.pivot.colsTypes); + + await this.rpc("/web/dataset/call_kw", { + model: "data_chart_model", + method: "set_default", + args: [ + this.pivot.modelParams.context.model, + this.pivot.modelParams.context.active_id, + options, + slice, + conditions, + formats, + colsTypes + ], + kwargs: {}, + }); + } + + async getDefault() { + await this.loadData(true); + this.initializeChart(); + } + + updateData() { + if (this.pivot && this.pivot.colsTypes && this.pivot.originalData) { + this.pivot.updateData({ + data: [this.pivot.colsTypes].concat(this.pivot.originalData) + }); + } + } + + fillColTypesDropDown(dropdown, selected) { + const options = [ + { value: 'string', text: 'string' }, + { value: 'date string', text: 'date string' }, + { value: 'date', text: 'date' }, + { value: 'year/month/day', text: 'year/month/day' }, + { value: 'year/quarter/month/day', text: 'year/quarter/month/day' }, + { value: 'number', text: 'number' }, + { value: 'weekday', text: 'weekday' }, + { value: 'month', text: 'month' }, + { value: 'datetime', text: 'datetime' }, + { value: 'time', text: 'time' } + ]; + + dropdown.innerHTML = ''; + options.forEach((option, index) => { + dropdown[index] = new Option(option.text, option.value); + }); + dropdown.value = selected; + } + + async setColsTypes(toolbar) { + // Implementation for column types setting + // This would need to be adapted based on the WebDataRocks API + const newColTypes = {}; + + for (const key in toolbar.pivot.colsTypes) { + const keyId = "ctse_" + key.split(' ').join('_'); + const el = document.getElementById(keyId); + if (el) { + newColTypes[key] = { type: el.value }; + } + } + + toolbar.pivot.colsTypes = newColTypes; + this.updateData(); + } + + customizeToolbar(toolbar) { + const tabs = toolbar.getTabs(); + + // Customize existing tabs + toolbar.getTabs = () => { + delete tabs[0]; + delete tabs[1]; + + // Modify save functionality + if (tabs[2]) { + tabs[2].handler = async () => { + const options = JSON.stringify(this.pivot.getOptions()); + const slice = JSON.stringify(this.pivot.getReport().slice); + const conditions = JSON.stringify(this.pivot.getReport().conditions); + const formats = JSON.stringify(this.pivot.getReport().formats); + const colsTypes = JSON.stringify(this.pivot.colsTypes); + + await this.rpc("/web/dataset/call_kw", { + model: "data_chart_model", + method: "save_options", + args: [ + this.pivot.modelParams.context.model, + this.pivot.modelParams.context.active_id, + options, + slice, + conditions, + formats, + colsTypes + ], + kwargs: {}, + }); + }; + } + + // Remove unwanted menu items + if (tabs[3] && tabs[3].menu) { + delete tabs[3].menu[0]; + delete tabs[3].menu[1]; + } + + // Add custom tabs + tabs.unshift({ + id: "wdr-tab-get-default", + title: "Original", + handler: () => this.getDefault(), + icon: 'Get Default' + }); + + if (this.pivot.modelParams.context.admin_view) { + tabs.unshift({ + id: "wdr-tab-set-default", + title: "Default", + handler: () => this.setDefault(), + icon: 'Set Default' + }); + } + + tabs.unshift({ + id: "wdr-tab-set-cols_types", + title: "Types", + handler: () => this.setColsTypes(toolbar), + icon: 'Field Types' + }); + + return tabs; + }; + } +} + +registry.category("actions").add("data_view", DataChart); + +export default DataChart; \ No newline at end of file diff --git a/odex30_base/data_chart/static/src/js/jspdf_custom.js b/odex30_base/data_chart/static/src/js/jspdf_custom.js new file mode 100644 index 0000000..10015e0 --- /dev/null +++ b/odex30_base/data_chart/static/src/js/jspdf_custom.js @@ -0,0 +1,459 @@ +(function (P) { + 'use strict'; + var O = 'addImage_', + X = ['jpeg', 'jpg', 'png'], + U = function (g) { + var j = this.internal.newObject(), + m = this.internal.write, + n = this.internal.putStream; + g['n'] = j; + m('<>'); + } + if ('trns' in g && g['trns'].constructor == Array) { + var o = '', + q = 0, + s = g['trns'].length; + for (; q < s; q++) o += (g['trns'][q] + ' ' + g['trns'][q] + ' '); + m('/Mask [' + o + ']'); + } + if ('smask' in g) { + m('/SMask ' + (j + 1) + ' 0 R'); + } + m('/Length ' + g['data'].length + '>>'); + n(g['data']); + m('endobj'); + if ('smask' in g) { + var t = '/Predictor 15 /Colors 1 /BitsPerComponent ' + g['bpc'] + ' /Columns ' + g['w']; + var v = { + 'w': g['w'], + 'h': g['h'], + 'cs': 'DeviceGray', + 'bpc': g['bpc'], + 'dp': t, + 'data': g['smask'] + }; + if ('f' in g) v.f = g['f']; + U.call(this, v); + } + if (g['cs'] === this.color_spaces.INDEXED) { + this.internal.newObject(); + m('<< /Length ' + g['pal'].length + '>>'); + n(this.arrayBufferToBinaryString(new Uint8Array(g['pal']))); + m('endobj'); + } + }, + Y = function () { + var g = this.internal.collections[O + 'images']; + for (var j in g) { + U.call(this, g[j]); + } + }, + W = function () { + var g = this.internal.collections[O + 'images'], + j = this.internal.write, + m; + for (var n in g) { + m = g[n]; + j('/I' + m['i'], m['n'], '0', 'R'); + } + }, + Q = function (g) { + if (g && typeof g === 'string') g = g.toUpperCase(); + return g in P.image_compression ? g : P.image_compression.NONE; + }, + s0 = function () { + var g = this.internal.collections[O + 'images']; + if (!g) { + this.internal.collections[O + 'images'] = g = {}; + this.internal.events.subscribe('putResources', Y); + this.internal.events.subscribe('putXobjectDict', W); + } + return g; + }, + k0 = function (n) { + var o = 0; + if (n) { + o = Object.keys ? Object.keys(n).length : (function (g) { + var j = 0; + for (var m in g) { + if (g.hasOwnProperty(m)) { + j++; + } + } + return j; + })(n); + } + return o; + }, + m0 = function (g) { + return typeof g === 'undefined' || g === null; + }, + j0 = function (g) { + return typeof g === 'string' && P.sHashCode(g); + }, + e0 = function (g) { + return X.indexOf(g) === -1; + }, + R = function (g) { + return typeof P['process' + g.toUpperCase()] !== 'function'; + }, + S = function (g) { + return typeof g === 'object' && g.nodeType === 1; + }, + y0 = function (g, j, m) { + if (g.nodeName === 'IMG' && g.hasAttribute('src')) { + var n = '' + g.getAttribute('src'); + if (!m && n.indexOf('data:image/') === 0) return n; + if (!j && /\.png(?:[?#].*)?$/i.test(n)) j = 'png'; + } + if (g.nodeName === 'CANVAS') { + var o = g; + } else { + var o = document.createElement('canvas'); + o.width = g.clientWidth || g.width; + o.height = g.clientHeight || g.height; + var q = o.getContext('2d'); + if (!q) { + throw ('addImage requires canvas to be supported by browser.'); + } + if (m) { + var s, t, v, H, z, I, K, M = Math.PI / 180, + N; + if (typeof m === 'object') { + s = m.x; + t = m.y; + v = m.bg; + m = m.angle; + } + N = m * M; + H = Math.abs(Math.cos(N)); + z = Math.abs(Math.sin(N)); + I = o.width; + K = o.height; + o.width = K * z + I * H; + o.height = K * H + I * z; + if (isNaN(s)) s = o.width / 2; + if (isNaN(t)) t = o.height / 2; + q.clearRect(0, 0, o.width, o.height); + q.fillStyle = v || 'white'; + q.fillRect(0, 0, o.width, o.height); + q.save(); + q.translate(s, t); + q.rotate(N); + q.drawImage(g, -(I / 2), -(K / 2)); + q.rotate(-N); + q.translate(-s, -t); + q.restore(); + } else { + q.drawImage(g, 0, 0, o.width, o.height); + } + } + return o.toDataURL(('' + j).toLowerCase() == 'png' ? 'image/png' : 'image/jpeg'); + }, + f0 = function (g, j) { + var m; + if (j) { + for (var n in j) { + if (g === j[n].alias) { + m = j[n]; + break; + } + } + } + return m; + }, + v0 = function (g, j, m) { + if (!g && !j) { + g = -96; + j = -96; + } + if (g < 0) { + g = (-1) * m['w'] * 72 / g / this.internal.scaleFactor; + } + if (j < 0) { + j = (-1) * m['h'] * 72 / j / this.internal.scaleFactor; + } + if (g === 0) { + g = j * m['w'] / m['h']; + } + if (j === 0) { + j = g * m['h'] / m['w']; + } + return [g, j]; + }, + z0 = function (g, j, m, n, o, q, s) { + var t = v0.call(this, m, n, o), + v = this.internal.getCoordinateString, + H = this.internal.getVerticalCoordinateString; + m = t[0]; + n = t[1]; + s[q] = o; + this.internal.write('q', v(m), '0 0', v(n), v(g), H(j + n), 'cm /I' + o['i'], 'Do Q'); + }; + P.color_spaces = { + DEVICE_RGB: 'DeviceRGB', + DEVICE_GRAY: 'DeviceGray', + DEVICE_CMYK: 'DeviceCMYK', + CAL_GREY: 'CalGray', + CAL_RGB: 'CalRGB', + LAB: 'Lab', + ICC_BASED: 'ICCBased', + INDEXED: 'Indexed', + PATTERN: 'Pattern', + SEPERATION: 'Seperation', + DEVICE_N: 'DeviceN' + }; + P.decode = { + DCT_DECODE: 'DCTDecode', + FLATE_DECODE: 'FlateDecode', + LZW_DECODE: 'LZWDecode', + JPX_DECODE: 'JPXDecode', + JBIG2_DECODE: 'JBIG2Decode', + ASCII85_DECODE: 'ASCII85Decode', + ASCII_HEX_DECODE: 'ASCIIHexDecode', + RUN_LENGTH_DECODE: 'RunLengthDecode', + CCITT_FAX_DECODE: 'CCITTFaxDecode' + }; + P.image_compression = { + NONE: 'NONE', + FAST: 'FAST', + MEDIUM: 'MEDIUM', + SLOW: 'SLOW' + }; + P.sHashCode = function (m) { + return Array.prototype.reduce && m.split("").reduce(function (g, j) { + g = ((g << 5) - g) + j.charCodeAt(0); + return g & g; + }, 0); + }; + P.isString = function (g) { + return typeof g === 'string'; + }; + P.extractInfoFromBase64DataURI = function (g) { + return /^data:([\w]+?\/([\w]+?));base64,(.+?)$/g.exec(g); + }; + P.supportsArrayBuffer = function () { + return typeof ArrayBuffer !== 'undefined' && typeof Uint8Array !== 'undefined'; + }; + P.isArrayBuffer = function (g) { + if (!this.supportsArrayBuffer()) return false; + return g instanceof ArrayBuffer; + }; + P.isArrayBufferView = function (g) { + if (!this.supportsArrayBuffer()) return false; + if (typeof Uint32Array === 'undefined') return false; + return (g instanceof Int8Array || g instanceof Uint8Array || (typeof Uint8ClampedArray !== 'undefined' && g instanceof Uint8ClampedArray) || g instanceof Int16Array || g instanceof Uint16Array || g instanceof Int32Array || g instanceof Uint32Array || g instanceof Float32Array || g instanceof Float64Array); + }; + P.binaryStringToUint8Array = function (g) { + var j = g.length, + m = new Uint8Array(j); + for (var n = 0; n < j; n++) { + m[n] = g.charCodeAt(n); + } + return m; + }; + P.arrayBufferToBinaryString = function (g) { + if (this.isArrayBuffer(g)) g = new Uint8Array(g); + var j = '', + m = g.byteLength; + for (var n = 0; n < m; n++) { + j += String.fromCharCode(g[n]); + } + return j; + }; + P.arrayBufferToBase64 = function (g) { + var j = '', + m = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', + n = new Uint8Array(g), + o = n.byteLength, + q = o % 3, + s = o - q, + t, v, H, z, I; + for (var K = 0; K < s; K = K + 3) { + I = (n[K] << 16) | (n[K + 1] << 8) | n[K + 2]; + t = (I & 16515072) >> 18; + v = (I & 258048) >> 12; + H = (I & 4032) >> 6; + z = I & 63; + j += m[t] + m[v] + m[H] + m[z]; + } + if (q == 1) { + I = n[s]; + t = (I & 252) >> 2; + v = (I & 3) << 4; + j += m[t] + m[v] + '=='; + } else if (q == 2) { + I = (n[s] << 8) | n[s + 1]; + t = (I & 64512) >> 10; + v = (I & 1008) >> 4; + H = (I & 15) << 2; + j += m[t] + m[v] + m[H] + '='; + } + return j; + }; + P.createImageInfo = function (g, j, m, n, o, q, s, t, v, H, z, I) { + var K = { + alias: t, + w: j, + h: m, + cs: n, + bpc: o, + i: s, + data: g + }; + if (q) K.f = q; + if (v) K.dp = v; + if (H) K.trns = H; + if (z) K.pal = z; + if (I) K.smask = I; + return K; + }; + P.addImage = function (g, j, m, n, o, q, s, t, v) { + 'use strict'; + if (typeof j !== 'string') { + var H = q; + q = o; + o = n; + n = m; + m = j; + j = H; + } + if (typeof g === 'object' && !S(g) && "imageData" in g) { + var z = g; + g = z.imageData; + j = z.format || j; + m = z.x || m || 0; + n = z.y || n || 0; + o = z.w || o; + q = z.h || q; + s = z.alias || s; + t = z.compression || t; + v = z.rotation || z.angle || v; + } + if (isNaN(m) || isNaN(n)) { + console.error('jsPDF.addImage: Invalid coordinates', arguments); + throw new Error('Invalid coordinates passed to jsPDF.addImage'); + } + var I = s0.call(this), + K; + if (!(K = f0(g, I))) { + var M; + if (S(g)) g = y0(g, j, v); + if (m0(s)) s = j0(g); + if (!(K = f0(s, I))) { + if (this.isString(g)) { + var N = this.extractInfoFromBase64DataURI(g); + if (N) { + j = N[2]; + g = atob(N[3]); + } else { + if (g.charCodeAt(0) === 0x89 && g.charCodeAt(1) === 0x50 && g.charCodeAt(2) === 0x4e && g.charCodeAt(3) === 0x47) j = 'png'; + } + } + j = (j || 'JPEG').toLowerCase(); + if (e0(j)) throw new Error('addImage currently only supports formats ' + X + ', not \'' + j + '\''); + if (R(j)) throw new Error('please ensure that the plugin for \'' + j + '\' support is added'); + if (this.supportsArrayBuffer()) { + M = g; + g = this.binaryStringToUint8Array(g); + } + K = this['process' + j.toUpperCase()](g, k0(I), s, Q(t), M); + if (!K) throw new Error('An unkwown error occurred whilst processing the image'); + } + } + z0.call(this, m, n, o, q, K, K.i, I); + return this; + }; + var C0 = function (g) { + 'use strict'; + var j, m, n; + if (!g.charCodeAt(0) === 0xff || !g.charCodeAt(1) === 0xd8 || !g.charCodeAt(2) === 0xff || !g.charCodeAt(3) === 0xe0 || !g.charCodeAt(6) === 'J'.charCodeAt(0) || !g.charCodeAt(7) === 'F'.charCodeAt(0) || !g.charCodeAt(8) === 'I'.charCodeAt(0) || !g.charCodeAt(9) === 'F'.charCodeAt(0) || !g.charCodeAt(10) === 0x00) { + throw new Error('getJpegSize requires a binary string jpeg file'); + } + var o = g.charCodeAt(4) * 256 + g.charCodeAt(5), + q = 4, + s = g.length; + while (q < s) { + q += o; + if (g.charCodeAt(q) !== 0xff) { + throw new Error('getJpegSize could not find the size of the image'); + } + if (g.charCodeAt(q + 1) === 0xc0 || g.charCodeAt(q + 1) === 0xc1 || g.charCodeAt(q + 1) === 0xc2 || g.charCodeAt(q + 1) === 0xc3 || g.charCodeAt(q + 1) === 0xc4 || g.charCodeAt(q + 1) === 0xc5 || g.charCodeAt(q + 1) === 0xc6 || g.charCodeAt(q + 1) === 0xc7) { + m = g.charCodeAt(q + 5) * 256 + g.charCodeAt(q + 6); + j = g.charCodeAt(q + 7) * 256 + g.charCodeAt(q + 8); + n = g.charCodeAt(q + 9); + return [j, m, n]; + } else { + q += 2; + o = g.charCodeAt(q) * 256 + g.charCodeAt(q + 1); + } + } + }, + Z = function (g) { + var j = (g[0] << 8) | g[1]; + if (j !== 0xFFD8) throw new Error('Supplied data is not a JPEG'); + var m = g.length, + n = (g[4] << 8) + g[5], + o = 4, + q, s, t, v; + while (o < m) { + o += n; + q = I0(g, o); + n = (q[2] << 8) + q[3]; + if ((q[1] === 0xC0 || q[1] === 0xC2) && q[0] === 0xFF && n > 7) { + q = I0(g, o + 5); + s = (q[2] << 8) + q[3]; + t = (q[0] << 8) + q[1]; + v = q[4]; + return { + width: s, + height: t, + numcomponents: v + }; + } + o += 2; + } + throw new Error('getJpegSizeFromBytes could not find the size of the image'); + }, + I0 = function (g, j) { + return g.subarray(j, j + 5); + }; + P.processJPEG = function (g, j, m, n, o) { + 'use strict'; + var q = this.color_spaces.DEVICE_RGB, + s = this.decode.DCT_DECODE, + t = 8, + v; + if (this.isString(g)) { + v = C0(g); + return this.createImageInfo(g, v[0], v[1], v[3] == 1 ? this.color_spaces.DEVICE_GRAY : q, t, s, j, m); + } + if (this.isArrayBuffer(g)) g = new Uint8Array(g); + if (this.isArrayBufferView(g)) { + v = Z(g); + g = o || this.arrayBufferToBinaryString(g); + return this.createImageInfo(g, v.width, v.height, v.numcomponents == 1 ? this.color_spaces.DEVICE_GRAY : q, t, s, j, m); + } + return null; + }; + P.processJPG = function () { + return this.processJPEG.apply(this, arguments); + }; +})(jsPDF.API); \ No newline at end of file diff --git a/odex30_base/data_chart/static/src/json/ar.json b/odex30_base/data_chart/static/src/json/ar.json new file mode 100644 index 0000000..d4a0fab --- /dev/null +++ b/odex30_base/data_chart/static/src/json/ar.json @@ -0,0 +1,389 @@ +{ + "fieldsList": { + "flatHierarchyBox": "Select and arrange columns", + "hierarchyBox": "Drag Dimensions", + "filterBox": "Drop & Arrange Report Filter", + "rowBox": "Drop & Arrange Rows", + "columnBox": "Drop & Arrange Columns", + "measureBox": "Drop & Arrange Values", + "values": "Values", + "addCalculatedMeasure": "Add calculated value", + "expandAll": "Expand All", + "collapseAll": "Collapse All", + "formulasGroupName": "Calculated Values", + "allFields": "All Fields", + "rows": "Rows", + "columns": "Columns", + "filters": "Report Filters", + "dropField": "Drop field here", + "title": "Fields", + "subtitle": "Drag and drop fields to arrange" + }, + "filter": { + "all": "All", + "multipleItems": "Multiple Items", + "selectAll": "Select All", + "selectAllResults": "Select All Results", + "top": "Top", + "bottom": "Bottom", + "ascSort": "Az", + "descSort": "zA", + "topX": "Top 10", + "clearTopX": "Clear", + "measuresPrompt": "Choose value", + "search": "Search", + "amountSelected": "{0} of {1} selected", + "amountFound": "{0} of {1} found are selected", + "sort": "Sort:", + "addGroup": "Add group", + "groupName": "Group 1", + "ungroup": "Ungroup" + }, + "drillThrough": { + "title": "العنوان", + "row": "سطر: {0}", + "column": "عمود: {0}", + "value": "{0}: {1}" + }, + "calculatedView": { + "title": "قيمة محسوبة", + "measureBox": "Drag values to formula", + "measureName": "Value name", + "formula": "Formula", + "formulaPrompt": "Drop values and edit formula here", + "calculateIndividualValues": "Calculate individual values", + "removeValue": "Remove", + "removeValueTitle": "Remove {0}?", + "removeValueMessage": "Are you sure you want to remove this calculated value?", + "header": "Add calculated value", + "allValues": "All values" + }, + "grid": { + "total": "مجموع", + "totals": "مجاميع", + "grandTotal": "مجموع إجمالي", + "blankMember": "(فارغ)", + "dateInvalidCaption": "تاريخ غير صحيح", + "reportInformation": "معلومات التقرير" + }, + "tooltips": { + "row": "سطر:", + "column": "عمود:", + "headerResize": "Drag to resize", + "headerFit": "Double click to fit", + "filterIcon": "Click to filter", + "filtered": "Filtered", + "expandIcon": "Click to expand", + "collapseIcon": "Click to collapse", + "drillDown": "Click to drill down", + "drillUp": "Click to drill up", + "sortIcon": "Click to sort Desc", + "sortedDescIcon": "Click to sort Asc", + "sortedAscIcon": "Click to sort Desc", + "close": "Click to close" + }, + "aggregations": { + "sum": { + "caption": "مجموع", + "totalCaption": "مجموع {0}", + "grandTotalCaption": "مجموع إجمالي {0}" + }, + "count": { + "caption": "عدد", + "totalCaption": "عدد {0}", + "grandTotalCaption": "مجموع أعداد {0}" + }, + "distinctCount": { + "caption": "Distinct Count", + "totalCaption": "Distinct Count of {0}", + "grandTotalCaption": "Total Distinct Count of {0}" + }, + "difference": { + "caption": "Difference", + "totalCaption": "Difference of {0}", + "grandTotalCaption": "Difference of {0}" + }, + "percentDifference": { + "caption": "% Difference", + "totalCaption": "% Difference of {0}", + "grandTotalCaption": "% Difference of {0}" + }, + "average": { + "caption": "Average", + "totalCaption": "Average of {0}", + "grandTotalCaption": "Total Average of {0}" + }, + "product": { + "caption": "Product", + "totalCaption": "Product of {0}", + "grandTotalCaption": "Total Product of {0}" + }, + "min": { + "caption": "Min", + "totalCaption": "Min of {0}", + "grandTotalCaption": "Total Min of {0}" + }, + "max": { + "caption": "Max", + "totalCaption": "Max of {0}", + "grandTotalCaption": "Total Max of {0}" + }, + "percent": { + "caption": "% of Grand Total", + "totalCaption": "% of Grand Total of {0}", + "grandTotalCaption": "Total % of Grand Total of {0}" + }, + "percentOfColumn": { + "caption": "% of Column", + "totalCaption": "% of Column of {0}", + "grandTotalCaption": "Total % of Column of {0}" + }, + "percentOfRow": { + "caption": "% of Row", + "totalCaption": "% of Row of {0}", + "grandTotalCaption": "Total % of Row of {0}" + }, + "index": { + "caption": "Index", + "totalCaption": "Index of {0}", + "grandTotalCaption": "Index of {0}" + }, + "none": { + "caption": "No Calculation" + } + }, + "messages": { + "error": "Error!", + "warning": "Warning!", + "limitation": "Limitation!", + "browse": "Browse", + "confirmation": "Confirmation", + "reportFileType": "Flexmonster report file", + "loading": "Loading...", + "loadingConfiguration": "", + "loadingData": "Loading data...", + "waiting": "Waiting for the response {0} sec.", + "progress": "{0}K", + "progressUnknown": "loaded {0}K", + "analyzing": "Analyzing data...", + "analyzingProgress": "{0} records of {1} ({2}%)", + "analyzingRecords": "{0}% records", + "saving": "Saving...", + "loadingDimensions": "Loading dimensions...", + "loadingHierarchies": "Loading hierarchies...", + "loadingMeasures": "Loading measures...", + "loadingKPIs": "Loading KPIs...", + "loadingMembers": "Loading members...", + "loadingLevels": "Loading levels...", + "loadingProperties": "Loading properties...", + "fullscreen": "Open report in full screen?", + "exportComplete": "Export data is created, please click \"Save\" button to save the _data.", + "exportProgress": "Export in progress...", + "exportError": "Failed to export. An unexpected error occurred.", + "generatingPDF": "Generating PDF", + "pleaseWait": "Please wait.", + "pagesWereGenerated": "pages were generated.", + "uploading": "Uploading...", + "cantSaveFile": "Cannot save file.", + "cantSaveToClipboard": "Error: Cannot write to the clipboard.", + "saveReportToFile": "Report is ready to be saved to file, please click \"Save\" button to save the report.", + "loadReportFromFile": "Select report file to be loaded.", + "inputNewName": "Input new name", + "inputReportName": "Please input report name", + "invalidDataSource": "Invalid datasource or catalog. Please check.

    Read more info about this error", + "dataStreamError": "Stream error occurred while loading '{0}'

    Read more info about this error", + "unableToOpenFile": "Unable to open file {0}.

    It seems that this file doesn't exist or 'Access-Control-Allow-Origin' header is absent in the resource requested.

    Read more info about this error", + "unableTwoFileBrowsingSessions": "Browse file dialog is already opened.", + "inappropriateFileFormat": "The data file is of inappropriate format.", + "invalidJSONdata": "JSON data is invalid.", + "wrongFormulaFormat": "Wrong formula format. Please check.", + "excelCsvChartsExportError": "Export to Microsoft Excel or CSV is not available for charts.", + "excelPdfExportLimitation": "Export to Microsoft Excel or PDF is not available in the current edition.", + "excelExportLimitation": "Export is not available in the current edition.", + "noDataAvailable": "Data source is empty. Please check the CSV file.", + "saveDataToFile": "Data is ready to be saved to file, please click \"Save\" button to save the file.", + "dataWasUpdated": "Data source has been updated on the server. Refresh the report?", + "ocsvIncompatible": "Unable to read data source. It seems that OCSV file was compressed with a newer version. Please update the component to version {0} or newer.", + "unknownError": "Unknown error occurred.", + "invalidReportFormat": "Invalid report format or access to file is denied.", + "csvHeaderParsingError": "CSV header parsing error.", + "tooManyColumnsInClassicMode": "Too many columns for classic form. Switched layout to compact form.", + "cantExpand": "Some fields cannot be expanded. Please narrow down the data set.", + "cantExpandTitle": "Data set is too large" + }, + "buttons": { + "ok": "OK", + "apply": "تطبيق", + "cancel": "إلغاء", + "save": "حفظ", + "clear": "تفريغ", + "select": "إختيار", + "yes": "نعم", + "no": "لا" + }, + "contextMenu": { + "clearSorting": "Clear sorting", + "collapse": "Collapse", + "drillThrough": "Drill through", + "expand": "Expand", + "openFilter": "Open filter", + "sortColumnAsc": "Sort column asc", + "sortColumnDesc": "Sort column desc", + "sortRowAsc": "Sort row asc", + "sortRowDesc": "Sort row desc" + }, + "date": { + "year": "Year", + "quarter": "Quarter", + "month": "Month", + "day": "Day" + }, + "quarters": { + "q1": "Quarter 1", + "q2": "Quarter 2", + "q3": "Quarter 3", + "q4": "Quarter 4" + }, + "months": { + "january": "January", + "february": "February", + "march": "March", + "april": "April", + "may": "May", + "june": "June", + "july": "July", + "august": "August", + "september": "September", + "october": "October", + "november": "November", + "december": "December" + }, + "monthsShort": { + "january": "Jan", + "february": "Feb", + "march": "Mar", + "april": "Apr", + "may": "May", + "june": "Jun", + "july": "Jul", + "august": "Aug", + "september": "Sep", + "october": "Oct", + "november": "Nov", + "december": "Dec" + }, + "weekdays": { + "first": "Sunday", + "second": "Monday", + "third": "Tuesday", + "fourth": "Wednesday", + "fifth": "Thursday", + "sixth": "Friday", + "seventh": "Saturday" + }, + "weekdaysShort": { + "first": "Sun", + "second": "Mon", + "third": "Tue", + "fourth": "Wed", + "fifth": "Thu", + "sixth": "Fri", + "seventh": "Sat" + }, + "toolbar": { + "connect": "Connect", + "connect_local_csv": "To local CSV", + "connect_local_ocsv": "To local OCSV", + "connect_local_json": "To local JSON", + "connect_remote_csv": "To remote CSV", + "connect_remote_csv_mobile": "CSV", + "connect_remote_json": "To remote JSON", + "connect_remote_json_mobile": "JSON", + "open": "Open", + "local_report": "Local report", + "remote_report": "Remote report", + "remote_report_mobile": "Report", + "save": "Save", + "save_json": null, + "load_json": "JSON report", + "grid": "Grid", + "grid_flat": "Flat", + "grid_classic": "Classic", + "grid_compact": "Compact", + "format": "التنسيق", + "format_cells": "تنسيق الخلايا", + "format_cells_mobile": "تنسيق", + "conditional_formatting": "التنسيق الشرطي", + "conditional_formatting_mobile": "شرطي", + "options": "الخيارات", + "fullscreen": "شاشة كاملة", + "minimize": "تصغير", + "export": "إستخراج", + "export_print": "Print", + "export_html": "To HTML", + "export_excel": "To Excel", + "export_pdf": "To PDF", + "fields": "الحقول", + "ok": "حسنا", + "apply": "تطبيق", + "done": "تم", + "cancel": "إلغاء", + "value": "Value", + "delete": "حذف", + "if": "إذا كان", + "then": "فإن", + "open_remote_csv": "Open remote CSV", + "open_remote_json": "Open remote JSON", + "csv": "CSV", + "open_remote_report": "Open remote report", + "choose_value": "إختر قيمة", + "text_align": "Text align", + "align_left": "يسار", + "align_right": "يمين", + "none": "فارغ", + "space": "(مساحة)", + "thousand_separator": "علامة اﻷلوف", + "decimal_separator": "العلامة العشرية", + "decimal_places": "Decimal places", + "currency_symbol": "علامة العملة", + "currency_align": "تنسيق العملة", + "null_value": "قيمةفارغة", + "is_percent": "تنسيق كمئوي", + "true_value": "صواب", + "false_value": "خطأ", + "conditional": "شرطي", + "add_condition": "إضافة شرط", + "less_than": "أقل من ", + "less_than_or_equal": "أقل من أو يساوي", + "greater_than": "أكبر من ", + "greater_than_or_equal": "أكبر من أو يساوي", + "equal_to": "يساوي", + "not_equal_to": "لا يساوي", + "between": "بين", + "is_empty": "خالي", + "all_values": "كل القيم", + "and": "و", + "and_symbole": "&", + "cp_text": "نص", + "cp_highlight": "لون الخلفية", + "layout_options": "خيارات التنسيق", + "layout": "التنسيق", + "compact_view": "Compact form", + "classic_view": "Classic form", + "flat_view": "Flat form", + "grand_totals": "المجموع الإجمالي", + "grand_totals_off": "عدم إظهار المجموع الإجمالي", + "grand_totals_on": "إظهار المجموع الإجمالي", + "grand_totals_on_rows": "إظهار المجموع الإجمالي للسطور فقط", + "grand_totals_on_columns": "إظهار المجموع الإجمالي للأعمدة فقط", + "subtotals": "المجاميع الفرعية", + "subtotals_off": "عدم إظهار المجاميع الفرعية", + "subtotals_on": "إظهار المجاميع الفرعية", + "subtotals_on_rows": "إظهار المجاميع الفرعية للسطور فقط", + "subtotals_on_columns": "إظهار المجاميع الفرعية للأعمدة فقط", + "choose_page_orientation": "إختار تنسيق الصفحة", + "landscape": "أفقي", + "portrait": "رأسي", + "to_printer": "إلى الطابعة" + } +} \ No newline at end of file diff --git a/odex30_base/data_chart/static/src/less/report_design.less b/odex30_base/data_chart/static/src/less/report_design.less new file mode 100644 index 0000000..02a8ff7 --- /dev/null +++ b/odex30_base/data_chart/static/src/less/report_design.less @@ -0,0 +1,47 @@ +.wdr_component_sub_container { + width: 100%; + text-align: center; + position: relative; + background-color: #fff; + padding: 2em; + + h1 { + margin: 0 0 2rem 0; + } + + .message_demo_barcodes { + font-size: 0.9em; + margin: 0; + } + + img { + overflow:hidden; // prevent margins colapsing with h1 + margin-top: 3rem; + width: 200px; + } + + p { + text-align: left; + margin: 3rem 0; + } + + > button { + font-size: 1.2em; + margin-bottom: 2rem; + width: 100%; + } + + > button:last-child { + margin-bottom: 0; + } + + @media (min-width: @screen-sm-min) { + flex: 0 0 auto; + width: 550px; + border-radius: 10px; + background-color: rgba(255,255,255,0.8); + box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.6); + font-size: 1.2em; + padding: 3em; + } +} \ No newline at end of file diff --git a/odex30_base/data_chart/static/src/xml/data_chart_templates.xml b/odex30_base/data_chart/static/src/xml/data_chart_templates.xml new file mode 100644 index 0000000..23eecb0 --- /dev/null +++ b/odex30_base/data_chart/static/src/xml/data_chart_templates.xml @@ -0,0 +1,27 @@ + + + + + + +
    +
    + + + + + + + + + +
    + +
    +
    +
    +
    + + + +
    diff --git a/odex30_base/data_chart/views/data_chart_report_view.xml b/odex30_base/data_chart/views/data_chart_report_view.xml new file mode 100644 index 0000000..2c607eb --- /dev/null +++ b/odex30_base/data_chart/views/data_chart_report_view.xml @@ -0,0 +1,95 @@ + + + + + data.chart.report.view.tree + data.chart.report + + + + + + + + + + data.chart.report.view.form + data.chart.report + +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + + + + Reports + data.chart.report + list,form + +

    + +

    +

    + +

    +
    +
    + + + + + + +
    diff --git a/odex30_base/data_chart/views/views.xml b/odex30_base/data_chart/views/views.xml new file mode 100644 index 0000000..4b2b790 --- /dev/null +++ b/odex30_base/data_chart/views/views.xml @@ -0,0 +1,16 @@ + + +