From a8d6b00676969f4b07af959872f0f953f6a35ed1 Mon Sep 17 00:00:00 2001 From: esam Date: Wed, 17 Sep 2025 05:07:19 -0400 Subject: [PATCH] fix --- .../system_notification/__manifest__.py | 19 +- .../system_notification/data/mail_data.xml | 5 +- .../models/group_state_notification.py | 19 +- .../system_notification/models/models.py | 248 +++++++++++------- .../system_notification/views/activity.xml | 1 - .../views/group_state_notification.xml | 130 ++++----- .../system_notification/views/views.xml | 129 ++++----- 7 files changed, 292 insertions(+), 259 deletions(-) delete mode 100644 odex30_base/system_notification/views/activity.xml diff --git a/odex30_base/system_notification/__manifest__.py b/odex30_base/system_notification/__manifest__.py index 55bdc6e..b3b7f45 100644 --- a/odex30_base/system_notification/__manifest__.py +++ b/odex30_base/system_notification/__manifest__.py @@ -1,19 +1,26 @@ # -*- coding: utf-8 -*- { 'name': "System Notification", - 'version': '18.0.1.0.0', + 'summary': """""", + 'description': """ """, - 'category': 'Odex30-base', # تم تغيير الفئة - 'depends': ['base_automation', 'mail'], + 'category' : 'Odex30-base', + + # Categories can be used to filter modules in modules listing + # Check https://github.com/odoo/odoo/blob/11.0/odoo/addons/base/module/module_data.xml + # for the full list + + # any module necessary for this one to work correctly + 'depends': ['base_automation','mail'], + + # always loaded 'data': [ 'security/ir.model.access.csv', 'views/views.xml', 'views/group_state_notification.xml', 'data/mail_data.xml', ], - 'installable': True, - 'application': False, - 'auto_install': False, + } diff --git a/odex30_base/system_notification/data/mail_data.xml b/odex30_base/system_notification/data/mail_data.xml index b87fcef..d920400 100644 --- a/odex30_base/system_notification/data/mail_data.xml +++ b/odex30_base/system_notification/data/mail_data.xml @@ -9,7 +9,6 @@ -
- -

