Example #1
0
    def set_module_python_file(self, module):
        super(CodeGeneratorWriter, self).set_module_python_file(module)
        if not module.theme_website:
            return

        cw = CodeWriter()
        for line in MODEL_HEAD:
            str_line = line.strip()
            cw.emit(str_line)

        cw.emit()
        cw.emit(
            f"class {self._get_class_name(module.name)}(models.AbstractModel):"
        )
        with cw.indent():
            cw.emit("_inherit = 'theme.utils'")
        cw.emit()
        with cw.indent():
            cw.emit(f"def _{module.name}_post_copy(self, mod):")
            with cw.indent():
                cw.emit(
                    "self.disable_view('website_theme_install.customize_modal')"
                )

        file_path = os.path.join(
            self.code_generator_data.models_path, f"{module.name}.py"
        )

        self.code_generator_data.write_file_str(file_path, cw.render())
    def _set_website_snippet_controller_file(self, module):
        """
        Function to set the module hook file
        :param module:
        :return:
        """

        cw = CodeWriter()
        cw.emit("from odoo import http")
        cw.emit("from odoo.http import request")
        cw.emit("")
        cw.emit("")
        cw.emit("class HelloWorldController(http.Controller):")
        cw.emit("")
        with cw.indent():
            cw.emit(
                f"@http.route(['/{module.name}/helloworld'], type='json', auth=\"public\", website=True,"
            )
        with cw.indent():
            with cw.indent():
                with cw.indent():
                    with cw.indent():
                        cw.emit("methods=['POST', 'GET'], csrf=False)")
        with cw.indent():
            cw.emit("def hello_world(self):")
            with cw.indent():
                cw.emit('return {"hello": "Hello World!"}')

        out = cw.render()

        l_model = out.split("\n")

        file_path = f"{self.code_generator_data.controllers_path}/main.py"

        self.code_generator_data.write_file_lst_content(file_path, l_model)
    def generate(self):
        for file_path, lst_info in self.dct_cb.items():
            cw = CodeWriter()
            lst_header = [b for a in lst_info for b in a[0]]
            # Fix divergence import
            try:
                index_pos = lst_header.index("import odoo.http as http")
                lst_header.pop(index_pos)
                lst_header.append("from odoo import http")
            except:
                pass

            set_header = set(lst_header)
            lst_cb = [a[1] for a in lst_info]
            enable_logger = any([a[3] for a in lst_info])
            lst_inherit_class = list(set([a[2] for a in lst_info]))

            if len(lst_inherit_class) > 1:
                _logger.error(
                    "Cannot support multiple class in the same python file:"
                    f" '{lst_inherit_class}', filepath: '{file_path}'")
                continue
            str_inherit_class = lst_inherit_class[0]

            for line in set_header:
                cw.emit(line)

            if enable_logger:
                cw.emit("import logging")
                cw.emit("_logger = logging.getLogger(__name__)")

            cw.emit(
                "class"
                f" {self._module.name.replace('_', ' ').title().replace(' ', '')}Controller({str_inherit_class}):"
            )

            with cw.indent():
                for cb in lst_cb:
                    cb(self._module, cw)

            out = cw.render()

            l_model = out.split("\n")

            self._code_generator_data.write_file_lst_content(
                file_path, l_model)
Example #4
0
    def _set_website_snippet_static_javascript_file(self, module):
        """
        Function to set the module hook file
        :param module:
        :return:
        """
        cw = CodeWriter()
        cw.cur_indent = 4 * cw.default_dent

        if module.generate_website_snippet_generic_model:
            lst_model_search = (
                module.generate_website_snippet_generic_model.split(";")
            )
            lst_model_id_search = []
            for s_model in lst_model_search:
                model_id = self.env["ir.model"].search(
                    [("model", "=", s_model)]
                )
                if model_id:
                    lst_model_id_search.append(model_id[0])
                else:
                    _logger.warning(f"Model not existing : {s_model}")
            for model_id in lst_model_id_search:
                for field_id in model_id.field_id:
                    if field_id.name not in MAGIC_FIELDS:
                        cw.emit(f'if (data["{field_id.name}"]) {{')
                        with cw.indent():
                            with cw.indent():
                                cw.emit(
                                    f'self.$(".{field_id.name}_value").text(data["{field_id.name}"]);'
                                )
                            cw.emit("}")
        else:
            cw.emit("var data_json = data;")
            cw.emit('var hello = data_json["hello"];')
            cw.emit(f'self.$(".{module.name}_value").text(hello);')

        code = cw.render()

        content = (
            f"odoo.define('{module.name}.animation', function (require)"
            """ {
    'use strict';

    var sAnimation = require('website.content.snippets.animation');

    sAnimation.registry."""
            f"{module.name}"
            """ = sAnimation.Class.extend({
        """
            f"selector: '.o_{module.name}',"
            """

        start: function () {
            var self = this;
            var def = this._rpc({route: '"""
            f"/{module.name}/helloworld"
            """'}).then(function (data) {

                if (data.error) {
                    return;
                }

                if (_.isEmpty(data)) {
                    return;
                }

"""
            + code
            + """    
            });

            return $.when(this._super.apply(this, arguments), def);
        }
    })
});
        """
        )

        file_path = os.path.join(
            "static", "src", "js", f"website.{module.name}.animation.js"
        )
        self.code_generator_data.write_file_str(file_path, content)
