diff --git a/sos_brm/__init__.py b/sos_brm/__init__.py new file mode 100755 index 0000000..072df18 --- /dev/null +++ b/sos_brm/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- + +from . import controllers +from . import models +from . import wizard +from . import report diff --git a/sos_brm/__manifest__.py b/sos_brm/__manifest__.py new file mode 100755 index 0000000..65aafe5 --- /dev/null +++ b/sos_brm/__manifest__.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +{ + 'name': "SOS BRM", + + 'summary': "Business Review", + + 'description': """ +Long description of module's purpose + """, + + 'author': "Deena", + 'website': "https://sosaley.com", + + 'category': 'Inventory', + 'version': '17.0.1.0.0', + 'depends': ['base','web','mail','sos_inventory','sos_sales','sos_qo_aod'], + + 'data': [ + 'security/ir.model.access.csv', + 'security/record_rules.xml', + 'views/menu.xml', + 'views/sos_brm_action_view.xml', + 'wizard/sos_brm_report_wizard_view.xml', + 'wizard/sos_cross_dept_report_wizard_view.xml', + 'report/sos_brm_report_result.xml', + 'report/sos_cross_dept_report_result.xml' + ], + 'demo': [ + 'demo/demo.xml', + ], + 'installable': True, + 'application': True, + 'license': 'LGPL-3' +} + diff --git a/sos_brm/controllers/__init__.py b/sos_brm/controllers/__init__.py new file mode 100755 index 0000000..b0f26a9 --- /dev/null +++ b/sos_brm/controllers/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import controllers diff --git a/sos_brm/controllers/controllers.py b/sos_brm/controllers/controllers.py new file mode 100755 index 0000000..5b383e9 --- /dev/null +++ b/sos_brm/controllers/controllers.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# from odoo import http + + +# class SosBrm(http.Controller): +# @http.route('/sos_brm/sos_brm', auth='public') +# def index(self, **kw): +# return "Hello, world" + +# @http.route('/sos_brm/sos_brm/objects', auth='public') +# def list(self, **kw): +# return http.request.render('sos_brm.listing', { +# 'root': '/sos_brm/sos_brm', +# 'objects': http.request.env['sos_brm.sos_brm'].search([]), +# }) + +# @http.route('/sos_brm/sos_brm/objects/', auth='public') +# def object(self, obj, **kw): +# return http.request.render('sos_brm.object', { +# 'object': obj +# }) + diff --git a/sos_brm/demo/demo.xml b/sos_brm/demo/demo.xml new file mode 100755 index 0000000..2cc796a --- /dev/null +++ b/sos_brm/demo/demo.xml @@ -0,0 +1,30 @@ + + + + + diff --git a/sos_brm/models/__init__.py b/sos_brm/models/__init__.py new file mode 100755 index 0000000..4f5891a --- /dev/null +++ b/sos_brm/models/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import sos_brm_action diff --git a/sos_brm/models/sos_brm_action.py b/sos_brm/models/sos_brm_action.py new file mode 100755 index 0000000..c92b3e5 --- /dev/null +++ b/sos_brm/models/sos_brm_action.py @@ -0,0 +1,225 @@ + +from odoo import models, fields, api + + +class sos_brm_action(models.Model): + _name = 'sos_brm_action' + _description = 'Business Review' + + todo_id = fields.Char(string="To-Do ID", readonly= True) + name = fields.Char(string="Action Point") + priority = fields.Selection([ + ('0', '🟢 Low'), + ('1', '🟡 Medium'), + ('2', '🔴 High'), + ('3', '🚨 Urgent') + ], string='Priority', default='0') + start_date = fields.Date(string="Start Date",default=fields.Date.today) + target_date = fields.Date(string="Target Date") + end_date = fields.Date(string="Actual end Date") + status = fields.Selection([ ('open', 'Open'),('close', 'Closed'),('hold', 'Hold')], default='open' , string="Status") + line_ids = fields.One2many('sos_brm_action_lines', 'ref_id', string="Action Details",copy=True) + target_date_line_ids = fields.One2many('sos_brm_action_revised_targets', 'ref_id', string="Revised Target Details",copy=True) + result = fields.Html(string="Remarks") + cross_dept_action = fields.Selection( + selection=[ + ('cross_dept', 'Cross-Dept'), + ('inter_dept', 'Intra-Dept') + ], + string='Type', + default='inter_dept', + required=True + ) + department = fields.Many2one('sos_departments', string='Self Department',required=True, default=lambda self: self._default_department()) + responsible_person = fields.Many2one( + 'res.users', + string='Assigned To',required=True, + domain="[('id', 'in', allowed_user_ids)]" +) + assigned_by = fields.Many2one( + 'res.users', + string='Assigned By', + default=lambda self: self.env.user +) + assigned_from_dept = fields.Many2one('sos_departments', string='Assigned By Dept', default=lambda self: self._default_department()) + assigned_to_dept = fields.Many2one('sos_departments', string='Assigned To Dept') + latest_target_date = fields.Date( + string="Latest Revised Target", + compute='_compute_latest_target', + store=True, compute_sudo=True, readonly=True, + ) + latest_target_line_id = fields.Many2one( + 'sos_brm_action_lines', + string="Latest Target Line", + compute='_compute_latest_target', + store=True, compute_sudo=True, readonly=True, + ) + is_sales_user_created = fields.Boolean( + compute='_compute_is_sales_user_created', + store=True, + string='Created by Sales User' + ) + allowed_user_ids = fields.Many2many('res.users', compute='_compute_allowed_users') + reporting_to = fields.Many2one('res.users',related="responsible_person.reporting_to", string='Reporting To') + + @api.model + def _default_department(self): + dept = self.env['sos_departments'].search( + [('users_line_ids.users', '=', self.env.user.id)], + limit=1 + ) + if dept: + return dept.id + return False + + @api.onchange('department') + def _onchange_department(self): + if self.department: + if self.cross_dept_action == "cross_dept": + self.assigned_from_dept = self.department.id + @api.depends('department','cross_dept_action','assigned_to_dept') + def _compute_allowed_users(self): + for rec in self: + if rec.cross_dept_action == "inter_dept": + rec.allowed_user_ids = rec.department.users_line_ids.mapped('users') + else: + rec.allowed_user_ids = rec.assigned_to_dept.users_line_ids.mapped('users') + @api.depends('create_uid') + def _compute_is_sales_user_created(self): + sales_groups = [ + self.env.ref('sos_inventory.sos_sales_user').id, + self.env.ref('sos_inventory.sos_inside_sales_user').id + ] + for record in self: + record.is_sales_user_created = any( + gid in record.create_uid.groups_id.ids for gid in sales_groups + ) + def _generate_id(self): + sequence_util = self.env['sos_common_scripts'] + scope = 'Cross' if self.cross_dept_action == 'cross_dept' else 'Intra' + dept_label = ( + getattr(self.department, 'short_form', False) + or getattr(self.department, 'name', 'NoDept') + ) + type_id = f"{scope}/{dept_label}" + return sequence_util.generate_sequence('sos_brm_action', type_id, 'todo_id') + + @api.depends('line_ids.target_date', 'line_ids.create_date') + def _compute_latest_target(self): + Line = self.env['sos_brm_action_lines'] + for rec in self: + latest = Line.search([ + ('ref_id', '=', rec.id), + ('target_date', '!=', False), + ], order='target_date desc, id desc', limit=1) + if not latest: + latest = Line.search([('ref_id', '=', rec.id)], + order='create_date desc, id desc', limit=1) + rec.latest_target_line_id = latest.id or False + rec.latest_target_date = latest.target_date or False + def action_revise_target(self): + print("bye") + + @api.model + def create(self, vals): + record = super().create(vals) + if record.priority == 0 : + priority_emo='🟢 Low' + elif record.priority == 1 : + priority_emo='🟡 Medium' + elif record.priority == 2 : + priority_emo='🔴 High' + else: + priority_emo='🚨 Urgent' + + # Set assigned_by + record.assigned_by = self.env.user.id + + # Send email if responsible person exists and is different + responsible_id = record.responsible_person + process_incharge = record.reporting_to + if record.cross_dept_action == "cross_dept": + if process_incharge.id != self.env.user.id: + cc_mail_id = process_incharge.login + else: + cc_mail_id = "" + if responsible_id and responsible_id.id != self.env.user.id: + body_html = f""" +

