diff --git a/README.md b/README.md index 8b10e6960..6864725ce 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# odex25-standard-moduless +# odex25-standard-modules This Repo contains general standard modules for all projects. diff --git a/odex25_transactions/.idea/inspectionProfiles/Project_Default.xml b/odex25_transactions/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 000000000..480ffc0b0 --- /dev/null +++ b/odex25_transactions/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,29 @@ + + + + \ No newline at end of file diff --git a/odex25_transactions/.idea/inspectionProfiles/profiles_settings.xml b/odex25_transactions/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 000000000..105ce2da2 --- /dev/null +++ b/odex25_transactions/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/odex25_transactions/.idea/modules.xml b/odex25_transactions/.idea/modules.xml new file mode 100644 index 000000000..a57643433 --- /dev/null +++ b/odex25_transactions/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/odex25_transactions/.idea/odex25_transactions.iml b/odex25_transactions/.idea/odex25_transactions.iml new file mode 100644 index 000000000..d0876a78d --- /dev/null +++ b/odex25_transactions/.idea/odex25_transactions.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/odex25_transactions/README.rst b/odex25_transactions/README.rst new file mode 100644 index 000000000..d64cf9a56 --- /dev/null +++ b/odex25_transactions/README.rst @@ -0,0 +1,4 @@ +*pip install arabic-reshaper +*pip install python-bidi +pip install python-barcode + diff --git a/odex25_transactions/cm_entity_sync_odex/__init__.py b/odex25_transactions/cm_entity_sync_odex/__init__.py new file mode 100644 index 000000000..3e0935305 --- /dev/null +++ b/odex25_transactions/cm_entity_sync_odex/__init__.py @@ -0,0 +1,4 @@ +#-*- coding: utf-8 -*- +from . import models +from . import wizards +from . import controllers diff --git a/odex25_transactions/cm_entity_sync_odex/__manifest__.py b/odex25_transactions/cm_entity_sync_odex/__manifest__.py new file mode 100644 index 000000000..186e57b1a --- /dev/null +++ b/odex25_transactions/cm_entity_sync_odex/__manifest__.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Odex - Communications Management System. +# Copyright (C) 2020 Expert Co. Ltd. (). +# +############################################################################## +{ + 'name' : 'C.M. Entity Sync', + 'version' : '0.1', + 'sequence' : 4, + 'author' : 'Expert Co. Ltd.', + 'category' : 'Odex25-Transactions/Odex25-Transactions', + 'summary' : 'Correspondence Management, Entity Sync', + 'description' : """ +Odex - Correspondence Management, Entity Syncronization +======================================================== + +Intercompanies entity syncronization + """, + 'website': 'http://www.exp-sa.com', + 'depends': ['exp_transaction_documents'], + 'data': [ + 'security/ir.model.access.csv', + # data + 'data/data.xml', + # views + 'views/entity_view.xml', + 'views/settings_view.xml', + # wizards + 'wizards/inter_entity_wizard.xml', + # actions amd menus + 'views/actions_and_menus.xml', + ], + 'qweb' : [ + ], + 'installable': True, + 'auto_install': False, + 'application': False, +} + diff --git a/odex25_transactions/cm_entity_sync_odex/controllers/__init__.py b/odex25_transactions/cm_entity_sync_odex/controllers/__init__.py new file mode 100644 index 000000000..398e67254 --- /dev/null +++ b/odex25_transactions/cm_entity_sync_odex/controllers/__init__.py @@ -0,0 +1,2 @@ +#-*- coding: utf-8 -*- +from . import sync diff --git a/odex25_transactions/cm_entity_sync_odex/controllers/sync.py b/odex25_transactions/cm_entity_sync_odex/controllers/sync.py new file mode 100644 index 000000000..e4b270a1c --- /dev/null +++ b/odex25_transactions/cm_entity_sync_odex/controllers/sync.py @@ -0,0 +1,312 @@ +#-*- coding: utf-8 -*- +import logging +import datetime +import base64 +from odoo import http +from odoo.http import request +from odoo import models, api, fields, _,exceptions,SUPERUSER_ID + + +_logger = logging.getLogger(__name__) + + +class Sync(http.Controller): + @http.route('/cm/sync/broadcast', type='json', auth='public', methods=['POST']) + def add_new(self, **kw): + keys = [ + 'url', + 'name', + 'code', + 'key', + 'auth', + ] + for k in keys: + if not kw.get(k, False): + return { + 'error': 'Bad Request 1', + } + inter_entity = request.env['cm.inter_entity'].sudo() + if not inter_entity.authenticate(kw.get('auth', '')): + return { + 'error': 'Bad Request 2', + 'req': kw, + } + data = { + 'url': kw.get('url', ''), + 'name': kw.get('name', ''), + 'code': kw.get('code', ''), + 'uuid': kw.get('key', ''), + } + entities = inter_entity.add_new(data) + return { + 'success': True, + 'entities': entities, + } + + @http.route('/cm/sync/update_from', type='json', auth='public', methods=['POST']) + def update_from(self, **kw): + keys = [ + 'key', + 'auth', + ] + for k in keys: + if not kw.get(k, False): + return { + 'error': 'Bad Request 1', + } + inter_entity = request.env['cm.inter_entity'].sudo() + if not inter_entity.authenticate(kw.get('auth', '')): + return { + 'error': 'Bad Request 2', + 'req': kw, + } + return { + 'success': True, + 'entities': inter_entity.get_entities() + } + data = { + 'url': kw.get('url', ''), + 'name': kw.get('name', ''), + 'code': kw.get('code', ''), + 'uuid': kw.get('key', ''), + } + entities = inter_entity.add_new(data) + return { + 'success': True, + 'entities': entities, + } + + @http.route('/cm/sync/new_key', type='json', auth='public', methods=['POST']) + def new_key(self, **kw): + keys = [ + 'old', + 'key', + 'auth', + ] + for k in keys: + if not kw.get(k, False): + return { + 'error': 'Bad Request 1', + } + inter_entity = request.env['cm.inter_entity'].sudo() + if not inter_entity.authenticate(kw.get('auth', '')): + return { + 'error': 'Bad Request 2', + } + old = inter_entity.search([('uuid', '=', kw.get('old'))], limit=1) + if len(old): + data = { + 'uuid': kw.get('key'), + 'code': kw.get('key').split('-')[0], + } + old.write(data) + return { + 'success': True, + } + + @http.route('/cm/sync/update_entity', type='json', auth='public', methods=['POST']) + def update_entity(self, **kw): + keys = [ + 'data', + 'auth', + ] + for k in keys: + if not kw.get(k, False): + return { + 'error': 'Bad Request 1', + } + inter_entity = request.env['cm.inter_entity'].sudo() + inter_entity_set = request.env['cm.inter_entity.sync'].sudo() + if not inter_entity.authenticate(kw.get('auth', '')): + return { + 'error': 'Bad Request 2', + } + data = kw['data'] + key = data['key'] + entity = inter_entity.search([('uuid', '=', key)], limit=1) + ecode = data['details']['code'] + is_new = data['details'].get('is_new', False) + if len(entity): + en = request.env['cm.entity'].sudo().search( + [('inter_entity_code', '=', ecode), ('inter_entity_id', '=', entity.id)]) + if len(en): + d = data['details']['data'] + d['broadcasted'] = True + en.write(d) + elif is_new: + d = data['details']['data'] + dd = { + 'name': d.get('name', ''), + # 'code': d.get('code', ''), + 'type': 'external', + 'is_inter_entity': True, + 'inter_entity_code': d.get('inter_entity_code', ''), + 'inter_entity_id': entity.id, + } + request.env['cm.entity'].sudo().create(dd) + else: + return { + 'error': 'No Record' + } + return { + 'success': True, + } + + @http.route('/cm/sync/push_new', type='json', auth='public', methods=['POST']) + def push_new(self, **kw): + keys = [ + 'data', + 'auth', + ] + for k in keys: + if not kw.get(k, False): + return { + 'error': 'Bad Request 1', + } + inter_entity = request.env['cm.inter_entity'].sudo() + if not inter_entity.authenticate(kw.get('auth', '')): + return { + 'error': 'Bad Request 2', + } + data = kw['data'] + key = data['key'] + entity = inter_entity.search([('uuid', '=', key)], limit=1) + + if len(entity): + + d = data['data'] + dd = { + 'name': d.get('name', ''), + # 'code': d.get('code', ''), + 'type': 'external', + 'is_inter_entity': True, + 'inter_entity_code': d.get('inter_entity_code', ''), + 'inter_entity_id': entity.id, + } + try: + request.env['cm.entity'].sudo().with_context( + broacasted=True).create(dd) + return { + 'success': True, + } + except Exception as e: + return { + 'error': 'No Record' + } + else: + return { + 'error': 'No Record' + } + return { + 'success': True, + } + + @http.route('/cm/sync/send_transaction', type='json', auth='public', methods=['POST']) + def send_transaction(self, **kw): + keys = [ + 'data', + 'code', + 'key', + 'auth', + ] + for k in keys: + if not kw.get(k, False): + return { + 'error': 'Bad Request 1', + } + inter_entity = request.env['cm.inter_entity'].sudo() + Entity = request.env['cm.entity'].sudo() + if not inter_entity.authenticate(kw.get('auth', '')): + return { + 'error': 'Bad Request 2', + } + data = kw['data'] + code = kw['code'] + key = kw['key'] + auth = kw['auth'] + from_id = data['from_id'] + ie = inter_entity.search([('uuid', '=', auth)], limit=1) + extie = inter_entity.search([('uuid', '=', key)], limit=1) + setting = inter_entity.get_settings() + if not len(ie) or not len(extie): + return { + 'error': 'No Record 1' + } + if not from_id: + from_id = Entity.search([('is_master_entity', '=', True), + ('type', '=', 'external'), ('inter_entity_id', '=', extie.id)], limit=1) + if not len(from_id): + return { + 'error': 'No Record 2' + } + else: + from_id = Entity.search([('inter_entity_code', '=', from_id), ( + 'type', '=', 'external'), ('inter_entity_id', '=', extie.id)], limit=1) + if not len(from_id): + return { + 'error': 'No Record 3' + } + entity = Entity.search([('inter_entity_code', '=', code),('type', '=', 'unit')], limit=1) + if len(entity) > 0 and len(from_id) > 0: + Incoming = request.env['incoming.transaction'].sudo() + d = data + d['from_id'] = from_id.id + d['inter_entity_id'] = extie.id + d['important_id'] = setting.important_id.id + d['subject_type_id'] = setting.subject_type_id.id + if len(entity.secretary_id): + d['employee_id'] = entity.secretary_id.id + d['preparation_id'] = entity.id + else: + d['employee_id'] = setting.employee_id.id + d['preparation_id'] = setting.id + d['to_ids'] = [(4, entity.id), ] + # if entity.body: + # d['body'] = entity.body + d['due_date'] = fields.date.today() + attachment_rule_ids = d.get('attachment_rule_ids') + d.pop('attachment_rule_ids') + inc = Incoming.create(d) + for attachment in attachment_rule_ids: + attachement_rule = request.env['cm.attachment.rule'].sudo().create({ + 'employee_id': entity.secretary_id.id if len(entity.secretary_id) else setting.employee_id.id, + 'entity_id': entity.id, + 'file_save': attachment['file_save'], + 'attachment_filename': attachment['attachment_filename'], + 'incoming_transaction_id': inc.id if inc.id else False, + 'date': attachment['date'], + 'description': attachment['description'], + }) + attachment_data = { + 'name': attachment['attachment_filename'], + 'datas_fname': attachment['attachment_filename'], + 'datas': attachment['file_save'], + 'res_model': 'cm.attachment.rule', + 'res_id': attachement_rule.id, + } + request.env['ir.attachment'].sudo().create(attachment_data) + inc.preparation_id = inc.entity_id + # notification system and mailing + employee = inc.from_id + subj = _('Message Has been send !') + msg = _(u'{} ← {}.{}').format(employee and employee.name or '#', + u' / '.join([k.name for k in inc.to_ids]), + u'رابط المعاملة ' % (inc.get_url())) + partner_ids = [] + for partner in inc.to_ids: + if partner.type == 'unit': + partner_ids.append(partner.secretary_id.user_id.partner_id.id) + elif partner.type == 'employee': + partner_ids.append(partner.user_id.partner_id.id) + # thread_obj = request.env['mail.thread'] + # thread_obj.message_post(type="notification", subject=subj, body=msg, + # partner_ids=partner_ids, + # subtype="mail.mt_comment") + # inc.send_message(template='exp_transaction_documents.incoming_notify_send_send_email') + else: + return { + 'error': 'No Record 4' + } + return { + 'success': True, + } \ No newline at end of file diff --git a/odex25_transactions/cm_entity_sync_odex/data/data.xml b/odex25_transactions/cm_entity_sync_odex/data/data.xml new file mode 100644 index 000000000..41e3ed549 --- /dev/null +++ b/odex25_transactions/cm_entity_sync_odex/data/data.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + Inter-Entities Seq + cm.inter.entity + + + 6 + + + diff --git a/odex25_transactions/cm_entity_sync_odex/i18n/ar_SY.po b/odex25_transactions/cm_entity_sync_odex/i18n/ar_SY.po new file mode 100644 index 000000000..522c0331c --- /dev/null +++ b/odex25_transactions/cm_entity_sync_odex/i18n/ar_SY.po @@ -0,0 +1,345 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * cm_entity_sync_odex +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-05-16 03:24+0000\n" +"PO-Revision-Date: 2020-05-16 03:24+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: cm_entity_sync_odex +#: model:ir.model.fields,help:cm_entity_sync_odex.field_cm_entity_is_inter_entity +#: model:ir.model.fields,help:cm_entity_sync_odex.field_cm_entity_is_master_entity +msgid "\n" +" If checked, this entity will be syncronized by other entities in the group.\n" +" " +msgstr "\n" +" اذا تمّ اختياره، سيتم مشاركة المؤسسة مع بقية المؤسسات في المجموعة.\n" +" " + +#. module: cm_entity_sync_odex +#: code:addons/cm_entity_sync_odex/models/entity.py:278 +#: code:addons/cm_entity_sync_odex/models/entity.py:280 +#, python-format +msgid "Access Error" +msgstr "ليس لديك صلاحية !" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_sync_activated +#: model:ir.ui.view,arch_db:cm_entity_sync_odex.view_cm_sync_config +msgid "Activate Syncronization" +msgstr "تفعيل نظام المزامنة" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_wizard_broadcast +msgid "Broadcast" +msgstr "مزامنة" + +#. module: cm_entity_sync_odex +#: code:addons/cm_entity_sync_odex/wizards/wizards.py:34 +#, python-format +msgid "Broadcast Error !Error While Broadcast new Server, please check server key and url." +msgstr "خطا في المزامنة ! خطا عند مزامنة مخدم الجديد , الرجاء التأكد من عنوان الويب او مفتاح المخدم." + +#. module: cm_entity_sync_odex +#: model:ir.ui.view,arch_db:cm_entity_sync_odex.view_cm_inter_entity_update_wizard +#: model:ir.ui.view,arch_db:cm_entity_sync_odex.view_cm_inter_entity_wizard +msgid "Cancel" +msgstr "إلغاء" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_code +msgid "Code" +msgstr "رمز" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_create_uid +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_sync_create_uid +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_update_wizard_create_uid +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_wizard_create_uid +msgid "Created by" +msgstr "أنشئ بواسطة" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_create_date +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_sync_create_date +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_update_wizard_create_date +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_wizard_create_date +msgid "Created on" +msgstr "أنشئ في" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_sync_server_id +msgid "Current Server" +msgstr "السيرفر (النظام) الحالي" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_sync_employee_id +msgid "Default Created By" +msgstr "مدخل المعاملة الافتراضي" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_sync_important_id +msgid "Default Important Degree" +msgstr "درجة الأهمية الافتراضية" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_sync_subject_type_id +msgid "Default Transaction Type" +msgstr "نوع المعاملة الافتراضي" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_name +msgid "Description" +msgstr "الوصف" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_display_name +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_sync_display_name +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_update_wizard_display_name +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_wizard_display_name +msgid "Display Name" +msgstr "الاسم المعروض" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_update_wizard_document_id +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_wizard_document_id +msgid "Document" +msgstr "مستند" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_sync_entities +msgid "Entities" +msgstr "العناوين و الجهات" + +#. module: cm_entity_sync_odex +#: model:ir.model,name:cm_entity_sync_odex.model_cm_inter_entity_sync +msgid "Entity Syncronization" +msgstr "الوحدات المتزامنه" + +#. module: cm_entity_sync_odex +#: model:ir.ui.view,arch_db:cm_entity_sync_odex.view_cm_inter_entity_wizard +msgid "Generate" +msgstr "توليــد" + +#. module: cm_entity_sync_odex +#: model:ir.ui.view,arch_db:cm_entity_sync_odex.view_cm_sync_config +msgid "Generate Key" +msgstr "توليد مفتاح مزامنة" + +#. module: cm_entity_sync_odex +#: code:addons/cm_entity_sync_odex/models/settings.py:36 +#, python-format +msgid "Generate new Key" +msgstr "توليد مفتاح مزامنة جديدة" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_id +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_sync_id +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_update_wizard_id +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_wizard_id +msgid "ID" +msgstr "المعرف" + +#. module: cm_entity_sync_odex +#: model:ir.ui.view,arch_db:cm_entity_sync_odex.view_cm_sync_config +msgid "Inter Entities" +msgstr "المؤسسات المتزامنة" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_incoming_transaction_inter_entity_id +msgid "Inter Entity" +msgstr "مؤسسة متزامنة" + +#. module: cm_entity_sync_odex +#: model:ir.actions.act_window,name:cm_entity_sync_odex.cm_inter_entity_sync_action +#: model:ir.ui.menu,name:cm_entity_sync_odex.cm_inter_entity_sync_menu +msgid "Inter Entity Sync" +msgstr "إعدادات المؤسسات المتزامنة" + +#. module: cm_entity_sync_odex +#: model:ir.ui.view,arch_db:cm_entity_sync_odex.cm_inter_entity_tree +msgid "Inter-Entities" +msgstr "المؤسسات المتزامنة" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_entity_inter_entity_code +msgid "Inter-Entities Code" +msgstr "رمز التزامن" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_entity_inter_entity_id +msgid "Inter-Entities Ref" +msgstr "مرجع المؤسسة المتزامنة" + +#. module: cm_entity_sync_odex +#: model:ir.ui.view,arch_db:cm_entity_sync_odex.cm_inter_entity_form +msgid "Inter-Entity" +msgstr "مؤسسة متزامنة" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_entity_is_inter_entity +msgid "Is Inter-Entity ?" +msgstr "مؤسسة متزامنة ؟" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_entity_is_master_entity +msgid "Is Master-Entity ?" +msgstr "مؤسسة متزمنة رئيسية ؟" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity___last_update +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_sync___last_update +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_update_wizard___last_update +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_wizard___last_update +msgid "Last Modified on" +msgstr "آخر تعديل في" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_sync_write_uid +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_update_wizard_write_uid +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_wizard_write_uid +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_write_uid +msgid "Last Updated by" +msgstr "آخر تحديث بواسطة" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_sync_write_date +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_update_wizard_write_date +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_wizard_write_date +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_write_date +msgid "Last Updated on" +msgstr "آخر تحديث في" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_update_wizard_primary_id +msgid "Main Server" +msgstr "الخادم الرئيسي" + +#. module: cm_entity_sync_odex +#: code:addons/cm_entity_sync_odex/controllers/sync.py:290 +#, python-format +msgid "Message Has been send !" +msgstr "تم ارسال الرساله" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_uuid +msgid "Secret Key" +msgstr "الرمز السري" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_wizard_server_key +msgid "Server Key" +msgstr "مفتاح التزامن للسيرفر" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_url +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_wizard_server_url +msgid "Server URL" +msgstr "رابط السيرفر" + +#. module: cm_entity_sync_odex +#: code:addons/cm_entity_sync_odex/models/entity.py:165 +#: code:addons/cm_entity_sync_odex/models/entity.py:266 +#: code:addons/cm_entity_sync_odex/models/entity.py:294 +#, python-format +msgid "Sync Error Cannot Syncronize new key to Server {}, URL \"{}\"" +msgstr "مشكلة في التزامن , غير قادر على مزامنة المفتاح الجديد Server {}, URL \"{}\"" + +#. module: cm_entity_sync_odex +#: code:addons/cm_entity_sync_odex/models/entity.py:242 +#, python-format +msgid "Sync Error Cannot send Transaction to server {}" +msgstr "مشكلة تزامن , لا يمكن ارسال المعاملة لمخدم {}" + +#. module: cm_entity_sync_odex +#: code:addons/cm_entity_sync_odex/models/entity.py:150 +#, python-format +msgid "Sync ErrorCannot Syncronize new key to Server {}, URL \"{}\"" +msgstr "مشكلة في التزامن , غير قادر على مزامنة المفتاح الجديد Server {}, URL \"{}\"" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_sync_sync_key +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_wizard_key +msgid "Sync Key" +msgstr "مفتاح التزامن" + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_incoming_transaction_syncronized +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_outgoing_transaction_syncronized +msgid "Syncronized ?" +msgstr "متزامن ؟" + +#. module: cm_entity_sync_odex +#: model:ir.model,name:cm_entity_sync_odex.model_cm_entity +msgid "Transactions Contacts" +msgstr "Transactions Contacts" + +#. module: cm_entity_sync_odex +#: model:ir.ui.view,arch_db:cm_entity_sync_odex.view_cm_inter_entity_update_wizard +msgid "Update" +msgstr "تحديث الخوادم" + +#. module: cm_entity_sync_odex +#: code:addons/cm_entity_sync_odex/models/settings.py:63 +#: model:ir.ui.view,arch_db:cm_entity_sync_odex.view_cm_sync_config +#, python-format +msgid "Update From ..." +msgstr "تحديث من ..." + +#. module: cm_entity_sync_odex +#: model:ir.model.fields,field_description:cm_entity_sync_odex.field_cm_inter_entity_update_wizard_server_id +msgid "Update Server" +msgstr "خادم التحديث" + +#. module: cm_entity_sync_odex +#: code:addons/cm_entity_sync_odex/models/entity.py:280 +#, python-format +msgid "You cannot change syncronized entity data !" +msgstr "لا يمكنك تعديل بيانات المؤسسات المتزامنة !" + +#. module: cm_entity_sync_odex +#: model:ir.model,name:cm_entity_sync_odex.model_cm_inter_entity_update_wizard +msgid "cm.inter.entity.update.wizard" +msgstr "cm.inter.entity.update.wizard" + +#. module: cm_entity_sync_odex +#: model:ir.model,name:cm_entity_sync_odex.model_cm_inter_entity_wizard +msgid "cm.inter.entity.wizard" +msgstr "cm.inter.entity.wizard" + +#. module: cm_entity_sync_odex +#: model:ir.model,name:cm_entity_sync_odex.model_cm_inter_entity +msgid "cm.inter_entity" +msgstr "cm.inter_entity" + +#. module: cm_entity_sync_odex +#: model:ir.model,name:cm_entity_sync_odex.model_incoming_transaction +msgid "incoming Transaction" +msgstr "معاملات الوارد الخارجي" + +#. module: cm_entity_sync_odex +#: model:ir.ui.view,arch_db:cm_entity_sync_odex.view_cm_inter_entity_update_wizard +#: model:ir.ui.view,arch_db:cm_entity_sync_odex.view_cm_inter_entity_wizard +msgid "or" +msgstr "أو" + +#. module: cm_entity_sync_odex +#: model:ir.model,name:cm_entity_sync_odex.model_outgoing_transaction +msgid "outgoing Transaction" +msgstr "معاملات الصادر الخارجي" + +#. module: cm_entity_sync_odex +#: code:addons/cm_entity_sync_odex/controllers/sync.py:291 +#, python-format +msgid "{} ← {}.{}" +msgstr "{} ← {}.{}" + diff --git a/odex25_transactions/cm_entity_sync_odex/models/__init__.py b/odex25_transactions/cm_entity_sync_odex/models/__init__.py new file mode 100644 index 000000000..da014f8d0 --- /dev/null +++ b/odex25_transactions/cm_entity_sync_odex/models/__init__.py @@ -0,0 +1,4 @@ +#-*- coding: utf-8 -*- +from . import entity +from . import settings +from . import outgoing diff --git a/odex25_transactions/cm_entity_sync_odex/models/entity.py b/odex25_transactions/cm_entity_sync_odex/models/entity.py new file mode 100644 index 000000000..44d966d86 --- /dev/null +++ b/odex25_transactions/cm_entity_sync_odex/models/entity.py @@ -0,0 +1,448 @@ +#-*- coding: utf-8 -*- +import logging +import uuid +import requests +# from odoo import _, api, exceptions, fields, models +from odoo import models, api, fields,_ +from odoo.exceptions import Warning,AccessError + + + +_logger = logging.getLogger(__name__) + + +class EntityMatrix(models.Model): + _name = 'cm.inter_entity' + + code = fields.Char(string='Code') + name = fields.Char(string='Description') + url = fields.Char(string='Server URL') + uuid = fields.Char(string='Secret Key') + + @api.model + def generate_key(self): + key = uuid.uuid4() + return str(key) + + @api.model + def broadcast(self, key=None, url=None, new_key=None): + if url.endswith('/'): + url = u'{}{}'.format(url[:-1], '/cm/sync/broadcast') + else: + url = u'{}{}'.format(url, '/cm/sync/broadcast') + code = new_key.split('-')[0] + company_name = self.env.user.company_id.name + new_url = self.env['ir.config_parameter'].sudo( + ).get_param('web.base.url') + new_url = new_url.replace('http://', 'http://') + data = { + 'code': code, + 'name': company_name, + 'url': new_url, + 'key': new_key, + 'auth': key, + } + try: + json = { + 'jsonrpc': '2.0', + 'method': 'call', + 'id': None, + 'params': data, + } + result = requests.post(url, json=json) + r = result.json() + if 'success' not in r.get('result', {}): + _logger.error(r) + return False + entities = r.get('result', {}).get('entities', []) + handle = [] + cm_entity = self.env['cm.entity'].sudo() + for e in entities: + ie = self.sudo().create(e) + if len(e.get('entities', [])): + for ce in e.get('entities', []): + O = ce.copy() + O['inter_entity_id'] = ie.id + cm_entity.create(O) + T = { + 'name': ie.name, + 'inter_entity_code': e['uuid'].split('-')[0], + 'type': 'external', + 'is_inter_entity': True, + 'is_master_entity': True, + 'inter_entity_id': ie.id, + } + cm_entity.with_context(broadcasted=True).create(T) + handle.append((4, ie.id)) + if handle: + sync = self.env['cm.inter_entity.sync'].sudo() + setting = sync.search([], limit=1) + setting.write({ + 'entities': handle, + }) + + except Exception as e: + _logger.error(e) + return False + return True + + @api.model + def add_new(self, arch): + sync = self.env['cm.inter_entity.sync'].sudo() + setting = sync.search([], limit=1) + entities = self.sudo().get_entities() + entity = self.sudo().create(arch) + T = { + 'name': arch['name'], + 'inter_entity_code': arch['uuid'].split('-')[0], + 'type': 'external', + 'is_inter_entity': True, + 'is_master_entity': True, + 'inter_entity_id': entity.id, + } + self.env['cm.entity'].sudo().with_context(broadcasted=True).create(T) + setting.write({ + 'entities': [(4, entity.id)], + }) + return entities + + @api.model + def wrap_jsonrpc(self, data): + return { + 'jsonrpc': '2.0', + 'method': 'call', + 'id': None, + 'params': data, + } + + @api.model + def post(self, url, data): + result = requests.post(url, json=data) + + return result + + @api.model + def is_success(self, result): + r = result.json() or {} + return 'success' in r.get('result', {}) + + @api.model + def get_settings(self): + sync = self.env['cm.inter_entity.sync'].sudo() + setting = sync.search([], limit=1) + return setting + + @api.model + def sync_new_key(self, key): + sync = self.env['cm.inter_entity.sync'].sudo() + setting = sync.search([], limit=1) + SUBURL = u'/cm/sync/new_key' + + for e in setting.entities.filtered(lambda k: k.uuid != setting.sync_key): + data = self.wrap_jsonrpc({ + 'key': key, + 'old': setting.sync_key, + 'auth': e.uuid, + }) + url = u'{}{}'.format(e.url, SUBURL) + result = self.post(url, data) + if not self.is_success(result): + raise Warning(_('Sync Error'u'Cannot Syncronize new key to Server {}, URL "{}"').format(e.name, e.url)) + return True + + @api.model + def update_from(self, server): + setting = self.sudo().get_settings() + SUBURL = u'/cm/sync/update_from' + + data = self.wrap_jsonrpc({ + 'auth': server.uuid, + 'key': setting.sync_key, + }) + url = u'{}{}'.format(server.url, SUBURL) + result = self.post(url, data) + if not self.is_success(result): + raise Warning(_('Sync Error Cannot Syncronize new key to Server {}, URL "{}"').format(server.name, server.url)) + try: + r = result.json() + entities = r.get('result', {}).get('entities', []) + handle = [] + cm_entity = self.env['cm.entity'].sudo() + for e in entities: + exists = setting.entities.filtered(lambda k: k.uuid == e['uuid']) + if len(exists): + exists.write(e) + continue + ie = self.sudo().create(e) + if len(e.get('entities', [])): + for ce in e.get('entities', []): + O = ce.copy() + O['inter_entity_id'] = ie.id + cm_entity.create(O) + try: + T = { + 'name': ie.name, + 'inter_entity_code': e['uuid'].split('-')[0], + 'type': 'external', + 'is_inter_entity': True, + 'is_master_entity': True, + 'inter_entity_id': ie.id, + } + cm_entity.with_context(broadcasted=True).create(T) + except Exception as e: + _logger.error(e) + handle.append((4, ie.id)) + if handle: + sync = self.env['cm.inter_entity.sync'].sudo() + setting = sync.search([], limit=1) + setting.write({ + 'entities': handle, + }) + except Exception as ee: + _logger.error(ee) + return False + return True + + @api.model + def send_transaction(self, trasaction, instance, to_send): + setting = self.sudo().get_settings() + SUBURL = u'/cm/sync/send_transaction' + for e in to_send: + # trasaction['to_ids'] = e.inter_entity_code + from_id = False + K = instance.employee_id + K = K.parent_id + if K.is_inter_entity: + from_id = K + # while True: + # if not len(K.parent_id): + # break + # K = K.parent_id + # if K.is_inter_entity: + # _logger.warning( + # '----ccxxxxxxxxxxxxxxxxxxxxcccccccccccccccccccccccccccccccccccccccccccccccccccccc---------sendtransaction %s', + # K.is_inter_entity) + # from_id = K + # break + if from_id: + trasaction['from_id'] = from_id.inter_entity_code + else: + trasaction['from_id'] = False + data = self.wrap_jsonrpc({ + 'data': trasaction, + 'key': setting.sync_key, + 'code': e.inter_entity_code, + 'auth': e.sudo().inter_entity_id.uuid, + }) + url = u'{}{}'.format(e.sudo().inter_entity_id.url, SUBURL) + result = self.post(url, data) + # 'http://localhost:8069/cm/sync/send_transaction' + if not self.is_success(result): + _logger.error(result.json()) + raise Warning(_('Sync Error Cannot send Transaction to server {}').format(e.name)) + + @api.model + def sync(self, entities): + raise NotImplementedError('Not NotImplemented !') + + @api.model + def activate(self, arch): + raise NotImplementedError('Not NotImplemented !') + + @api.model + def push_new(self, vals): + """here we have bug""" + setting = self.sudo().get_settings() + SUBURL = u'/cm/sync/push_new' + for e in setting.entities.filtered(lambda k: + k.uuid != setting.sync_key): + data = self.wrap_jsonrpc({ + 'data': vals, + 'auth': e.uuid, + }) + url = u'{}{}'.format(e.url, SUBURL) + result = self.post(url, data) + if not self.is_success(result): + raise Warning(_('Sync Error Cannot Syncronize new key to Server {}, URL "{}"').format(e.name, e.url)) + return True + + @api.model + def clone(self, entity): + raise NotImplementedError('Not NotImplemented !') + + @api.model + def update(self, vals): + setting = self.sudo().get_settings() + if vals['key'] != setting.sync_key: + if not vals.get('broadcasted', False) and not vals.get('dont_appear_in_send', False): + e = AccessError(_('Access Error')) + e.args = ( + _('Access Error'), _('You cannot change syncronized entity data !')) + raise e + else: + return True + SUBURL = u'/cm/sync/update_entity' + for e in setting.entities.filtered(lambda k: + k.uuid != setting.sync_key): + data = self.wrap_jsonrpc({ + 'data': vals, + 'auth': e.uuid, + }) + url = u'{}{}'.format(e.url, SUBURL) + result = self.post(url, data) + if not self.is_success(result): + raise Warning(_('Sync Error Cannot Syncronize new key to Server {}, URL "{}"').format(e.name, e.url)) + return True + + @api.model + def remove(self, vals): + raise NotImplementedError('Not NotImplemented !') + + @api.model + def get_cm_entities(self, e): + entity = self.env['cm.entity'].sudo() + entities = entity.search( + [('is_inter_entity', '=', True), ('inter_entity_id', '=', e.id)]) + result = [] + for ce in entities: + result.append({ + 'inter_entity_code': ce.inter_entity_code, + 'name': ce.name, + 'code': ce.code, + 'type': 'external', + 'is_inter_entity': True, + }) + return result + + @api.model + def get_entities(self): + sync = self.env['cm.inter_entity.sync'].sudo() + setting = sync.search([], limit=1) + data = [] + for e in setting.entities: + if e.id == setting.server_id.id: + cm_entities = self.sudo().get_cm_entities(e) + data.append({ + 'name': e.name, + 'code': e.code, + 'uuid': e.uuid, + 'url': e.url, + 'entities': cm_entities, + }) + return data + + @api.model + def authenticate(self, key): + # add by Fatima 7/5/2020 for clean older code + """to check key of entity before sync using in controller method receive key and return true if right key""" + sync = self.env['cm.inter_entity.sync'].sudo() + setting = sync.search([], limit=1) + try: + if setting.sync_key == key.strip(): + return True + except Exception as e: + return False + return False + + +class Entity(models.Model): + _inherit = 'cm.entity' + + inter_entity_id = fields.Many2one('cm.inter_entity', string='Inter-Entities Ref') + inter_entity_code = fields.Char( + string='Inter-Entities Code') + is_inter_entity = fields.Boolean(string='Is Inter-Entity ?', help=''' + If checked, this entity will be syncronized by other entities in the group. + ''') + is_master_entity = fields.Boolean(string='Is Master-Entity ?', help=''' + If checked, this entity will be syncronized by other entities in the group. + ''') + + @api.model + def name_search(self, name='', args=None, operator='ilike', limit=100): + args = args or [] + if not (name == '' and operator == 'ilike'): + search = self.env['cm.inter_entity'].sudo().search([('name', 'ilike', name)]) + if len(search): + args += ['|', ('inter_entity_id', 'in', search.ids)] + return super(Entity, self).name_search(name=name, args=args, operator=operator, limit=limit) + + def name_get(self): + result = [] + for r in self: + if r.is_inter_entity: + if r.type == 'external': + result.append((r.id, u'{} \u21E6 {}'.format( + r.inter_entity_id.name or u'**', r.name))) + continue + result.append((r.id, r.name)) + return result + + @api.model + def create(self, vals): + setting = self.env['cm.inter_entity'].sudo().get_settings() + if vals.get('type', False) == 'unit' and vals.get('is_inter_entity', False): + if not vals.get('inter_entity_code', False): + vals['inter_entity_id'] = setting.server_id.id + vals['inter_entity_code'] = u'{}-{}'.format(setting.sync_key.split('-')[0] if setting.sync_key else False, + self.env['ir.sequence'].sudo().next_by_code('cm.inter.entity')) + obj = super(Entity, self).create(vals) + IE = self.env['cm.inter_entity'].sudo() + if vals.get('type', False) == 'unit' and vals.get('is_inter_entity', False): + if not self.env.context.get('broadcasted', False): + IE.push_new({ + 'data': vals, + 'key': setting.sync_key, + }) + return obj + + # def unlink(self, cr, uid, ids, context=None): + # return super(Entity, self).unlink(cr, uid, ids, context=context) + + def write(self, vals): + data = {} + values = vals.copy() + is_inter_entity = False + setting = self.env['cm.inter_entity'].sudo().get_settings() + if vals.get('is_inter_entity', False): + values['inter_entity_id'] = setting.server_id.id + values['inter_entity_code'] = u'{}-{}'.format(setting.sync_key.split( + '-')[0], self.env['ir.sequence'].sudo().next_by_code('cm.inter.entity')) + vals['inter_entity_id'] = values['inter_entity_id'] + vals['inter_entity_code'] = values['inter_entity_code'] + is_inter_entity = True + for r in self: + if r.is_inter_entity: + data = { + 'details': {'code': r.inter_entity_code, 'data': vals}, + 'key': r.inter_entity_id.uuid, + 'broadcasted': vals.get('broadcasted', False) + } + if not is_inter_entity: + data['details']['remove'] = True + elif is_inter_entity: + vals1 = r.read([]) + vals1 = vals1[0] + lister = [ + 'name', 'inter_entity_code', + 'is_inter_entity', + ] + vals2, vals3 = {}, {} + for l in lister: + if l in vals1: + vals2[l] = vals1[l] + if l in vals: + vals3[l] = vals[l] + vals2.update(vals3) + if vals2: + code = vals2.get('inter_entity_code', r.inter_entity_code) + data = { + 'details': {'code': code, 'data': vals2, 'is_new': True}, + 'key': setting.sync_key, + 'broadcasted': vals.get('broadcasted', False) + } + u = super(Entity, self).write(values) + if data: + IE = self.env['cm.inter_entity'].sudo() + IE.update(data) + return u diff --git a/odex25_transactions/cm_entity_sync_odex/models/outgoing.py b/odex25_transactions/cm_entity_sync_odex/models/outgoing.py new file mode 100644 index 000000000..2b77fc85e --- /dev/null +++ b/odex25_transactions/cm_entity_sync_odex/models/outgoing.py @@ -0,0 +1,60 @@ +#-*- coding: utf-8 -*- + +import logging +import base64 +from odoo import api, models, fields, _, exceptions + + +_logger = logging.getLogger(__name__) + + +class Transaction(models.Model): + _inherit = 'outgoing.transaction' + + syncronized = fields.Boolean(string='Syncronized ?') + + + def action_draft(self): + super(Transaction, self).action_draft() + to_send = [] + inter_entity = self.env['cm.inter_entity'].sudo() + for r in self: + r.write({ + 'syncronized': True, + }) + for e in r.to_ids: + if e.is_inter_entity: + to_send.append(e) + attachment_rule_data = [] + for attachment in r.attachment_rule_ids: + attachment_rule_data.append({ + 'id': attachment.id if attachment else '', + 'file_save': attachment.file_save.decode('utf-8') if attachment.file_save else '', + 'attachment_filename': u"".join(u'%s'%attachment.attachment_filename) if attachment.attachment_filename else '', + 'outgoing_id': False, + 'incoming_transaction_id': r.id if r else False, + 'internal_id': False, + 'date': attachment.date if attachment.date else '', + 'description': attachment.description if attachment.description else '', + }) + if len(to_send): + trasaction = { + # 'out_date': r.out_date, + 'to_ids': None, + 'type': 'new', + 'subject': r.subject, + 'incoming_number': r.name, + 'incoming_date': r.transaction_date, + 'syncronized': True, + 'body': r.body, + 'attachment_rule_ids': attachment_rule_data, + } + inter_entity.send_transaction(trasaction, r, to_send) + + +class Incoming(models.Model): + _inherit = 'incoming.transaction' + + syncronized = fields.Boolean(string='Syncronized ?') + inter_entity_id = fields.Many2one('cm.inter_entity', string='Inter Entity') + diff --git a/odex25_transactions/cm_entity_sync_odex/models/settings.py b/odex25_transactions/cm_entity_sync_odex/models/settings.py new file mode 100644 index 000000000..aa24733d5 --- /dev/null +++ b/odex25_transactions/cm_entity_sync_odex/models/settings.py @@ -0,0 +1,79 @@ +#-*- coding: utf-8 -*- +'''Doc''' +import logging +from odoo import api, models, fields, _ + + +_logger = logging.getLogger(__name__) + + +class Sync(models.Model): + '''Doc''' + _name = 'cm.inter_entity.sync' + _description = 'Entity Syncronization' + + activated = fields.Boolean(string='Activate Syncronization') + sync_key = fields.Char(string='Sync Key', related='server_id.uuid') + server_id = fields.Many2one('cm.inter_entity', string='Current Server', store=True) + entities = fields.Many2many( + 'cm.inter_entity', 'inter_entity_sync_rel', 'sync_id', 'inter_entity_id') + + important_id = fields.Many2one( + 'cm.transaction.important', string='Default Important Degree') + subject_type_id = fields.Many2one( + 'cm.subject.type', string='Default Transaction Type') + employee_id = fields.Many2one( + 'cm.entity', string='Default Created By') + + def generate_key(self): + '''Doc''' + inter_entity = self.env['cm.inter_entity'].sudo() + for rec in self: + # if not len(rec.entities.filtered(lambda k: k.uuid != rec.sync_key)): + # first time + return { + 'name': _('Generate new Key'), + 'view_type': 'form', + 'view_mode': 'form', + 'res_id': False, + 'res_model': 'cm.inter.entity.wizard', + 'target': 'new', + 'type': 'ir.actions.act_window', + 'context': { + 'default_document_id': rec.id, + 'default_broadcast': True, + }, + } + # k = inter_entity.generate_key() + # synced = inter_entity.sync_new_key(k) + # print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>synced",synced) + # if synced: + # rec.write({ + # 'sync_key': k, + # }) + + def update_from(self): + '''Doc''' + inter_entity = self.env['cm.inter_entity'].sudo() + for rec in self: + if len(rec.entities.filtered(lambda k: k.uuid != rec.sync_key)): + # first time + return { + 'name': _('Update From ...'), + 'view_type': 'form', + 'view_mode': 'form', + 'res_id': False, + 'res_model': 'cm.inter.entity.update.wizard', + 'target': 'new', + 'type': 'ir.actions.act_window', + 'context': { + 'default_document_id': rec.id, + 'default_broadcast': True, + }, + } + k = inter_entity.generate_key() + synced = inter_entity.sync_new_key(k) + if synced: + rec.write({ + 'sync_key': k, + }) diff --git a/odex25_transactions/cm_entity_sync_odex/security/ir.model.access.csv b/odex25_transactions/cm_entity_sync_odex/security/ir.model.access.csv new file mode 100644 index 000000000..1283e91b3 --- /dev/null +++ b/odex25_transactions/cm_entity_sync_odex/security/ir.model.access.csv @@ -0,0 +1,6 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_inter_objects_manager,access_outgoing_inter_objects_manager,model_cm_inter_entity,exp_transaction_documents.group_cm_employee_group,1,1,1,1 +access_inter_objects_reviewer,access_outgoing_inter_objects_reviewer_manager,model_cm_inter_entity,exp_transaction_documents.group_cm_user,1,1,1,1 +access_inter_objects_unit_manager,access_outgoing_inter_objects_unit_manager,model_cm_inter_entity,exp_transaction_documents.group_cm_reviewer,1,1,1,1 +access_inter_objects_dep,access_outgoing_inter_objects_dep,model_cm_inter_entity,exp_transaction_documents.group_cm_department_manager,1,1,1,1 +access_outgoing_inter_objects_exe,access_outgoing_inter_objects_exe,model_cm_inter_entity,exp_transaction_documents.group_cm_executive_manager,1,1,1,1 diff --git a/odex25_transactions/cm_entity_sync_odex/static/description/icon.png b/odex25_transactions/cm_entity_sync_odex/static/description/icon.png new file mode 100644 index 000000000..4141f52da Binary files /dev/null and b/odex25_transactions/cm_entity_sync_odex/static/description/icon.png differ diff --git a/odex25_transactions/cm_entity_sync_odex/views/actions_and_menus.xml b/odex25_transactions/cm_entity_sync_odex/views/actions_and_menus.xml new file mode 100644 index 000000000..200d2dcec --- /dev/null +++ b/odex25_transactions/cm_entity_sync_odex/views/actions_and_menus.xml @@ -0,0 +1,15 @@ + + + + Inter Entity Sync + cm.inter_entity.sync + form + + + + + + + + diff --git a/odex25_transactions/cm_entity_sync_odex/views/entity_view.xml b/odex25_transactions/cm_entity_sync_odex/views/entity_view.xml new file mode 100644 index 000000000..ea700e527 --- /dev/null +++ b/odex25_transactions/cm_entity_sync_odex/views/entity_view.xml @@ -0,0 +1,60 @@ + + + + + cm.inter_entity.tree + cm.inter_entity + + + + + + + + + + + + cm.inter_entity.form + cm.inter_entity + +
+ + + + + + + + + + +
+
+
+ + + cm.entity.form + cm.entity + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/odex25_transactions/cm_entity_sync_odex/views/settings_view.xml b/odex25_transactions/cm_entity_sync_odex/views/settings_view.xml new file mode 100644 index 000000000..8172eda88 --- /dev/null +++ b/odex25_transactions/cm_entity_sync_odex/views/settings_view.xml @@ -0,0 +1,36 @@ + + + + CM Settings Ext + cm.inter_entity.sync + +
+ + + + + +