- + \ No newline at end of file diff --git a/odex30_base/system_notification/models/group_state_notification.py b/odex30_base/system_notification/models/group_state_notification.py index 8c1c135..edf62af 100644 --- a/odex30_base/system_notification/models/group_state_notification.py +++ b/odex30_base/system_notification/models/group_state_notification.py @@ -1,25 +1,16 @@ # -*- coding: utf-8 -*- -from odoo import models, fields, api +from odoo import models, fields class BaseGroupAutomation(models.Model): _name = 'automation.group' _rec_name = 'model_id' - _description = 'Automation Group' model_id = fields.Many2one('ir.model', string="Model", ondelete='cascade', required=True) - atuomation_ids = fields.Many2many( - comodel_name='base.automation', - relation='automation_state_groups_rel', - string='Group States' - ) - + atuomation_ids = fields.Many2many(comodel_name='base.automation', relation='automation_state_groups_rel', + string='Group States ') def unlink(self): - """ - Delete all record(s) from recordset - return True on success, False otherwise - """ - for record in self.atuomation_ids: - record.unlink() + for recored in self.atuomation_ids: + recored.unlink() result = super(BaseGroupAutomation, self).unlink() return result diff --git a/odex30_base/system_notification/models/models.py b/odex30_base/system_notification/models/models.py index 951192b..89c25d7 100644 --- a/odex30_base/system_notification/models/models.py +++ b/odex30_base/system_notification/models/models.py @@ -2,154 +2,170 @@ from odoo import models, fields, api, _ from datetime import datetime - - class BaseAutomation(models.Model): _inherit = 'base.automation' - - # إضافة خيار الإشعار send_notify = fields.Boolean(string='Send Notify', help="Send Notifications Within The System") notify_title = fields.Char(string='Notification Title', related='model_id.name') notify_note = fields.Char(string='Notification Note') notify_summary = fields.Char(string='Notification Message') - notify_to_groups_ids = fields.Many2many( comodel_name='res.groups', relation='automation_notifications_to_groups_rel', string='TO Notify Groups' ) - notify_cc_groups_ids = fields.Many2many( comodel_name='res.groups', relation='automation_notifications_cc_groups_rel', string='CC Notify Groups' ) - - hr_notifys = fields.Boolean( - string='HR Notifys', - help="Send Notifications HR Modules Depend on (Employee Id) only" - ) - direct_manager_notify = fields.Boolean(string='Direct Manager Notify', help="Notify direct manager") - department_manager_notify = fields.Boolean(string='Department Manager Notify', help="Notify department manager") - employee_notify = fields.Boolean(string='Employee Notify', help="Notify employee") - ceo_notify = fields.Boolean(string='CEO Manager', help="Notify CEO") - hr_manager_notify = fields.Boolean(string='HR Manager', help="Notify HR manager") - hr_email_notify = fields.Boolean(string='HR E-Mail', help="Notify HR email") - services_manager_id = fields.Boolean(string='Services Manager', help="Notify services manager") - it_manager_id = fields.Boolean(string='IT Manager', help="Notify IT manager") - admin_manager_id = fields.Boolean(string='Admin Affairs Manager', help="Notify admin manager") - financial_manager_id = fields.Boolean(string='Financial Manager', help="Notify financial manager") - cyber_security_id = fields.Boolean(string='Cyber Security', help="Notify cyber security") - - def check_record_access(self, user_id, record, mode='read'): + hr_notifys = fields.Boolean(string='HR Notifys', help="Send Notifications HR Modules Depend on (Employee Id) only") + direct_manager_notify = fields.Boolean(string='Direct Manager Notify', + help="Send Notification To The Employee's Direct Manager Only") + department_manager_notify = fields.Boolean(string='Department Manager Notify', + help="Send Notification To The Department Manager For The Employee Only") + employee_notify = fields.Boolean(string='Employee Notify', + help="Send Notification To The Employee Only") + ceo_notify = fields.Boolean(string='CEO Manager', + help="Send Notification To The CEO Manager Only") + hr_manager_notify = fields.Boolean(string='HR Manager', + help="Send Notification To The HR Manager Only") + hr_email_notify = fields.Boolean(string='HR E-Mail', + help="Send Notification To The HR E-Mail Only") + services_manager_id = fields.Boolean(string='Services Manager', + help="Send Notification To The Services Manager Only") + it_manager_id = fields.Boolean(string='IT Manager', + help="Send Notification To The IT Manager Only") + admin_manager_id = fields.Boolean(string='Admin Affairs Manager', + help="Send Notification To The Admin Affairs Manager Only") + financial_manager_id = fields.Boolean(string='Financial Manager', + help="Send Notification To The Financial Manager Only") + cyber_security_id = fields.Boolean(string='Cyber Security', + help="Send Notification To The Cyber Security Only") + def check_user_access(self, user_id, record, mode='read'): try: - record.with_user(user_id).check_access_rule(mode) - return True - except: + return record.with_user(user_id).has_access(mode) + except Exception: return False - def access_users(self, groups, record): users = [] for group in groups: for user in group.users: - if user.partner_id.email not in users and \ - self.check_record_access(user_id=user.id, record=record, mode='read') and \ - user.partner_id.email: + if user.partner_id.email not in users and self.check_user_access(user_id=user.id, record=record, + mode='read') and user.partner_id.email: if self.hr_notifys: if hasattr(record, 'employee_id') and record.employee_id: - emp = record.employee_id.sudo() - if self.direct_manager_notify and user.id == emp.parent_id.user_id.id: - users.append(user.partner_id.email) - elif self.department_manager_notify and user.id == emp.coach_id.user_id.id: - users.append(user.partner_id.email) - elif self.employee_notify and user.id == emp.user_id.id: - users.append(user.partner_id.email) - elif self.ceo_notify and user.id == emp.company_id.general_supervisor_id.user_id.id: - users.append(user.partner_id.email) - elif self.hr_manager_notify and user.id == emp.company_id.hr_manager_id.user_id.id: - users.append(user.partner_id.email) - elif self.services_manager_id and user.id == emp.company_id.services_manager_id.user_id.id: - users.append(user.partner_id.email) - elif self.it_manager_id and user.id == emp.company_id.it_manager_id.user_id.id: - users.append(user.partner_id.email) - elif self.admin_manager_id and user.id == emp.company_id.admin_manager_id.user_id.id: - users.append(user.partner_id.email) - elif self.financial_manager_id and user.id == emp.company_id.financial_manager_id.user_id.id: - users.append(user.partner_id.email) - elif self.cyber_security_id and user.id == emp.company_id.cyber_security_id.user_id.id: - users.append(user.partner_id.email) - elif self.hr_email_notify and emp.company_id.hr_email and emp.company_id.hr_email not in users: - users.append(emp.company_id.hr_email) + hr_mail = record.employee_id.sudo().company_id.hr_email + if self.direct_manager_notify: + if user.id == record.employee_id.sudo().parent_id.user_id.id: + users.append(user.partner_id.email) + if self.department_manager_notify: + if user.id == record.employee_id.sudo().coach_id.user_id.id: + users.append(user.partner_id.email) + if self.employee_notify: + if user.id == record.employee_id.sudo().user_id.id: + users.append(user.partner_id.email) + if self.ceo_notify: + if user.id == record.employee_id.sudo().company_id.general_supervisor_id.user_id.id: + users.append(user.partner_id.email) + if self.hr_manager_notify: + if user.id == record.employee_id.sudo().company_id.hr_manager_id.user_id.id: + users.append(user.partner_id.email) + if self.services_manager_id: + if user.id == record.employee_id.sudo().company_id.services_manager_id.user_id.id: + users.append(user.partner_id.email) + if self.it_manager_id: + if user.id == record.employee_id.sudo().company_id.it_manager_id.user_id.id: + users.append(user.partner_id.email) + if self.admin_manager_id: + if user.id == record.employee_id.sudo().company_id.admin_manager_id.user_id.id: + users.append(user.partner_id.email) + if self.financial_manager_id: + if user.id == record.employee_id.sudo().company_id.financial_manager_id.user_id.id: + users.append(user.partner_id.email) + if self.cyber_security_id: + if user.id == record.employee_id.sudo().company_id.cyber_security_id.user_id.id: + users.append(user.partner_id.email) + if self.hr_email_notify and hr_mail not in users: + users.append(hr_mail) else: users.append(user.partner_id.email) else: users.append(user.partner_id.email) return ",".join(users) - def access_users_ids(self, groups, record): processed_users = set() for group in groups: for user in group.users: - if user.id not in processed_users and \ - self.check_record_access(user_id=user.id, record=record, mode='read'): + if user.id not in processed_users and self.check_user_access(user_id=user.id, record=record,mode='read'): if self.hr_notifys: if hasattr(record, 'employee_id') and record.employee_id: - emp = record.employee_id.sudo() - if self.direct_manager_notify and user.id == emp.parent_id.user_id.id: - processed_users.add(user.id) - elif self.department_manager_notify and user.id == emp.coach_id.user_id.id: - processed_users.add(user.id) - elif self.employee_notify and user.id == emp.user_id.id: - processed_users.add(user.id) - elif self.ceo_notify and user.id == emp.company_id.general_supervisor_id.user_id.id: - processed_users.add(user.id) - elif self.hr_manager_notify and user.id == emp.company_id.hr_manager_id.user_id.id: - processed_users.add(user.id) - elif self.services_manager_id and user.id == emp.company_id.services_manager_id.user_id.id: - processed_users.add(user.id) - elif self.it_manager_id and user.id == emp.company_id.it_manager_id.user_id.id: - processed_users.add(user.id) - elif self.admin_manager_id and user.id == emp.company_id.admin_manager_id.user_id.id: - processed_users.add(user.id) - elif self.financial_manager_id and user.id == emp.company_id.financial_manager_id.user_id.id: - processed_users.add(user.id) - elif self.cyber_security_id and user.id == emp.company_id.cyber_security_id.user_id.id: - processed_users.add(user.id) + if self.direct_manager_notify: + if user.id == record.employee_id.sudo().parent_id.user_id.id: + processed_users.add(user.id) + if self.department_manager_notify: + if user.id == record.employee_id.sudo().coach_id.user_id.id: + processed_users.add(user.id) + if self.employee_notify: + if user.id == record.employee_id.sudo().user_id.id: + processed_users.add(user.id) + if self.ceo_notify: + if user.id == record.employee_id.sudo().company_id.general_supervisor_id.user_id.id: + processed_users.add(user.id) + if self.hr_manager_notify: + if user.id == record.employee_id.sudo().company_id.hr_manager_id.user_id.id: + processed_users.add(user.id) + if self.services_manager_id: + if user.id == record.employee_id.sudo().company_id.services_manager_id.user_id.id: + processed_users.add(user.id) + if self.it_manager_id: + if user.id == record.employee_id.sudo().company_id.it_manager_id.user_id.id: + processed_users.add(user.id) + if self.admin_manager_id: + if user.id == record.employee_id.sudo().company_id.admin_manager_id.user_id.id: + processed_users.add(user.id) + if self.financial_manager_id: + if user.id == record.employee_id.sudo().company_id.financial_manager_id.user_id.id: + processed_users.add(user.id) + if self.cyber_security_id: + if user.id == record.employee_id.sudo().company_id.cyber_security_id.user_id.id: + processed_users.add(user.id) else: processed_users.add(user.id) else: processed_users.add(user.id) return list(processed_users) - def get_notify_message(self, record): user_ids = self.access_users_ids(self.notify_to_groups_ids, record) today = datetime.today() - for user in user_ids: + summary = (self.name or + (self.template_id.name if hasattr(self, 'template_id') and self.template_id else None) or + 'Notification') data = { 'res_id': record.id, 'res_model_id': self.env['ir.model'].search([('model', '=', record._name)]).id, 'user_id': user, - 'summary': _(self.name or 'Notification'), + 'summary': _(summary), 'activity_type_id': self.env.ref('mail.mail_activity_data_todo').id, 'date_deadline': today } self.env['mail.activity'].create(data) - if self.hr_notifys: if not user_ids and self.notify_to_groups_ids: if hasattr(record, 'employee_id') and record.employee_id: hr_manager_user = record.employee_id.sudo().company_id.hr_manager_id.user_id.id + summary = (self.name or + (self.template_id.name if hasattr(self, 'template_id') and self.template_id else None) or + 'Notification') data = { 'res_id': record.id, 'res_model_id': self.env['ir.model'].search([('model', '=', record._name)]).id, 'user_id': hr_manager_user, - 'summary': _(self.name or 'Notification'), + 'summary': _(summary), 'activity_type_id': self.env.ref('mail.mail_activity_data_todo').id, 'date_deadline': today } self.env['mail.activity'].create(data) - def get_mail_to(self, record): users = self.access_users(self.notify_to_groups_ids, record) if self.hr_notifys: @@ -158,7 +174,6 @@ class BaseAutomation(models.Model): hr_manager_mail = record.employee_id.sudo().company_id.hr_manager_id.user_id.partner_id.email users = hr_manager_mail return users - def get_mail_cc(self, record): users = self.access_users(self.notify_cc_groups_ids, record) if self.hr_notifys: @@ -167,59 +182,88 @@ class BaseAutomation(models.Model): hr_mail = record.employee_id.sudo().company_id.hr_email users = hr_mail return users - def _process(self, records, domain_post=None): result = super()._process(records, domain_post) if self.send_notify: for record in records: self.get_notify_message(record) return result - - +class ServerActions(models.Model): + _inherit = 'ir.actions.server' + @api.model + def _run_action_email(self, eval_context=None): + if self._context.get('__action_done'): + automations = self._context.get('__action_done') + automation = list(automations.keys())[0] + record = automations[automation] + action = automation.action_server_id + old_email_to = action.template_id.email_to if action.template_id else '' + old_email_cc = action.template_id.email_cc if action.template_id else '' + if action.template_id: + template_values = { + 'email_to': automation.get_mail_to(record), + 'email_cc': automation.get_mail_cc(record), + } + action.template_id.write(template_values) + cleaned_ctx = dict(self.env.context) + cleaned_ctx.pop('default_type', None) + cleaned_ctx.pop('default_parent_id', None) + action.template_id.with_context(cleaned_ctx).send_mail(record.id, force_send=True, + notif_layout="system_notification.mail_notification_odex", + raise_exception=False) + old_template_values = { + 'email_to': old_email_to, + 'email_cc': old_email_cc, + } + action.template_id.write(old_template_values) + if automation.send_notify: + automation.get_notify_message(record) + return False + return super()._run_action_email(eval_context=eval_context) class MailActivity(models.Model): _inherit = 'mail.activity' - def action_notify(self): if not self: return - original_context = self.env.context body_template = self.env.ref('mail.message_activity_assigned') - for activity in self: if activity.user_id.lang: self = self.with_context(lang=activity.user_id.lang) body_template = body_template.with_context(lang=activity.user_id.lang) activity = activity.with_context(lang=activity.user_id.lang) - model_description = self.env['ir.model']._get(activity.res_model).display_name - body = body_template._render( { 'activity': activity, 'model_description': model_description, - 'access_link': self.env['mail.thread']._notify_get_action_link( - 'view', - model=activity.res_model, - res_id=activity.res_id - ), + 'access_link': self.env['mail.thread']._notify_get_action_link('view', model=activity.res_model, + res_id=activity.res_id), }, engine='ir.qweb', minimal_qcontext=True ) - record = self.env[activity.res_model].browse(activity.res_id) if activity.user_id: record.message_post( body=body, subject=_('%(activity_name)s: %(summary)s assigned to you', activity_name=activity.res_name, - summary=activity.summary or activity.activity_type_id.name - ), + summary=activity.summary or activity.activity_type_id.name), partner_ids=activity.user_id.partner_id.ids, email_layout_xmlid='system_notification.mail_notification_odex', message_type='notification' ) - body_template = body_template.with_context(original_context) self = self.with_context(original_context) +class BaseGroupAutomation(models.Model): + _name = 'automation.group' + _rec_name = 'model_id' + model_id = fields.Many2one('ir.model', string="Model", ondelete='cascade', required=True) + atuomation_ids = fields.Many2many(comodel_name='base.automation', relation='automation_state_groups_rel', + string='Group States ') + def unlink(self): + for record in self.atuomation_ids: + record.unlink() + result = super().unlink() + return result diff --git a/odex30_base/system_notification/views/activity.xml b/odex30_base/system_notification/views/activity.xml deleted file mode 100644 index 8b13789..0000000 --- a/odex30_base/system_notification/views/activity.xml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/odex30_base/system_notification/views/group_state_notification.xml b/odex30_base/system_notification/views/group_state_notification.xml index cda90c7..7022287 100644 --- a/odex30_base/system_notification/views/group_state_notification.xml +++ b/odex30_base/system_notification/views/group_state_notification.xml @@ -1,63 +1,75 @@ + - - - - base.automation.inherit.view.form - base.automation - - - - - - - + + + Automations + automation.group + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
- - - - - - - - - - - - - - - + + + base.automation.list + automation.group + + + + + + - - - - - - - - - - - - - - - - - - - - - - -
-
+ + + Automated Actions + automation.group + list,form + + +

