import copy import json import logging import subprocess import sys from io import StringIO from pathlib import Path from flectra import models, fields, api, _ from flectra.tools import config, etree, base64, convert_xml_import, tempfile import os from flectra.exceptions import ValidationError _logger = logging.getLogger(__name__) class MisBuilderImportWizard(models.TransientModel): # Private attributes _name = "mis.builder.import.wizard" _description = "Import MIS Builder Report" file = fields.Binary( string='Settings File', required=True, ) def __int__(self): super(MisBuilderImportWizard, self).__int__() def import_report(self): self.ensure_one() json_data = base64.b64decode(self.file) report_data = json.loads(json_data) for report_entry in report_data: report_values = self.__prepare_report_values(report_entry) self.__prepare_style_values(report_entry, report_values) self.__prepare_subreport_values(report_entry, report_values) self.__prepare_query_values(report_values) self.__prepare_kpi_values(report_values) subkpi_values = [] if report_values.get('subkpi_ids'): for subkpi_value in report_values['subkpi_ids']: subkpi_values.append(subkpi_value) del report_values['subkpi_ids'] new_report = self.env['mis.report'].create(report_values) self._create_external_reference(new_report, report_entry['extid']) self.__update_subkpi_values(new_report, report_entry, subkpi_values) def __prepare_style_values(self, report_entry, report_values): if report_entry.get('style_id'): report_values['style_id'] = self._create_style(report_values['style_id']).id def __prepare_report_values(self, report_entry): result = self.env['ir.model.data'].xmlid_to_res_id(report_entry['extid']) if result: raise ValidationError('Report already exists! Please delete it first before importing') report_values = copy.deepcopy(report_entry) del report_values['extid'] for kpi in report_values.get('kpi_ids', []): del kpi['extid'] for expr in kpi.get('expression_ids', []): del expr['extid'] for kpi in report_values.get('subkpi_ids', []): del kpi['extid'] for expr in kpi.get('expression_ids', []): del expr['extid'] report_values['move_lines_source'] = self.env['ir.model'].search([('model', '=', report_values['move_lines_source'])]).id return report_values def __update_subkpi_values(self, new_report, report_entry, subkpi_values): temporary_extids = self.env['ir.model.data'] subkpi_updates = [] if subkpi_values: for kpi_id in new_report.kpi_ids: for kpi_data in report_entry['kpi_ids']: if kpi_id.sequence == kpi_data['sequence']: temporary_extids |= self._create_external_reference(kpi_id, kpi_data['extid']) for subkpi_value in subkpi_values: expression_updates = [] for expression_value in subkpi_value['expression_ids']: expression_value['kpi_id'] = self.env.ref(expression_value['kpi_id']).id expression_updates.append((0, False, expression_value)) subkpi_value['expression_ids'] = expression_updates subkpi_updates.append((0, False, subkpi_value)) if subkpi_updates: new_report.write({'subkpi_ids': subkpi_updates}) if temporary_extids: temporary_extids.unlink() def __prepare_kpi_values(self, report_values): if report_values.get('kpi_ids'): kpi_values = [] for kpi_value in report_values['kpi_ids']: self.__prepare_style_values(kpi_value, kpi_value) if kpi_value.get('auto_expand_accounts_style_id'): kpi_value['auto_expand_accounts_style_id'] = self._create_style(kpi_value['auto_expand_accounts_style_id']).id if report_values.get('subkpi_ids'): del kpi_value['expression'] del kpi_value['expression_ids'] else: if kpi_value.get('expression_ids'): expression_values = [(0, False, v) for v in kpi_value['expression_ids']] kpi_value['expression_ids'] = expression_values kpi_values.append((0, False, kpi_value)) report_values['kpi_ids'] = kpi_values def __prepare_query_values(self, report_values): if report_values.get('query_ids'): query_values = [] for query_value in report_values['query_ids']: query_model = self.env['ir.model'].search([('model', '=', query_value['model_id'])]) query_value['model_id'] = query_model.id query_value['field_ids'] = [(6, 0, [f.id for f in query_model.field_id if f.name in query_value['field_ids']])] query_values.append((0, False, query_value)) report_values['query_ids'] = query_values def __prepare_subreport_values(self, report_entry, report_values): if report_entry.get('subreport_ids'): subreport_values = [] for subreport_value in report_entry['subreport_ids']: subreport_value['subreport_id'] = self.env.ref(subreport_value['subreport_id']).id subreport_values.append((0, False, subreport_value)) report_values['subreport_ids'] = subreport_values @api.model def _create_style(self, style_data): exit_id = style_data['extid'] result = self.env['ir.model.data'].xmlid_to_object(exit_id) if result: return result del style_data['extid'] new_style = self.env['mis.report.style'].create(style_data) self._create_external_reference(new_style, exit_id) return new_style def _create_external_reference(self, obj, extid, temporary=False): module, name = extid.split('.', 1) existing = self.env['ir.model.data'].search([ ('module', '=', module), ('model', '=', obj._name), ('name', '=', name), ], limit=1) if existing: existing.res_id = obj.id return existing return self.env['ir.model.data'].create({ 'module': module, 'model': obj._name, 'name': name, 'res_id': obj.id, })