99 lines
4.1 KiB
Python
99 lines
4.1 KiB
Python
from collections import defaultdict
|
|
|
|
from odoo import api, fields, models
|
|
from odoo.tools import frozendict
|
|
|
|
|
|
class DocumentsAccessTracking(models.Model):
|
|
_name = 'documents.access.tracking'
|
|
_description = 'Document Access Tracking'
|
|
_log_access = False
|
|
|
|
changes = fields.Json(string='Changes need to be tracked', required=True)
|
|
documents = fields.Json(string='Impacted Document Ids', required=True)
|
|
user_id = fields.Many2one('res.users', string='User', default=lambda self: self.env.user)
|
|
|
|
@api.model
|
|
def _create_access_tracking(self, changes_by_document_dict):
|
|
documents_by_changes = defaultdict(list)
|
|
for document_id, changes in changes_by_document_dict.items():
|
|
documents_by_changes[frozendict(changes)].append(document_id)
|
|
|
|
batch_size = int(self.env['ir.config_parameter'].sudo().get_param('documents.tracking_batch_size', '500'))
|
|
for changes, documents in documents_by_changes.items():
|
|
self.sudo().create([
|
|
{
|
|
'changes': changes,
|
|
'documents': documents[offset: offset + batch_size],
|
|
'user_id': self.env.user.id,
|
|
} for offset in range(0, len(documents), batch_size)
|
|
])
|
|
|
|
self.env.ref('documents.ir_cron_documents_access_tracking')._trigger()
|
|
|
|
@api.model
|
|
def _cron_generate_tracking(self):
|
|
tracking_id = self.search([], limit=1)
|
|
if not tracking_id:
|
|
self.env['ir.cron']._commit_progress(remaining=0)
|
|
return
|
|
|
|
tracking_id._create_message_track()
|
|
tracking_id.unlink()
|
|
self.env['ir.cron']._commit_progress(processed=len(tracking_id), remaining=self.search_count([]))
|
|
|
|
def _create_message_track(self):
|
|
self.ensure_one()
|
|
document_ids = self.env['documents.document'].browse(self.documents)
|
|
if initial_values := self._get_initial_values():
|
|
if 'members' in self.changes:
|
|
self._add_pre_commit_members_data()
|
|
document_ids.with_user(self.user_id)._message_track([
|
|
'access_internal',
|
|
'access_via_link',
|
|
'is_access_via_link_hidden',
|
|
], initial_values)
|
|
else:
|
|
body = self._get_members_change_template_body()
|
|
document_ids.with_user(self.user_id)._message_log_batch(
|
|
bodies={doc_id: body for doc_id in document_ids.ids}
|
|
)
|
|
|
|
def _get_initial_values(self):
|
|
self.ensure_one()
|
|
fields_list = ['access_internal', 'access_via_link', 'is_access_via_link_hidden']
|
|
common_values = {
|
|
field: self.changes[field] for field in fields_list if field in self.changes
|
|
}
|
|
return {doc_id: common_values for doc_id in self.documents if common_values}
|
|
|
|
def _add_pre_commit_members_data(self):
|
|
self.ensure_one()
|
|
common_body = self._get_members_change_template_body()
|
|
self.env.cr.precommit.data.setdefault('mail.tracking.message.documents.document', {
|
|
doc_id: common_body for doc_id in self.documents
|
|
})
|
|
|
|
def _get_members_change_template_body(self):
|
|
self.ensure_one()
|
|
return self.env['ir.qweb']._render('documents.tracking_access_members_change', {
|
|
'created_access': self.changes['members']['added'],
|
|
'updated_access': self.changes['members']['updated'],
|
|
'removed_access': self.changes['members']['removed'],
|
|
'partner_map': self._get_partners_mapping(),
|
|
}, lang=self.user_id.lang, minimal_qcontext=True)
|
|
|
|
def _get_partners_mapping(self):
|
|
self.ensure_one()
|
|
partner_map = {}
|
|
members_dict = self.changes['members']
|
|
for operation in ['added', 'updated']:
|
|
# must cast into int because fields.Json set all keys in string
|
|
partner_ids = self.env['res.partner'].browse([int(id) for id in members_dict[operation]])
|
|
partner_map.update(dict(zip(members_dict[operation].keys(), partner_ids)))
|
|
|
|
partner_ids = self.env['res.partner'].browse(members_dict['removed'])
|
|
partner_map.update(dict(zip(members_dict['removed'], partner_ids)))
|
|
|
|
return partner_map
|