def main():
    config = get_config()
    cw = CodeWriter()

    mydoc = minidom.parse(config.file)
    if not mydoc:
        print(f"Error, cannot parse {config.file}")
        sys.exit(1)

    cw.emit("from lxml.builder import E")
    cw.emit("from lxml import etree as ET")
    cw.emit("from code_writer import CodeWriter")
    cw.emit("")
    cw.emit('print(\'<?xml version="1.0" encoding="utf-8"?>\')')
    cw.emit('print("<odoo>")')

    lst_function = []
    comment_for_next_group = None

    for odoo in mydoc.getElementsByTagName("odoo"):
        for ir_view_item in odoo.childNodes:
            if ir_view_item.nodeType == Node.ELEMENT_NODE:
                # Show part of xml
                fct_name = "ma_fonction"
                lst_function.append(fct_name)
                cw.emit(f"def {fct_name}():")
                with cw.indent():
                    cw.emit('"""')
                    for line in transform_string_to_list(
                        ir_view_item.toprettyxml()
                    ):
                        cw.emit(line)
                    cw.emit('"""')
                    # Show comment
                    if comment_for_next_group:
                        cw.emit(
                            "print('<!--"
                            f" {comment_for_next_group.strip()} -->')"
                        )
                        comment_for_next_group = None
                    attributes_root = dict(ir_view_item.attributes.items())

                    lst_out = code_writer_deep_xml(ir_view_item)

                    generate_code = GenerateCode()
                    generate_code.generate_code(lst_out)
                    child_root = generate_code.result

                    code = (
                        "root ="
                        f" E.{ir_view_item.tagName}({str(attributes_root)},"
                        f" {child_root})"
                    )

                    for line in code.split("\n"):
                        cw.emit(line)

                    cw.emit("content = ET.tostring(root, pretty_print=True)")
                    cw.emit()
                    cw.emit("cw = CodeWriter()")
                    cw.emit(
                        'for line in content.decode("utf-8").split("\\n"):'
                    )
                    with cw.indent():
                        cw.emit("with cw.indent():")
                        with cw.indent():
                            cw.emit("cw.emit(line)")
                    cw.emit("print(cw.render())")
                cw.emit(f"{fct_name}()")
            elif ir_view_item.nodeType == Node.COMMENT_NODE:
                comment_for_next_group = ir_view_item.data
            else:
                # print(ir_view_item)
                pass

    cw.emit('print("</odoo>")')

    output = cw.render()
    if config.output:
        with open(config.output, "w") as file:
            file.write(output)
    else:
        print(output)
    def _set_website_leaflet_controller_file(self, module):
        """
        Function to set the module hook file
        :param module:
        :return:
        """

        lst_fields = []
        lst_model = []
        for a in module.o2m_models:
            active_id = a.field_id.filtered(lambda key: key.name == "active")
            open_popup_id = a.field_id.filtered(
                lambda key: key.name == "open_popup")
            html_text_id = a.field_id.filtered(
                lambda key: key.name == "html_text")
            fields_id = a.field_id.filtered(
                lambda key: "geo_" in key.ttype).sorted(key="name")
            if fields_id:
                lst_model.append(a)
                lst_fields = [b for b in fields_id]
                # Find right model
                break
        if not len(lst_fields):
            return
        # Cannot support multiple model with field geo
        assert len(lst_model) == 1
        model_id = lst_model[0]

        cw = CodeWriter()
        cw.emit("from odoo import http")
        cw.emit("from operator import attrgetter")
        cw.emit("import json")
        cw.emit("import numpy")
        cw.emit("from pyproj import Transformer")
        cw.emit("from odoo.http import request")
        cw.emit("from collections import defaultdict")
        cw.emit("")
        cw.emit("")
        cw.emit("class MapFeatureController(http.Controller):")
        cw.emit("")
        with cw.indent():
            cw.emit(
                f"@http.route(['/{module.name}/map/config'], type='json', auth=\"public\", website=True,"
            )
        with cw.indent():
            with cw.indent():
                with cw.indent():
                    with cw.indent():
                        cw.emit("methods=['POST', 'GET'], csrf=False)")
        with cw.indent():
            cw.emit("def map_detail(self):")
            with cw.indent():
                cw.emit('name = "test"')
                cw.emit("lat = 45.587134")
                cw.emit("lng = -73.733368")
                cw.emit("enable = True")
                cw.emit("size_width = 800")
                cw.emit("size_height = 600")
                cw.emit('provider = "CartoDB"')
                cw.emit("zoom = 13")
                cw.emit("categories = {}")
                # cw.emit(f"for i in http.request.env['{model_id.model}'].search([[\"active\", \"=\", True]]):")
                # with cw.indent():
                #     cw.emit("categories[i.id] = {")
                #     with cw.indent():
                #         cw.emit("\"name\": i.name,")
                #         cw.emit("\"description\": i.description,")
                # with cw.indent():
                #     cw.emit("}")
            with cw.indent():
                cw.emit("features = defaultdict(list)")
                cw.emit(
                    'transformer = Transformer.from_crs("epsg:3857", "epsg:4326")'
                )
            cw.emit("")
            with cw.indent():
                str_search = ""
                if active_id:
                    str_search = '("active", "=", True)'
                cw.emit(
                    f'map_feature_ids = request.env["{model_id.model}"].sudo().search([{str_search}])'
                )
                cw.emit("for feature in map_feature_ids:")
                with cw.indent():
                    cw.emit("value = {}")
                    cw.emit("# Help robot, ignore this")
                    cw.emit("if False:")
                    with cw.indent():
                        cw.emit("pass")
                    for field_id in lst_fields:
                        cw.emit(f'elif feature.type == "{field_id.name}":')
                        with cw.indent():
                            cw.emit(f"if not feature.{field_id.name}:")
                            with cw.indent():
                                cw.emit(f"continue")
                            if field_id.ttype == "geo_polygon":
                                cw.emit(
                                    f"xy = feature.{field_id.name}.exterior.coords.xy"
                                )
                            else:
                                cw.emit(f"xy = feature.{field_id.name}.xy")
            cw.emit("")
            with cw.indent():
                with cw.indent():
                    cw.emit("coord_UTM = numpy.column_stack(xy).tolist()")
                    cw.emit(
                        "coord_lat_long = [transformer.transform(*i) for i in coord_UTM]"
                    )
            # cw.emit("")
            with cw.indent():
                # with cw.indent():
                #     cw.emit("if feature.category_id:")
                #     with cw.indent():
                #         cw.emit("value[\"category_id\"] = feature.category_id.id")
                if open_popup_id:
                    with cw.indent():
                        cw.emit("if feature.open_popup:")
                        with cw.indent():
                            cw.emit('value["open_popup"] = feature.open_popup')
                if html_text_id:
                    with cw.indent():
                        cw.emit("if feature.html_text:")
                        with cw.indent():
                            cw.emit('value["html_popup"] = feature.html_text')
            cw.emit("")
            with cw.indent():
                with cw.indent():
                    cw.emit("# Help robot, ignore this")
                    cw.emit("if False:")
                    with cw.indent():
                        cw.emit("pass")
                for field_id in lst_fields:
                    with cw.indent():
                        cw.emit(f'elif feature.type == "{field_id.name}":')
                        with cw.indent():
                            if field_id.ttype == "geo_point":
                                cw.emit(
                                    'value["coordinates"] = coord_lat_long[0]')
                                cw.emit('features["markers"].append(value)')
                            else:
                                cw.emit(
                                    'value["coordinates"] = coord_lat_long')
                                if field_id.ttype == "geo_polygon":
                                    cw.emit('features["areas"].append(value)')
                                elif field_id.ttype == "geo_line":
                                    cw.emit('features["lines"].append(value)')
            cw.emit("")
        with cw.indent():
            with cw.indent():
                cw.emit("return {")
                with cw.indent():
                    cw.emit('"name": name,')
                    cw.emit('"lat": lat,')
                    cw.emit('"lng": lng,')
                    cw.emit('"enable": enable,')
                    cw.emit('"size_width": size_width,')
                    cw.emit('"size_height": size_height,')
                    cw.emit('"zoom": zoom,')
                    cw.emit('"provider": provider,')
                    cw.emit('"features": features,')
                    cw.emit('"categories": categories,')
            with cw.indent():
                cw.emit("}")

        out = cw.render()

        l_model = out.split("\n")

        file_path = f"{self.code_generator_data.controllers_path}/main.py"

        self.code_generator_data.write_file_lst_content(file_path, l_model)
    def set_module_css_file(self, module):
        super(CodeGeneratorWriter, self).set_module_css_file(module)
        if not module.theme_website:
            return

        # _variables.scss files
        cw = CodeWriter(default_width=80)
        # cw.emit(f"$primary: {module.theme_website_primary_color} !default;")
        # cw.emit(f"$secondary: {module.theme_website_secondary_color} !default;")
        # cw.emit(f"$body-color: {module.theme_website_body_color} !default;")
        file_path = os.path.join(self.code_generator_data.css_path, "_variables.scss")
        self.code_generator_data.write_file_str(file_path, cw.render())

        # custom.scss files
        cw = CodeWriter()
        file_path = os.path.join(self.code_generator_data.css_path, "custom.scss")
        self.code_generator_data.write_file_str(file_path, cw.render())

        # primary_variables.scss files
        cw = CodeWriter()
        file_path = os.path.join(self.code_generator_data.css_path, "primary_variables.scss")
        cw.emit("$o-theme-layout: 'full';")
        cw.emit("//$o-theme-navbar-height: 300px;")
        cw.emit()
        cw.emit("//" + "-" * 78)
        cw.emit_wrapped_text(
            "Colors",
            prefix="// ",
            indent_after_first=True,
        )
        cw.emit("//" + "-" * 78)
        cw.emit()
        cw.emit("// Extend default color palettes with website-related colors")
        cw.emit("$-palettes: ();")
        cw.emit("@each $palette in $o-color-palettes {")
        with cw.indent():
            cw.emit("$-palettes: append($-palettes, map-merge((")
            with cw.indent():
                cw.emit(f"'body': {module.theme_website_body_color},")
                cw.emit(f"'menu': {module.theme_website_menu_color},")
                cw.emit(f"'footer': {module.theme_website_footer_color},")
                cw.emit(f"'text': {module.theme_website_text_color},")
                cw.emit(f"'alpha': {module.theme_website_primary_color},")
                cw.emit(f"'beta': {module.theme_website_secondary_color},")
                cw.emit(f"'gamma': {module.theme_website_extra_1_color},")
                cw.emit(f"'delta': {module.theme_website_extra_2_color},")
                cw.emit(f"'epsilon': {module.theme_website_extra_3_color},")
                cw.emit(f"'h1': null, // Default to text")
                cw.emit(f"'h2': null, // Default to h1")
                cw.emit(f"'h3': null, // Default to h2")
                cw.emit(f"'h4': null, // Default to h3")
                cw.emit(f"'h5': null, // Default to h4")
                cw.emit(f"'h6': null, // Default to h5")
            cw.emit("), $palette));")
        cw.emit("}")
        cw.emit()
        cw.emit("$o-color-palettes: $-palettes;")
        cw.emit()
        cw.emit("$o-theme-color-palettes: ();")
        cw.emit("@each $-palette in $-palettes {")
        with cw.indent():
            cw.emit(
                "$o-theme-color-palettes: append($o-theme-color-palettes, map-merge($-palette, ("
            )
            with cw.indent():
                cw.emit("'primary': map-get($-palette, 'alpha'),")
                cw.emit("'secondary': map-get($-palette, 'beta'),")
            cw.emit(")));")
        cw.emit("}")
        cw.emit()
        cw.emit("// By default, all user color palette values are null. Each null value is")
        cw.emit("// automatically replaced with corresponding color of chosen color palette.")
        cw.emit("$o-user-color-palette: () !default;")
        cw.emit()
        cw.emit("// By default, all user theme color palette values are null. Each null value")
        cw.emit("// is automatically replaced with corresponding color of chosen theme color")
        cw.emit("// palette.")
        cw.emit("$o-user-theme-color-palette: () !default;")
        cw.emit()
        cw.emit("//" + "-" * 78)
        cw.emit_wrapped_text(
            "Fonts",
            prefix="// ",
            indent_after_first=True,
        )
        cw.emit("//" + "-" * 78)
        cw.emit()
        cw.emit("$o-theme-fonts: (")
        with cw.indent():
            cw.emit(
                '(-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Noto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"), // This is BS default'
            )
            cw.emit("('Open Sans', sans-serif),")
            cw.emit("('Source Sans Pro', sans-serif),")
            cw.emit("('Raleway', sans-serif),")
            cw.emit("('Noto Serif', serif),")
            cw.emit("('Arvo', Times, serif),")
        cw.emit(") !default;")
        cw.emit("$o-theme-font-urls: (")
        with cw.indent():
            cw.emit("null,")
            cw.emit("'Open+Sans:400,400i,700,700i',")
            cw.emit("'Source+Sans+Pro:400,400i,700,700i',")
            cw.emit("'Raleway:400,400i,700,700i',")
            cw.emit("'Noto+Serif:400,400i,700,700i',")
            cw.emit("'Arvo:400,400i,700,700i',")
        cw.emit(") !default;")
        cw.emit("$o-theme-font-names: (")
        with cw.indent():
            cw.emit("'Bootstrap',")
            cw.emit("'Open Sans',")
            cw.emit("'Source Sans Pro',")
            cw.emit("'Raleway',")
            cw.emit("'Noto Serif',")
            cw.emit("'Arvo',")
        cw.emit(") !default;")
        cw.emit("$o-theme-font-number: 1 !default;")
        cw.emit("$o-theme-headings-font-number: 1 !default;")
        cw.emit("$o-theme-buttons-font-number: 1 !default;")
        cw.emit("$o-theme-navbar-font-number: 1 !default;")
        self.code_generator_data.write_file_str(file_path, cw.render())
