#!/usr/bin/env python2 # -*- coding: utf-8 -*- # __coconut_hash__ = 0xb0af9f53 # Compiled with Coconut version 1.4.3 [Ernest Scribbler] """ Odoo XML DSL """ # Coconut Header: ------------------------------------------------------------- from __future__ import print_function, absolute_import, unicode_literals, division import sys as _coconut_sys, os.path as _coconut_os_path _coconut_file_path = _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_path: del _coconut_sys.modules[b"__coconut__"] _coconut_sys.path.insert(0, _coconut_file_path) from __coconut__ import * from __coconut__ import _coconut, _coconut_MatchError, _coconut_igetitem, _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_back_pipe, _coconut_star_pipe, _coconut_back_star_pipe, _coconut_dubstar_pipe, _coconut_back_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_mark_as_match # 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 typing import Text from typing import Dict from xml_base import XMLAttrs from xml_base import XMLDictElement from xml_base import xmlroot from xml_base import xmln # XML helpers functions and macros # Odoo root XML Node def odoo(children # type: Dict ): # type: (...) -> ET.Element return (xmlroot)({'tag': 'odoo', 'attrs': {}, 'children': children}) # Special data Node def data(*args): """ Allow optional args on data tag """ if (len)(args) == 1: args = (list)(args) args.insert(0, {}) return xmln('data', *args) # Aliases def function(*args): # type: (...) -> XMLDictElement return xmln('function', *args) def record(*args): # type: (...) -> XMLDictElement return xmln('record', *args) def form(*args): # type: (...) -> XMLDictElement return xmln('form', *args) def tree(*args): # type: (...) -> XMLDictElement return xmln('tree', *args) def search(*args): # type: (...) -> XMLDictElement return xmln('search', *args) # Actions def act_window(*args): # type: (...) -> XMLDictElement return xmln('act_window', *args) def act_window_model(model, # type: Text attrs # type: XMLAttrs ): # type: (...) -> XMLDictElement """ Build new act_window from model and args """ xmlid = '%s_view_action' % ((model.replace)(*('.', '_'))) name = '%s Action' % ((' '.join)((list)(map(lambda _=None: _.capitalize(), (model.split)('.'))))) attrs_clone = attrs.copy() # Avoid side-effect (attrs_clone.update)({'id': xmlid, 'name': name, 'res_model': model}) return act_window(attrs_clone) def action_server_code(xmlid, # type: Text name, # type: Text modelref, # type: Text code # type: Text ): # type: (...) -> XMLDictElement """ Server actions of type code """ children = [(field_name)(name), (field)(*({'name': 'model_id', 'ref': modelref}, [])), (field)(*({'name': 'state'}, ['code'])), (field)(*({'name': 'code'}, [code]))] return (record)(*({'id': xmlid, 'model': 'ir.actions.server'}, children)) def client_action_multi(xmlid, # type: Text name, # type: Text model, # type: Text action # type: Text ): # type: (...) -> XMLDictElement """ 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 (record)(*({'id': xmlid, 'model': 'ir.values'}, children)) # Menus def menuitem(*args): # type: (...) -> XMLDictElement return xmln('menuitem', *args) def menuitem_model(model, # type: Text attrs # type: XMLAttrs ): # type: (...) -> XMLDictElement """ 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 menuitem(attrs_clone) # Form aliases def group(*args): # type: (...) -> XMLDictElement return xmln('group', *args) def header(*args): # type: (...) -> XMLDictElement return xmln('header', *args) def footer(*args): # type: (...) -> XMLDictElement return xmln('footer', *args) def sheet(*args): # type: (...) -> XMLDictElement return xmln('sheet', *args) def button(*args): # type: (...) -> XMLDictElement return xmln('button', *args) def p(*args): # type: (...) -> XMLDictElement return xmln('p', *args) def xpath(*args): # type: (...) -> XMLDictElement return xmln('xpath', *args) def attribute(name, # type: Text value # type: Text ): # type: (...) -> XMLDictElement return (xmln)(*('attribute', {'name': name}, [value])) # Fields def field(*args): # type: (...) -> XMLDictElement return xmln('field', *args) def field_name(name # type: Text ): # type: (...) -> XMLDictElement return (field)(*({'name': 'name'}, [name])) def field_model(model # type: Text ): # type: (...) -> XMLDictElement return (field)(*({'name': 'model'}, [model])) def field_inherit(xmlid # type: Text ): # type: (...) -> XMLDictElement return (field)(*({'name': 'inherit_id', 'ref': xmlid}, [])) def field_arch(*args): # type: (...) -> XMLDictElement return ((_coconut.functools.partial(_coconut.functools.partial, field))({'name': 'arch', 'type': 'xml'}))(*args) # Search def filter(*args): # type: (...) -> XMLDictElement return xmln('filter', *args) # Views def view(xmlid, # type: Text children # type: List ): # type: (...) -> XMLDictElement return (record)(*({'id': xmlid, 'model': 'ir.ui.view'}, children)) def view_def(xmlid, # type: Text name, # type: Text model, # type: Text arch # type: List ): # type: (...) -> XMLDictElement return (view)(*(xmlid, [field_name(name), field_model(model), field_arch(arch)])) def view_new(view_type, # type: Text model, # type: Text arch # type: List ): # type: (...) -> XMLDictElement """ View : new view definition, based on type (form, tree, ...) and model ID """ model_und = (model.replace)(*('.', '_')) model_cap = ((' '.join)((list)(map(lambda _=None: _.capitalize(), (model.split)('.'))))) xmlid = "%s_view_%s" % (model_und, view_type) name = (' '.join)((model_cap, view_type.capitalize())) return (view_def)(*(xmlid, name, model, arch)) def view_inherit(filename, # type: Text model, # type: Text inherit, # type: Text arch # type: List ): # type: (...) -> XMLDictElement """ 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)((list)(map(lambda _=None: _.capitalize(), (model.split)('.'))))) name = '%s Adaptations' % model_cap return view(xmlid, [(field_name)(name), (field_model)(model), (field_inherit)(inherit), (field_arch)(arch)])