|
| 1 | +# Copyright (C) 2019 - Raphael Valyi Akretion |
| 2 | +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html |
| 3 | + |
| 4 | +import sys |
| 5 | +import inspect |
| 6 | +from odoo import api, models, SUPERUSER_ID |
| 7 | +from .models.spec_models import SpecModel, StackedModel |
| 8 | + |
| 9 | + |
| 10 | +def post_init_hook(cr, registry, module_name, spec_module): |
| 11 | + "automatically generate access rules for spec models" |
| 12 | + env = api.Environment(cr, SUPERUSER_ID, {}) |
| 13 | + # TODO no hardcode |
| 14 | + remaining_models = get_remaining_spec_models( |
| 15 | + cr, registry, module_name, spec_module) |
| 16 | + fields = ['id', 'name', 'model_id/id', 'group_id/id', |
| 17 | + 'perm_read', 'perm_write' , 'perm_create', 'perm_unlink'] |
| 18 | + access_data = [] |
| 19 | + for model in remaining_models: |
| 20 | + underline_name = model.replace('.', '_') |
| 21 | + rec_id = "acl_%s_nfe_40_%s" % ('todo'.split('.')[-1], |
| 22 | + underline_name) |
| 23 | + # TODO no nfe ref |
| 24 | + model_id = "l10n_br_nfe_spec.model_%s" % (underline_name,) |
| 25 | + access_data.append([rec_id, underline_name, model_id, 'base.group_user', |
| 26 | + '1', '1', '1', '1']) |
| 27 | + # TODO make more secure! |
| 28 | + env['ir.model.access'].load(fields, access_data) |
| 29 | + |
| 30 | +def get_remaining_spec_models(cr, registry, module_name, spec_module): |
| 31 | + cr.execute("""select ir_model.model from ir_model_data |
| 32 | + join ir_model on res_id=ir_model.id |
| 33 | + where ir_model_data.model='ir.model' |
| 34 | + and module=%s;""", (module_name,)) |
| 35 | + module_models = [i[0] for i in cr.fetchall() if registry.get(i[0]) |
| 36 | + and not registry[i[0]]._abstract] |
| 37 | + |
| 38 | + injected_models = set() |
| 39 | + for model in module_models: |
| 40 | + base_class = registry[model] |
| 41 | + # 1st classic Odoo classes |
| 42 | + if hasattr(base_class, '_inherit'): |
| 43 | + injected_models.add(base_class._name) |
| 44 | + if isinstance(base_class._inherit, list): |
| 45 | + injected_models = injected_models.union( |
| 46 | + set(base_class._inherit)) |
| 47 | + elif base_class._inherit is not None: |
| 48 | + injected_models.add(base_class._inherit) |
| 49 | + |
| 50 | + # visit_stack will now need the associated spec classes |
| 51 | + injected_classes = set() |
| 52 | + remaining_models = set(['nfe.40.tveiculo']) # TODO |
| 53 | + # TODO when using a registry loading, use _stack_skip to find |
| 54 | + # out which models to leave concrete, see later commented loop |
| 55 | + |
| 56 | + for m in injected_models: |
| 57 | + c = SpecModel._odoo_name_to_class(m, spec_module) |
| 58 | + if c is not None: |
| 59 | + injected_classes.add(c) |
| 60 | + |
| 61 | + for model in module_models: |
| 62 | + base_class = registry[model] |
| 63 | + # 2nd StackedModel classes, that we will visit |
| 64 | + if hasattr(base_class, '_stacked'): |
| 65 | + node = SpecModel._odoo_name_to_class(base_class._stacked, |
| 66 | + spec_module) |
| 67 | + |
| 68 | + # TODO with registry!! |
| 69 | + base_class._visit_stack(node, injected_classes, |
| 70 | + base_class._stacked.split('.')[-1], |
| 71 | + registry, cr) |
| 72 | + # for f in base_class._stack_skip: |
| 73 | + # if base_class._fields[] |
| 74 | + |
| 75 | + used_models = [c._name for c in injected_classes] |
| 76 | + print(" **** injected spec models (%s): %s" % ( |
| 77 | + len(used_models), used_models)) |
| 78 | + # TODO replace by SELECT like for module_models ? |
| 79 | + all_spec_models = set([c._name for name, c |
| 80 | + in inspect.getmembers( |
| 81 | + sys.modules[spec_module], inspect.isclass)]) |
| 82 | + |
| 83 | + print("number of all spec models:", len(all_spec_models)) |
| 84 | + remaining_models = remaining_models.union( |
| 85 | + set([i for i in all_spec_models |
| 86 | + if i not in [c._name for c in injected_classes]])) |
| 87 | + print("\n **** REMAINING spec models to init (%s): %s \n\n" % ( |
| 88 | + len(remaining_models), remaining_models)) |
| 89 | + return remaining_models |
| 90 | + |
| 91 | +def register_hook(env, module_name, spec_module): |
| 92 | + remaining_models = get_remaining_spec_models(env.cr, env.registry, |
| 93 | + module_name, spec_module) |
| 94 | + for name in remaining_models: |
| 95 | + spec_class = StackedModel._odoo_name_to_class(name, spec_module) |
| 96 | + spec_class._module = "fiscal" # TODO use python_module ? |
| 97 | + c = type(name, (SpecModel, spec_class), |
| 98 | + {'_name': spec_class._name, |
| 99 | + '_inherit': ['spec.mixin.nfe'], |
| 100 | + '_original_module': "fiscal", |
| 101 | + '_rec_name': spec_class._concrete_rec_name}) |
| 102 | + models.MetaModel.module_to_models[module_name] += [c] |
| 103 | + |
| 104 | + # now we init these models properly |
| 105 | + # a bit like odoo.modules.loading#load_module_graph would do. |
| 106 | + c._build_model(env.registry, env.cr) |
| 107 | + |
| 108 | + env[name]._prepare_setup() |
| 109 | + env[name]._setup_base() |
| 110 | + env[name]._setup_fields() |
| 111 | + env[name]._setup_complete() |
| 112 | + |
| 113 | + # TODO only in update mode! |
| 114 | + env.registry.init_models(env.cr, remaining_models, {'module': module_name}) |
0 commit comments