+ Click to setup a new automated automation. +

+

+ Use automated actions to automatically trigger actions for + various screens. Example: a lead created by a specific user may + be automatically set to a specific sales channel, or an + opportunity which still has status pending after 14 days might + trigger an automatic reminder email. +

+
+
- - - - System Notifications - - -
-
+ + \ No newline at end of file diff --git a/odex30_base/system_notification/views/views.xml b/odex30_base/system_notification/views/views.xml index bc2ebec..6b5d13e 100644 --- a/odex30_base/system_notification/views/views.xml +++ b/odex30_base/system_notification/views/views.xml @@ -1,77 +1,60 @@ - - - - Automations - automation.group - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
-
+ + + base.automation.inherit.view.form + base.automation + + - - - base.automation.list - automation.group - - - - - - + + + + + + + + + + + + + + + + + + - - - Automated Actions - automation.group - list,form - - -

- Click to setup a new automated automation. -

-

- Use automated actions to automatically trigger actions for - various screens. Example: a lead created by a specific user may - be automatically set to a specific sales channel, or an - opportunity which still has status pending after 14 days might - trigger an automatic reminder email. -

-
-
+ + + + + + + + + + + + + + + + + + + + + +
+
+
- -
+ + + + System Notifications + + + + \ No newline at end of file