Example #8
0
    def _set_portal_controller_file(self, module):
        """
        Function to set the module hook file
        :param module:
        :return:
        """

        cw = CodeWriter()
        cw.emit("from collections import OrderedDict")
        cw.emit("from operator import itemgetter")
        cw.emit("")
        cw.emit("from odoo import http, _")
        cw.emit("from odoo.exceptions import AccessError, MissingError")
        cw.emit("from odoo.http import request")
        cw.emit(
            "from odoo.addons.portal.controllers.portal import CustomerPortal, pager as portal_pager"
        )
        cw.emit("from odoo.tools import groupby as groupbyelem")
        cw.emit("")
        cw.emit("from odoo.osv.expression import OR")
        cw.emit("")
        cw.emit("")
        cw.emit("class CustomerPortal(CustomerPortal):")
        cw.emit("")
        with cw.indent():
            cw.emit("def _prepare_portal_layout_values(self):")
            with cw.indent():
                cw.emit("values = super(CustomerPortal, self)._prepare_portal_layout_values()")
                for model in module.o2m_models:
                    cw.emit(
                        f"values['{self._fmt_underscores(model.model)}_count'] = request.env['{model.model}']."
                        f"search_count([])"
                    )
                cw.emit("return values")
        cw.emit("")

        for model in module.o2m_models:
            has_group_by = False
            with cw.indent():
                cw.emit("# ------------------------------------------------------------")
                cw.emit(f"# My {self._fmt_title(model.model)}")
                cw.emit("# ------------------------------------------------------------")
                cw.emit(
                    f"def _{self._fmt_underscores(model.model)}_get_page_view_values(self, {self._fmt_underscores(model.model)}, "
                    f"access_token, **kwargs):"
                )
                with cw.indent():
                    cw.emit("values = {")
                    with cw.indent():
                        cw.emit(f"'page_name': '{self._fmt_underscores(model.model)}',")
                        cw.emit(
                            f"'{self._fmt_underscores(model.model)}': {self._fmt_underscores(model.model)},"
                        )
                        # MATHBEN ADDED
                        cw.emit("'user': request.env.user")
                with cw.indent():
                    cw.emit("}")
                    cw.emit(
                        f"return self._get_page_view_values({self._fmt_underscores(model.model)}, access_token, values, "
                        f"'my_{self._fmt_underscores(model.model)}s_history', False, **kwargs)"
                    )
            cw.emit("")
            with cw.indent():
                cw.emit(
                    f"@http.route(['/my/{self._fmt_underscores(model.model)}s', "
                    f"'/my/{self._fmt_underscores(model.model)}s/page/<int:page>'], type='http', auth=\"user\", "
                    f"website=True)"
                )
                # cw.emit(f"def portal_my_{_fmt_underscores(model.model)}s(self, page=1, date_begin=None, date_end=None, "
                #         f"sortby=None, **kw):")
                # MATHBEN ADDED
                cw.emit(
                    f"def portal_my_{self._fmt_underscores(model.model)}s(self, page=1, date_begin=None, date_end=None, "
                    f"sortby=None, filterby=None, search=None, search_in='content', **kw):"
                )
                # MATHBEN NEED THIS FOR NEXT MODEL IF ONE DEPEND TO ANOTHER ONE
                # f"sortby=None, filterby=None, search=None, search_in='content', groupby='project', **kw):")
                with cw.indent():
                    cw.emit("values = self._prepare_portal_layout_values()")
                    cw.emit(f"{self._fmt_camel(model.model)} = request.env['{model.model}']")
                    cw.emit("domain = []")
            cw.emit("")
            with cw.indent():
                with cw.indent():
                    cw.emit("searchbar_sortings = {")
                    with cw.indent():
                        cw.emit("'date': {'label': _('Newest'), 'order': 'create_date desc'},")
                        cw.emit("'name': {'label': _('Name'), 'order': 'name'},")
                        # MATHBEN NEEDED BY TASK
                        # cw.emit("'name': {'label': _('Title'), 'order': 'name'},")
                        # cw.emit("'stage': {'label': _('Stage'), 'order': 'stage_id'},")
                        # cw.emit("'update': {'label': _('Last Stage Update'), 'order': 'date_last_stage_update desc'},")
                with cw.indent():
                    cw.emit("}")
                    cw.emit("searchbar_filters = {")
                    with cw.indent():
                        cw.emit("'all': {'label': _('All'), 'domain': []},")
                with cw.indent():
                    cw.emit("}")
                    cw.emit("searchbar_inputs = {")
                    # MATHBEN REMOVED, WAS in task
                    # with cw.indent():
                    #     cw.emit(
                    #         "'content': {'input': 'content', 'label': _('Search <span class=\"nolabel\"> (in Content)</span>')},")
                    #     cw.emit("'message': {'input': 'message', 'label': _('Search in Messages')},")
                    #     cw.emit("'customer': {'input': 'customer', 'label': _('Search in Customer')},")
                    #     cw.emit("'stage': {'input': 'stage', 'label': _('Search in Stages')},")
                    #     cw.emit("'all': {'input': 'all', 'label': _('Search in All')},")
                with cw.indent():
                    cw.emit("}")
                    cw.emit("searchbar_groupby = {")
                    # MATHBEN REMOVED, WAS in task
                    # with cw.indent():
                    #     cw.emit("'none': {'input': 'none', 'label': _('None')},")
                    #     cw.emit("'project': {'input': 'project', 'label': _('Project')},")
                with cw.indent():
                    cw.emit("}")
            cw.emit("")
            with cw.indent():
                with cw.indent():
                    pass
                    # MATHBEN WAS FOR TASK NOT USE IN PROJECT
                    # cw.emit("# extends filterby criteria with project the customer has access to")
                    # cw.emit("projects = request.env['project.project'].search([])")
                    # cw.emit("for project in projects:")
                    # with cw.indent():
                    #     cw.emit("searchbar_filters.update({")
                    #     with cw.indent():
                    #         cw.emit(
                    #             "str(project.id): {'label': project.name, 'domain': [('project_id', '=', project.id)]}")
                    # with cw.indent():
                    #     cw.emit("})")
            pass
            # cw.emit("")
            # with cw.indent():
            #     with cw.indent():
            #         cw.emit("# extends filterby criteria with project (criteria name is the project id)")
            #         cw.emit("# Note: portal users can't view projects they don't follow")
            #         cw.emit(
            #             "project_groups = request.env['project.task'].read_group([('project_id', 'not in', projects.ids)], "
            #             "['project_id'], ['project_id'])")
            #     with cw.indent():
            #         cw.emit("for group in project_groups:")
            #         with cw.indent():
            #             cw.emit("proj_id = group['project_id'][0] if group['project_id'] else False")
            #             cw.emit("proj_name = group['project_id'][1] if group['project_id'] else _('Others')")
            #             cw.emit("searchbar_filters.update({")
            #             with cw.indent():
            #                 cw.emit("str(proj_id): {'label': proj_name, 'domain': [('project_id', '=', proj_id)]}")
            #         with cw.indent():
            #             cw.emit("})")
            # cw.emit("")
            with cw.indent():
                with cw.indent():
                    cw.emit("# default sort by value")
                    cw.emit("if not sortby:")
                    with cw.indent():
                        cw.emit("sortby = 'date'")
                with cw.indent():
                    cw.emit("order = searchbar_sortings[sortby]['order']")
                    cw.emit("# default filter by value")
                    cw.emit("if not filterby:")
                    with cw.indent():
                        cw.emit("filterby = 'all'")
                with cw.indent():
                    cw.emit("domain = searchbar_filters[filterby]['domain']")
            cw.emit("")
            with cw.indent():
                with cw.indent():
                    cw.emit("# search")
                    cw.emit("if search and search_in:")
                    with cw.indent():
                        cw.emit("search_domain = []")
                    pass
                    # MATHBEN REMOVE IT, NOT USED IN PROJECT
                    #     cw.emit("if search_in in ('content', 'all'):")
                    #     with cw.indent():
                    #         cw.emit(
                    #             "search_domain = OR([search_domain, ['|', ('name', 'ilike', search), ('description', 'ilike', search)]])")
                    # with cw.indent():
                    #     cw.emit("if search_in in ('customer', 'all'):")
                    #     with cw.indent():
                    #         cw.emit("search_domain = OR([search_domain, [('partner_id', 'ilike', search)]])")
                    # with cw.indent():
                    #     cw.emit("if search_in in ('message', 'all'):")
                    #     with cw.indent():
                    #         cw.emit("search_domain = OR([search_domain, [('message_ids.body', 'ilike', search)]])")
                    # with cw.indent():
                    #     cw.emit("if search_in in ('stage', 'all'):")
                    #     with cw.indent():
                    #         cw.emit("search_domain = OR([search_domain, [('stage_id', 'ilike', search)]])")
                    with cw.indent():
                        cw.emit("domain += search_domain")
            with cw.indent():
                with cw.indent():
                    cw.emit("# archive groups - Default Group By 'create_date'")
                    cw.emit(f"archive_groups = self._get_archive_groups('{model.model}', domain)")
                    cw.emit("if date_begin and date_end:")
                    with cw.indent():
                        cw.emit(
                            "domain += [('create_date', '>', date_begin), ('create_date', '<=', date_end)]"
                        )
                with cw.indent():
                    cw.emit(f"# {self._fmt_underscores(model.model)}s count")
                    cw.emit(
                        f"{self._fmt_underscores(model.model)}_count = {self._fmt_camel(model.model)}.search_count(domain)"
                    )
                    cw.emit("# pager")
                    cw.emit("pager = portal_pager(")
                    with cw.indent():
                        cw.emit(f'url="/my/{self._fmt_underscores(model.model)}s",')
                        cw.emit(
                            "url_args={'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby, 'filterby': "
                            "filterby, 'search_in': search_in, 'search': search},"
                        )
                        cw.emit(f"total={self._fmt_underscores(model.model)}_count,")
                        cw.emit("page=page,")
                        cw.emit("step=self._items_per_page")
                with cw.indent():
                    cw.emit(")")
                    cw.emit("# content according to pager and archive selected")
                    # MATHBEN NOT IN PROJECT, BUT TASK
                    # cw.emit("if groupby == 'project':")
                    # with cw.indent():
                    #     cw.emit("order = \"project_id, %s\" % order  "
                    #             "# force sort on project first to group by project in view")
            cw.emit("")
            with cw.indent():
                with cw.indent():
                    cw.emit("# content according to pager and archive selected")
                    cw.emit(
                        f"{self._fmt_underscores(model.model)}s = {self._fmt_camel(model.model)}.search(domain, order=order, "
                        f"limit=self._items_per_page, offset=pager['offset'])"
                    )
                    # MATHBEN LAST LINE, TASK WAS offset=(page - 1) * self._items_per_page
                    cw.emit(
                        f"request.session['my_{self._fmt_underscores(model.model)}s_history'] = "
                        f"{self._fmt_underscores(model.model)}s.ids[:100]"
                    )
                    # MATHBEN NEXT BLOCK 43 COMMENT TO NEXT LINE
                    # cw.emit("if groupby == 'project':")
                    # with cw.indent():
                    #     cw.emit(
                    #         "grouped_tasks = [request.env['project.task'].concat(*g) for k, g in groupbyelem(tasks, itemgetter('project_id'))]")
                pass
                # with cw.indent():
                #     cw.emit("else:")
                #     with cw.indent():
                #         cw.emit("grouped_tasks = [tasks]")
                # MATHBEN END BLOCK 43
            cw.emit("")
            with cw.indent():
                with cw.indent():
                    cw.emit("values.update({")
                    with cw.indent():
                        cw.emit("'date': date_begin,")
                        cw.emit("'date_end': date_end,")
                        # MATHBEN WAS IN TASK
                        # cw.emit("'grouped_tasks': grouped_tasks,")
                        # GROUPED_TASKS CAN REPLACE PROJECTS
                        cw.emit(
                            f"'{self._fmt_underscores(model.model)}s': {self._fmt_underscores(model.model)}s,"
                        )
                        cw.emit(f"'page_name': '{self._fmt_underscores(model.model)}',")
                        cw.emit("'archive_groups': archive_groups,")
                        cw.emit(f"'default_url': '/my/{self._fmt_underscores(model.model)}s',")
                        cw.emit("'pager': pager,")
                        cw.emit("'searchbar_sortings': searchbar_sortings,")
                        cw.emit("'searchbar_groupby': searchbar_groupby,")
                        cw.emit("'searchbar_inputs': searchbar_inputs,")
                        cw.emit("'search_in': search_in,")
                        if has_group_by:
                            cw.emit("'groupby': groupby,")
                        cw.emit(
                            "'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())),"
                        )
                        cw.emit("'sortby': sortby,")
                        cw.emit("'filterby': filterby,")
                with cw.indent():
                    cw.emit("})")
                    cw.emit(
                        f'return request.render("{module.name}.portal_my_{self._fmt_underscores(model.model)}s", values)'
                    )
            cw.emit("")
            with cw.indent():
                cw.emit(
                    f"@http.route(['/my/{self._fmt_underscores(model.model)}/<int:{self._fmt_underscores(model.model)}_id>'], "
                    f"type='http', auth=\"public\", website=True)"
                )
                cw.emit(
                    f"def portal_my_{self._fmt_underscores(model.model)}(self, {self._fmt_underscores(model.model)}_id=None, "
                    f"access_token=None, **kw):"
                )
                with cw.indent():
                    cw.emit("try:")
                    with cw.indent():
                        cw.emit(
                            f"{self._fmt_underscores(model.model)}_sudo = self._document_check_access('{model.model}', "
                            f"{self._fmt_underscores(model.model)}_id, access_token)"
                        )
                with cw.indent():
                    cw.emit("except (AccessError, MissingError):")
                    with cw.indent():
                        cw.emit("return request.redirect('/my')")
            cw.emit("")
            with cw.indent():
                with cw.indent():
                    if "attachment_ids" in [a.name for a in model.field_id]:
                        cw.emit(
                            "# ensure attachment are accessible with access token inside template"
                        )
                        cw.emit(
                            f"for attachment in {self._fmt_underscores(model.model)}_sudo.attachment_ids:"
                        )
                        with cw.indent():
                            cw.emit("attachment.generate_access_token()")
                with cw.indent():
                    cw.emit(
                        f"values = self._{self._fmt_underscores(model.model)}_get_page_view_values("
                        f"{self._fmt_underscores(model.model)}_sudo, access_token, **kw)"
                    )
                    cw.emit(
                        f'return request.render("{module.name}.portal_my_{self._fmt_underscores(model.model)}", values)'
                    )
            cw.emit("")

        out = cw.render()

        l_model = out.split("\n")

        file_path = f"{self.code_generator_data.controllers_path}/portal.py"

        self.code_generator_data.write_file_lst_content(file_path, l_model)