Below Action Plan is assigned to your Department

+

Action Plan : {record.name}

+

Priority : {priority_emo}

+

Assigned By Dept : {record.assigned_from_dept.name}

+

Assigned By : {self.env.user.name}

+ """ + subject = "Action Plan - Notification" + self.env['sos_common_scripts'].send_direct_email( + self.env, + "sos_brm_action", + record.id, + responsible_id.login, + subject, + body_html, + cc_mail_id + ) + else: + if responsible_id and responsible_id.id != self.env.user.id: + body_html = f""" +

Below Action Plan is assigned to you

+

Action Plan : {record.name}

+

Priority : {priority_emo}

+

Assigned By : {self.env.user.name}

+ """ + subject = "Action Plan - Notification" + self.env['sos_common_scripts'].send_direct_email( + self.env, + "sos_brm_action", + record.id, + responsible_id.login, + subject, + body_html + ) + + # Now department is guaranteed → Generate ID + dept_label = record.department.short_form or record.department.name or 'NoDept' + scope = 'Cross' if record.cross_dept_action == 'cross_dept' else 'Intra' + type_id = f"{scope}/{dept_label}" + record.todo_id = self.env['sos_common_scripts'].generate_sequence('sos_brm_action', type_id, 'todo_id') + + return record + + + + + + def action_assign_action_btn(self): + return { + 'name': "Assign Action to Other Department", + 'type': 'ir.actions.act_window', + 'res_model': 'sos_brm_action', + 'view_mode': 'form', + 'view_id': self.env.ref('sos_brm.view_form_sos_brm_action_cross_dept').id, + 'target': 'new', + 'context': { + 'from_wizard': True, + 'default_cross_dept_action': 'cross_dept' + } + } +class sos_brm_action_lines(models.Model): + _name = 'sos_brm_action_lines' + _description = 'Business Review' + + ref_id = fields.Many2one('sos_brm_action', string="BRM action lines", ondelete="cascade") + name = fields.Char(string="Action Plan") + start_date = fields.Date(string="Entry Date") + target_date = fields.Date(string="Revised Target Date") + result = fields.Text(string="Result") + status = fields.Selection([ ('open', 'Open'),('close', 'Closed'),('hold', 'Hold')], default='open' , string="Status") + + +class sos_revised_targets(models.Model): + _name = 'sos_brm_action_revised_targets' + _description = 'Business Review' + + ref_id = fields.Many2one('sos_brm_action', string="BRM action lines", ondelete="cascade") + revised_date = fields.Date(string="Revised Date") + diff --git a/sos_brm/report/__init__.py b/sos_brm/report/__init__.py new file mode 100755 index 0000000..1bfba1f --- /dev/null +++ b/sos_brm/report/__init__.py @@ -0,0 +1,3 @@ +from .import sos_brm_summary_report +from .import sos_cross_dept_report + diff --git a/sos_brm/report/sos_brm_report_result.xml b/sos_brm/report/sos_brm_report_result.xml new file mode 100755 index 0000000..7614371 --- /dev/null +++ b/sos_brm/report/sos_brm_report_result.xml @@ -0,0 +1,417 @@ + + + BRM Landscape Format + + A4 + Landscape + 10 + 10 + 10 + 10 + + + + + + To-Do Reports + sos_brm_action + qweb-html + sos_brm.report_brm_action_plan_summary + BRM_Plan_Summary + + + + + diff --git a/sos_brm/report/sos_brm_summary_report.py b/sos_brm/report/sos_brm_summary_report.py new file mode 100755 index 0000000..1114b25 --- /dev/null +++ b/sos_brm/report/sos_brm_summary_report.py @@ -0,0 +1,71 @@ +from odoo import models, api +from odoo.exceptions import UserError +from datetime import date, timedelta +from calendar import month_name +from collections import defaultdict + +class BRM_WeekSummaryReport(models.AbstractModel): + _name = 'report.sos_brm.report_brm_action_plan_summary' + _description = 'BRM Action Plan Summary Report' + + + + + @api.model + def _get_report_values(self, docids, data=None): + if not data: + raise UserError("No filter data provided for the report.") + + done_by = data.get('done_by') + status = data.get('status') + department = data.get('department') + department_name = data.get('department_name') + cross_dept_action = data.get('cross_dept_action') + + domain = [] + if done_by: + domain.append(('responsible_person', '=', int(done_by))) + if department: + domain += [ + '|', + ('department', '=', department), + ('assigned_to_dept', '=', department) + ] + + if status and status != 'all': + domain.append(('status', '=', status)) + if cross_dept_action != "all": + domain.append(('cross_dept_action', '=', cross_dept_action)) + + + # Main actions + docs = self.env['sos_brm_action'].search(domain, order='target_date asc, id asc') + + # Subsets + cross = docs.filtered(lambda r: r.cross_dept_action == 'cross_dept') + local = docs.filtered(lambda r: r.cross_dept_action == 'inter_dept') + + # Prefetch all child lines once and group by parent id + ActionLines = self.env['sos_brm_action_lines'] + lines_map = defaultdict(list) # action_id -> list of line records + if docs: + all_lines = ActionLines.search([ + ('ref_id', 'in', docs.ids) + ], order='ref_id, start_date, id') + + for ln in all_lines: + lines_map[ln.ref_id.id].append(ln) + return { + 'doc_ids': docs.ids, + 'doc_model': 'sos_brm_action', + 'done_by': self.env['res.users'].browse(int(done_by)) if done_by else self.env['res.users'], + 'status': status or '', + 'department': department_name or '', + 'docs': docs, + 'cross': cross, + 'local': local, + 'count_cross': len(cross), + 'count_local': len(local), + 'cross_dept_action':cross_dept_action, + 'lines_map': lines_map, + } \ No newline at end of file diff --git a/sos_brm/report/sos_cross_dept_report.py b/sos_brm/report/sos_cross_dept_report.py new file mode 100755 index 0000000..ddb3fb6 --- /dev/null +++ b/sos_brm/report/sos_cross_dept_report.py @@ -0,0 +1,74 @@ +from odoo import models, api +from odoo.exceptions import UserError +from datetime import date, timedelta +from calendar import month_name +from collections import defaultdict + +class BRM_CrossReport(models.AbstractModel): + _name = 'report.sos_brm.report_cross_dept_summary' + _description = 'Cross Dept Summary Report' + + + @api.model + def _get_report_values(self, docids, data=None): + if not data: + raise UserError("No filter data provided for the report.") + + # Wizard inputs (expect raw IDs / strings, or falsy) + assigned_from_dept = data.get('assigned_from_dept') + assigned_to_dept = data.get('assigned_to_dept') + assigned_by = data.get('assigned_by') + status = data.get('status') or False + + # Cross-dept only + domain = [('cross_dept_action', '=', 'cross_dept')] + if assigned_from_dept not in (None, '', 0, '0'): + try: + domain.append(('assigned_from_dept', '=', int(assigned_from_dept))) + except (TypeError, ValueError): + pass + if assigned_to_dept not in (None, '', 0, '0'): + try: + domain.append(('assigned_to_dept', '=', int(assigned_to_dept))) + except (TypeError, ValueError): + pass + if assigned_by not in (None, '', 0, '0'): + try: + domain.append(('assigned_by', '=', int(assigned_by))) + except (TypeError, ValueError): + pass + if status and status != 'all': + domain.append(('status', '=', status)) + + Action = self.env['sos_brm_action'] + ActionLine = self.env['sos_brm_action_lines'] + + # Main actions + docs = Action.search(domain, order='target_date asc, id asc') + + # Prefetch child lines (open only) and group by parent + lines_map = defaultdict(list) + # ensure keys exist for all docs (lets us index lines_map[rec.id] in QWeb) + for rec in docs: + lines_map.setdefault(rec.id, []) + if docs: + all_lines = ActionLine.search( + [('ref_id', 'in', docs.ids)], + order='ref_id, start_date, id' + ) + for ln in all_lines: + lines_map[ln.ref_id.id].append(ln) + + # Precompute for QWeb (avoid len()/dict() calls there) + count_cross = len(docs) + child_counts = {rid: len(lst) for rid, lst in lines_map.items()} + + return { + 'doc_ids': docs.ids, + 'doc_model': 'sos_brm_action', + 'docs': docs, + 'status': status or '', + 'lines_map': lines_map, + 'count_cross': count_cross, + 'child_counts': child_counts, + } \ No newline at end of file diff --git a/sos_brm/report/sos_cross_dept_report_result.xml b/sos_brm/report/sos_cross_dept_report_result.xml new file mode 100755 index 0000000..2e04c82 --- /dev/null +++ b/sos_brm/report/sos_cross_dept_report_result.xml @@ -0,0 +1,172 @@ + + + BRM Landscape Format + + A4 + Landscape + 10 + 10 + 10 + 10 + + + + + + BRM Reports + sos_brm_action + qweb-html + sos_brm.report_cross_dept_summary + Cross Dept Summary + + + + + + diff --git a/sos_brm/security/ir.model.access.csv b/sos_brm/security/ir.model.access.csv new file mode 100755 index 0000000..4b7b157 --- /dev/null +++ b/sos_brm/security/ir.model.access.csv @@ -0,0 +1,7 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_sos_brm_action,sos_brm_action access,model_sos_brm_action,base.group_user,1,1,1,1 +access_sos_brm_action_lines,sos_brm_action_lines access,model_sos_brm_action_lines,base.group_user,1,1,1,1 +access_sos_brm_action_revised_targets,sos_brm_action_revised_targets access,model_sos_brm_action_revised_targets,base.group_user,1,1,1,1 +access_sos_brm_action_report_wizard,sos_brm_action_report_wizard access,model_sos_brm_action_report_wizard,base.group_user,1,1,1,1 +access_sos_cross_dept_report_wizard,sos_cross_dept_report_wizard access,model_sos_cross_dept_report_wizard,base.group_user,1,1,1,1 + diff --git a/sos_brm/security/record_rules.xml b/sos_brm/security/record_rules.xml new file mode 100755 index 0000000..e315c1e --- /dev/null +++ b/sos_brm/security/record_rules.xml @@ -0,0 +1,72 @@ + + + + + BRM Action: Full (own/assigned/creator) + + [ + '|','|','|', + ('responsible_person', '=', user.id), + ('assigned_by', '=', user.id), + ('create_uid', '=', user.id), + ('reporting_to', '=', user.id) + ] + + + + + + + + + + BRM Action: Create (any) + + [(1,'=',1)] + + + + + + + + + + + BRM Action: Create (any) + + [(1,'=',1)] + + + + + + + + + + BRM Action: Full (managers/finance) + + [(1,'=',1)] + + + + + + + + + BRM Action: Reviewer Read Sales User Created Records + + [('is_sales_user_created', '=', True)] + + + + + + + + diff --git a/sos_brm/views/menu.xml b/sos_brm/views/menu.xml new file mode 100755 index 0000000..55a2b34 --- /dev/null +++ b/sos_brm/views/menu.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/sos_brm/views/sos_brm_action_view.xml b/sos_brm/views/sos_brm_action_view.xml new file mode 100755 index 0000000..bcd801a --- /dev/null +++ b/sos_brm/views/sos_brm_action_view.xml @@ -0,0 +1,155 @@ + + + + Actions + ir.actions.act_window + sos_brm_action + tree,form,kanban + + + + sos_brm_action.view.search + sos_brm_action + + + + + + + + + + + + + + + + + + sos_brm_action.view.tree + sos_brm_action + + + + + + + + + + + + + + + + + + + + + + + Form + sos_brm_action + + +
+ + + + + + + + + + + + + + + + + +
+
+
+ + Form + sos_brm_action + +
+ + + +

To-Do Management




+ + + + + +
+





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



+ + + + + + + + + +
+
+
+
+ + Reports + sos_brm_action_report_wizard + form + new + + + Reports + sos_cross_dept_report_wizard + form + new + + + + + +
diff --git a/sos_brm/wizard/__init__.py b/sos_brm/wizard/__init__.py new file mode 100755 index 0000000..f6a1584 --- /dev/null +++ b/sos_brm/wizard/__init__.py @@ -0,0 +1,2 @@ +from .import sos_brm_report_wizard +from .import sos_cross_dept_report_wizard \ No newline at end of file diff --git a/sos_brm/wizard/sos_brm_report_wizard.py b/sos_brm/wizard/sos_brm_report_wizard.py new file mode 100755 index 0000000..386784c --- /dev/null +++ b/sos_brm/wizard/sos_brm_report_wizard.py @@ -0,0 +1,63 @@ +from odoo import models, fields, api +import io +from datetime import date, timedelta +from odoo.exceptions import UserError + +class SOS_BRM_Report_Wizard(models.TransientModel): + _name = 'sos_brm_action_report_wizard' + _description = 'BRM Report Wizard' + + cross_dept_action = fields.Selection( + selection=[ + ('all', 'Both'), + ('cross_dept', 'Cross-Dept'), + ('inter_dept', 'Intra-Dept') + ], + string='Type', + default='all' + ) + done_by = fields.Many2one( + 'res.users', + string='Responsible') + department = fields.Many2one('sos_departments', string='Department') + status = fields.Selection([ ('all', 'All'),('open', 'Open'),('close', 'Closed'),('hold', 'Hold')], default='open' , string="Status") + + + + def generate_report(self): + # Build domain for filtering records + domain = [] + if self.done_by: + + domain.append(('responsible_person', '=', self.done_by.id)) + if self.status != 'all': + domain.append(('status', '=', self.status)) + if self.department: + domain.append(('department', '=', self.department.id)) + if self.cross_dept_action != "all": + domain.append(('cross_dept_action', '=', self.cross_dept_action)) + # Search for records + records = self.env['sos_brm_action'].search(domain) + if not records: + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': ('No Records Found'), + 'message': ('No Records Found'), + 'type': 'warning', + 'sticky': False, + } + } + # Generate report with filtered record IDs + return self.env.ref('sos_brm.action_brm_summary_report').report_action( + records.ids, + data={ + + 'done_by' : self.done_by.id, + 'department':self.department.id, + 'department_name':self.department.name, + 'status' : self.status, + 'cross_dept_action' : self.cross_dept_action + } + ) diff --git a/sos_brm/wizard/sos_brm_report_wizard_view.xml b/sos_brm/wizard/sos_brm_report_wizard_view.xml new file mode 100755 index 0000000..7a9dde7 --- /dev/null +++ b/sos_brm/wizard/sos_brm_report_wizard_view.xml @@ -0,0 +1,23 @@ + + + sos_brm_action_report_wizard.form + sos_brm_action_report_wizard + +
+ + + + + + + +
+ + +
+
+
+
+ +
\ No newline at end of file diff --git a/sos_brm/wizard/sos_cross_dept_report_wizard.py b/sos_brm/wizard/sos_cross_dept_report_wizard.py new file mode 100755 index 0000000..997e36d --- /dev/null +++ b/sos_brm/wizard/sos_cross_dept_report_wizard.py @@ -0,0 +1,56 @@ +from odoo import models, fields, api +import io +from datetime import date, timedelta +from odoo.exceptions import UserError + +class SOS_BRM_Report_Wizard(models.TransientModel): + _name = 'sos_cross_dept_report_wizard' + _description = 'Cross dept Report Wizard' + + + assigned_from_dept = fields.Many2one('sos_departments', string='Assigned By') + assigned_to_dept = fields.Many2one('sos_departments', string='Assigned To Dept') + status = fields.Selection([ ('all', 'All'),('open', 'Open'),('close', 'Closed'),('hold', 'Hold')], default='open' , string="Status") + assigned_by = fields.Many2one( + 'res.users', + string='Assigned By' +) + + + def generate_report(self): + # Build domain for filtering records + domain = [('cross_dept_action','=','cross_dept')] + if self.assigned_from_dept: + domain.append(('assigned_from_dept', '=', self.assigned_from_dept.id)) + if self.assigned_to_dept: + domain.append(('assigned_to_dept', '=', self.assigned_to_dept.id)) + if self.assigned_by: + domain.append(('assigned_by', '=', self.assigned_by.id)) + if self.status and self.status != 'all': + domain.append(('status', '=', self.status)) + + # Search for records + records = self.env['sos_brm_action'].search(domain) + if not records: + return { + 'type': 'ir.actions.client', + 'tag': 'display_notification', + 'params': { + 'title': ('No Records Found'), + 'message': ('No Records Found'), + 'type': 'warning', + 'sticky': False, + } + } + # Generate report with filtered record IDs + return self.env.ref('sos_brm.action_cross_dept_report').report_action( + records.ids, + data={ + + 'assigned_from_dept' : self.assigned_from_dept.id, + 'assigned_to_dept':self.assigned_to_dept.id, + 'assigned_by':self.assigned_by.id, + 'status' : self.status, + 'cross_dept_action':'cross_dept' + } + ) diff --git a/sos_brm/wizard/sos_cross_dept_report_wizard_view.xml b/sos_brm/wizard/sos_cross_dept_report_wizard_view.xml new file mode 100755 index 0000000..e64d7cf --- /dev/null +++ b/sos_brm/wizard/sos_cross_dept_report_wizard_view.xml @@ -0,0 +1,23 @@ + + + sos_cross_dept_report_wizard.form + sos_cross_dept_report_wizard + +
+ + + + + + + + +
+
+
+ +
\ No newline at end of file