#!/usr/bin/env python2 # -*- coding: utf-8 -*- # __coconut_hash__ = 0xb1df5fa # Compiled with Coconut version 2.1.1 [The Spanish Inquisition] """ Odoo XML DSL """ # Coconut Header: ------------------------------------------------------------- from __future__ import print_function, absolute_import, unicode_literals, division import sys as _coconut_sys, os as _coconut_os _coconut_file_dir = _coconut_os.path.dirname(_coconut_os.path.abspath(__file__)) _coconut_cached_module = _coconut_sys.modules.get(b"__coconut__") if _coconut_cached_module is not None and _coconut_os.path.dirname(_coconut_cached_module.__file__) != _coconut_file_dir: # type: ignore del _coconut_sys.modules[b"__coconut__"] _coconut_sys.path.insert(0, _coconut_file_dir) _coconut_module_name = _coconut_os.path.splitext(_coconut_os.path.basename(_coconut_file_dir))[0] if _coconut_module_name and _coconut_module_name[0].isalpha() and all(c.isalpha() or c.isdigit() for c in _coconut_module_name) and "__init__.py" in _coconut_os.listdir(_coconut_file_dir): _coconut_full_module_name = str(_coconut_module_name + ".__coconut__") import __coconut__ as _coconut__coconut__ _coconut__coconut__.__name__ = _coconut_full_module_name for _coconut_v in vars(_coconut__coconut__).values(): if getattr(_coconut_v, "__module__", None) == b"__coconut__": try: _coconut_v.__module__ = _coconut_full_module_name except AttributeError: _coconut_v_type = type(_coconut_v) if getattr(_coconut_v_type, "__module__", None) == b"__coconut__": _coconut_v_type.__module__ = _coconut_full_module_name _coconut_sys.modules[_coconut_full_module_name] = _coconut__coconut__ from __coconut__ import * from __coconut__ import _coconut_tail_call, _coconut_tco, _coconut_call_set_names, _coconut_handle_cls_kwargs, _coconut_handle_cls_stargs, _namedtuple_of, _coconut, _coconut_super, _coconut_MatchError, _coconut_iter_getitem, _coconut_base_compose, _coconut_forward_compose, _coconut_back_compose, _coconut_forward_star_compose, _coconut_back_star_compose, _coconut_forward_dubstar_compose, _coconut_back_dubstar_compose, _coconut_pipe, _coconut_star_pipe, _coconut_dubstar_pipe, _coconut_back_pipe, _coconut_back_star_pipe, _coconut_back_dubstar_pipe, _coconut_none_pipe, _coconut_none_star_pipe, _coconut_none_dubstar_pipe, _coconut_bool_and, _coconut_bool_or, _coconut_none_coalesce, _coconut_minus, _coconut_map, _coconut_partial, _coconut_get_function_match_error, _coconut_base_pattern_func, _coconut_addpattern, _coconut_sentinel, _coconut_assert, _coconut_raise, _coconut_mark_as_match, _coconut_reiterable, _coconut_self_match_types, _coconut_dict_merge, _coconut_exec, _coconut_comma_op, _coconut_multi_dim_arr, _coconut_mk_anon_namedtuple, _coconut_matmul _coconut_sys.path.pop(0) # Compiled Coconut: ----------------------------------------------------------- # -*- coding: utf-8 -*- # # Copyright 2019-2020 Fabien Bourgeois # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . from .xml_base import xmlroot from .xml_base import xmln # XML helpers functions and macros # Odoo root XML Node odoo = lambda children: xmlroot({'tag': 'odoo', 'attrs': {}, 'children': children}) # Special data Node @_coconut_tco def data(*args): """ Allow optional args on data tag """ if len(args) == 1: args = list(args) args.insert(0, {}) return _coconut_tail_call(xmln, 'data', *args) # Aliases function = lambda *args: xmln('function', *args) record = lambda *args: xmln('record', *args) form = lambda *args: xmln('form', *args) tree = lambda *args: xmln('tree', *args) search = lambda *args: xmln('search', *args) # Actions act_window = lambda *args: xmln('act_window', *args) @_coconut_tco def act_window_model(model, attrs): """ Build new act_window from model and args """ xmlid = '%s_view_action' % (model.replace('.', '_')) name = '%s Action' % ' '.join(map(lambda w: w.capitalize(), model.split('.'))) attrs_clone = attrs.copy() # Avoid side-effect attrs_clone.update({'id': xmlid, 'name': name, 'res_model': model}) return _coconut_tail_call(act_window, attrs_clone) @_coconut_tco def action_server_code(xmlid, name, modelref, code): """ Server actions of type code """ children = [field_name(name), field({'name': 'model_id', 'ref': modelref}, []), field({'name': 'state'}, ['code',]), field({'name': 'code'}, [code,])] return _coconut_tail_call(record, {'id': xmlid, 'model': 'ir.actions.server'}, children) @_coconut_tco def client_action_multi(xmlid, name, model, action): """ Client action multi (ir.values), with own xmlid, name, targeted model and action """ action = "'ir.actions.server,%d'%{}".format(action) children = [field_name(name), field({'name': 'key2', 'eval': "'client_action_multi'"}), field({'name': 'model', 'eval': "'%s'" % model}), field({'name': 'value', 'eval': action})] return _coconut_tail_call(record, {'id': xmlid, 'model': 'ir.values'}, children) # Menus menuitem = lambda *args: xmln('menuitem', *args) @_coconut_tco def menuitem_model(model, attrs): """ Build new menuitem from model and attrs """ model_und = model.replace('.', '_') xmlid = '%s_menu' % model_und actionid = '%s_view_action' % model_und attrs_clone = attrs.copy() # Avoid side-effect attrs_clone.update({'id': xmlid, 'action': actionid}) return _coconut_tail_call(menuitem, attrs_clone) # Form aliases group = lambda *args: xmln('group', *args) header = lambda *args: xmln('header', *args) footer = lambda *args: xmln('footer', *args) sheet = lambda *args: xmln('sheet', *args) button = lambda *args: xmln('button', *args) p = lambda *args: xmln('p', *args) xpath = lambda *args: xmln('xpath', *args) attribute = lambda name, value: xmln('attribute', {'name': name}, [value,]) # Fields field = lambda *args: xmln('field', *args) field_name = lambda name: field({'name': 'name'}, [name,]) field_nval = lambda name, value: field({'name': name}, [value,]) field_model = lambda model: field({'name': 'model'}, [model,]) field_inherit = lambda xmlid: field({'name': 'inherit_id', 'ref': xmlid}, []) field_arch = lambda *args: field({'name': 'arch', 'type': 'xml'}, *args) # Search filter = lambda *args: xmln('filter', *args) # Views view = lambda xmlid, children: record({'id': xmlid, 'model': 'ir.ui.view'}, children) @_coconut_tco def view_def(xmlid, name, model, arch): """ Shortcut for new view """ return _coconut_tail_call(view, xmlid, [field_name(name), field_model(model), field_arch(arch)]) @_coconut_tco def view_new(view_type, model, arch): """ View : new view definition, based on type (form, tree, ...) and model ID """ model_und = model.replace('.', '_') model_cap = ' '.join(map(lambda w: w.capitalize(), model.split('.'))) xmlid = "%s_view_%s" % (model_und, view_type) name = ' '.join([model_cap, view_type.capitalize()]) return _coconut_tail_call(view_def, xmlid, name, model, arch) @_coconut_tco def view_inherit(filename, model, inherit, arch): """ Inherited View simplification with name of the record, xmlid for model and inherited view """ module = filename.split('.')[2] inherited = inherit.split('.')[1] xmlid = '%s_inherit_%s' % (inherited, module) model_cap = ' '.join(map(lambda w: w.capitalize(), model.split('.'))) name = '%s Adaptations' % model_cap return _coconut_tail_call(view, xmlid, [field_name(name), field_model(model), field_inherit(inherit), field_arch(arch)])