Ejemplo n.º 1
0
    def _column_to_field(column):
        def _get_xpath(col):
            def _get_conditional(condition, if_true, if_false):
                return 'if({condition}, {if_true}, {if_false})'.format(
                    condition=condition,
                    if_true=if_true,
                    if_false=if_false,
                )

            def _get_word_eval(word_translations, default_value):
                word_eval = default_value
                for lang, translation in word_translations.items():
                    word_eval = _get_conditional(
                        "$lang = '{lang}'".format(lang=lang, ),
                        "'{translation}'".format(
                            translation=translation.replace("'", "''"), ),
                        word_eval)
                return word_eval

            try:
                transform = col['transform']
            except KeyError:
                transform = {}

            if transform.get('type') == 'translation':
                if new_mobile_ucr_restore:
                    default_val = "{column_id}"
                else:
                    default_val = "column[@id='{column_id}']"
                xpath_function = default_val
                for word, translations in transform['translations'].items():
                    if isinstance(translations, str):
                        # This is a flat mapping, not per-language translations
                        word_eval = "'{}'".format(translations)
                    else:
                        word_eval = _get_word_eval(translations, default_val)
                    xpath_function = _get_conditional(
                        "{value} = '{word}'".format(
                            value=default_val,
                            word=word,
                        ), word_eval, xpath_function)
                return Xpath(
                    function=xpath_function.format(column_id=col.column_id),
                    variables=[
                        XpathVariable(name='lang', locale_id='lang.current')
                    ],
                )
            else:
                if new_mobile_ucr_restore:
                    return Xpath(function="{}".format(col.column_id), )
                else:
                    return Xpath(function="column[@id='{}']".format(
                        col.column_id), )

        return Field(
            header=Header(
                text=Text(locale=Locale(id=id_strings.report_column_header(
                    config.uuid, column.column_id)), )),
            template=Template(text=Text(xpath=_get_xpath(column), )),
        )
Ejemplo n.º 2
0
 def _get_report_context_tile_detail():
     from corehq.apps.app_manager.suite_xml.features.mobile_ucr import MOBILE_UCR_TILE_DETAIL_ID
     return Detail(
         id=MOBILE_UCR_TILE_DETAIL_ID,
         title=Text(),
         fields=[
             Field(
                 style=Style(
                     horz_align="left",
                     font_size="small",
                     grid_height=1,
                     grid_width=12,
                     grid_x=0,
                     grid_y=0,
                 ),
                 header=Header(text=Text()),
                 template=Template(text=Text(xpath=Xpath(
                     function=
                     "concat($message, ' ', format-date(date(instance('commcare-reports:index')/report_index/reports/@last_update), '%e/%n/%Y'))",
                     variables=[
                         XpathVariable(
                             name='message',
                             locale_id=id_strings.reports_last_updated_on())
                     ],
                 ))),
             )
         ])
Ejemplo n.º 3
0
    def _get_graph_fields():
        from corehq.apps.userreports.reports.specs import MultibarChartSpec
        from corehq.apps.app_manager.models import GraphConfiguration, GraphSeries

        def _locale_config(key):
            return id_strings.mobile_ucr_configuration(
                module,
                config.uuid,
                key
            )

        def _locale_series_config(index, key):
            return id_strings.mobile_ucr_series_configuration(
                module,
                config.uuid,
                index,
                key
            )

        def _locale_annotation(index):
            return id_strings.mobile_ucr_annotation(
                module,
                config.uuid,
                index
            )


        for chart_config in config.report(domain).charts:
            if isinstance(chart_config, MultibarChartSpec):
                graph_config = config.complete_graph_configs.get(chart_config.chart_id, GraphConfiguration(
                    series=[GraphSeries() for c in chart_config.y_axis_columns],
                ))

                # Reconcile graph_config.series with any additions/deletions in chart_config.y_axis_columns
                while len(chart_config.y_axis_columns) > len(graph_config.series):
                    graph_config.series.append(GraphSeries())
                if len(chart_config.y_axis_columns) < len(graph_config.series):
                    graph_config.series = graph_config.series[:len(chart_config.y_axis_columns)]

                for index, column in enumerate(chart_config.y_axis_columns):
                    graph_config.series[index].data_path = (
                        graph_config.series[index].data_path or
                        get_data_path(config, domain, new_mobile_ucr_restore)
                    )
                    graph_config.series[index].x_function = (
                        graph_config.series[index].x_function
                        or _get_column_xpath_template(new_mobile_ucr_restore).format(chart_config.x_axis_column)
                    )
                    graph_config.series[index].y_function = (
                        graph_config.series[index].y_function
                        or _get_column_xpath_template(new_mobile_ucr_restore).format(column.column_id)
                    )
                yield Field(
                    header=Header(text=Text()),
                    template=GraphTemplate.build('graph', graph_config,
                                                 locale_config=_locale_config,
                                                 locale_series_config=_locale_series_config,
                                                 locale_annotation=_locale_annotation)
                )
Ejemplo n.º 4
0
def _get_select_details(config):
    return models.Detail(custom_xml=Detail(
        id=_get_select_detail_id(config),
        title=Text(locale=Locale(id=id_strings.report_menu()), ),
        fields=[
            Field(
                header=Header(text=Text(locale=Locale(
                    id=id_strings.report_name_header()), )),
                template=Template(text=Text(locale=Locale(
                    id=id_strings.report_name(config.uuid)))),
            )
        ]).serialize().decode('utf-8'))
Ejemplo n.º 5
0
 def get_select_details(config, filter_slug, domain):
     return models.Detail(custom_xml=Detail(
         id=_MobileSelectFilterHelpers.get_select_detail_id(
             config, filter_slug),
         title=Text(config.report(domain).get_ui_filter(filter_slug).label),
         fields=[
             Field(
                 header=Header(text=Text(
                     config.report(domain).get_ui_filter(
                         filter_slug).label)),
                 template=Template(text=Text(xpath_function='.')),
             )
         ]).serialize())
Ejemplo n.º 6
0
    def _column_to_field(column):
        def _get_xpath(col):
            def _get_conditional(condition, if_true, if_false):
                return u'if({condition}, {if_true}, {if_false})'.format(
                    condition=condition,
                    if_true=if_true,
                    if_false=if_false,
                )

            def _get_word_eval(word_translations, default_value):
                word_eval = default_value
                for lang_translation_pair in word_translations:
                    lang = lang_translation_pair[0]
                    translation = lang_translation_pair[1]
                    word_eval = _get_conditional(
                        "$lang = '{lang}'".format(lang=lang, ),
                        u"'{translation}'".format(
                            translation=translation.replace("'", "''"), ),
                        word_eval)
                return word_eval

            transform = col['transform']
            if transform.get('type') == 'translation':
                default_val = "column[@id='{column_id}']"
                xpath_function = default_val
                for word, translations in transform['translations'].items():
                    xpath_function = _get_conditional(
                        u"{value} = '{word}'".format(
                            value=default_val,
                            word=word,
                        ), _get_word_eval(translations, default_val),
                        xpath_function)
                return Xpath(
                    function=xpath_function.format(column_id=col.column_id),
                    variables=[
                        XpathVariable(name='lang', locale_id='lang.current')
                    ],
                )
            else:
                return Xpath(function="column[@id='{}']".format(
                    col.column_id), )

        return Field(
            header=Header(
                text=Text(locale=Locale(id=id_strings.report_column_header(
                    config.uuid, column.column_id)), )),
            template=Template(text=Text(xpath=_get_xpath(column), )),
        )
Ejemplo n.º 7
0
 def _get_fixture_detail(module):
     d = Detail(
         id=id_strings.fixture_detail(module),
         title=Text(),
     )
     xpath = Xpath(function=module.fixture_select.display_column)
     if module.fixture_select.localize:
         template_text = Text(locale=Locale(child_id=Id(xpath=xpath)))
     else:
         template_text = Text(
             xpath_function=module.fixture_select.display_column)
     fields = [Field(header=Header(text=Text()),
                     template=Template(text=template_text),
                     sort_node='')]
     d.fields = fields
     return d
Ejemplo n.º 8
0
 def _get_persistent_case_context_detail(module, xml):
     return Detail(id=id_strings.persistent_case_context_detail(module),
                   title=Text(),
                   fields=[
                       Field(
                           style=Style(
                               horz_align="center",
                               font_size="large",
                               grid_height=1,
                               grid_width=12,
                               grid_x=0,
                               grid_y=0,
                           ),
                           header=Header(text=Text()),
                           template=Template(text=Text(xpath_function=xml)),
                       )
                   ])
Ejemplo n.º 9
0
    def _get_graph_fields():
        from corehq.apps.userreports.reports.specs import MultibarChartSpec
        # todo: make this less hard-coded
        for chart_config in config.report(domain).charts:
            if isinstance(chart_config, MultibarChartSpec):
                graph_config = config.graph_configs.get(
                    chart_config.chart_id, ReportGraphConfig())

                def _column_to_series(column):
                    return Series(nodeset=(
                        "instance('reports')/reports/report[@id='{}']/rows/row[@is_total_row='False']{}"
                        .format(
                            config.uuid,
                            _MobileSelectFilterHelpers.get_data_filter_xpath(
                                config, domain))),
                                  x_function="column[@id='{}']".format(
                                      chart_config.x_axis_column),
                                  y_function="column[@id='{}']".format(column),
                                  configuration=ConfigurationGroup(configs=[
                                      ConfigurationItem(id=key,
                                                        xpath_function=value)
                                      for key, value in graph_config.
                                      series_configs.get(column, {}).items()
                                  ]))

                yield Field(
                    header=Header(text=Text()),
                    template=GraphTemplate(
                        form='graph',
                        graph=Graph(
                            type=graph_config.graph_type,
                            series=[
                                _column_to_series(c.column_id)
                                for c in chart_config.y_axis_columns
                            ],
                            configuration=ConfigurationGroup(configs=[
                                ConfigurationItem(id=key, xpath_function=value)
                                for key, value in graph_config.config.items()
                            ]),
                        ),
                    ))
Ejemplo n.º 10
0
    def _get_graph_fields():
        from corehq.apps.userreports.reports.specs import MultibarChartSpec
        from corehq.apps.app_manager.models import GraphConfiguration, GraphSeries

        def _locale_config(key):
            return id_strings.mobile_ucr_configuration(module, config.uuid,
                                                       key)

        def _locale_series_config(index, key):
            return id_strings.mobile_ucr_series_configuration(
                module, config.uuid, index, key)

        def _locale_annotation(index):
            return id_strings.mobile_ucr_annotation(module, config.uuid, index)

        for chart_config in config.report(domain).charts:
            if isinstance(chart_config, MultibarChartSpec):
                graph_config = config.complete_graph_configs.get(
                    chart_config.chart_id,
                    GraphConfiguration(series=[
                        GraphSeries() for c in chart_config.y_axis_columns
                    ], ))
                for index, column in enumerate(chart_config.y_axis_columns):
                    graph_config.series[index].data_path = (
                        graph_config.series[index].data_path
                        or get_data_path(config, domain))
                    graph_config.series[index].x_function = (
                        graph_config.series[index].x_function
                        or COLUMN_XPATH_TEMPLATE.format(
                            chart_config.x_axis_column))
                    graph_config.series[index].y_function = (
                        graph_config.series[index].y_function
                        or COLUMN_XPATH_TEMPLATE.format(column.column_id))
                yield Field(header=Header(text=Text()),
                            template=GraphTemplate.build(
                                'graph',
                                graph_config,
                                locale_config=_locale_config,
                                locale_series_config=_locale_series_config,
                                locale_annotation=_locale_annotation))
Ejemplo n.º 11
0
 def _get_lookup_element(self, detail, module):
     if detail.lookup_display_results:
         field = Field(
             header=Header(
                 width=None if detail.lookup_field_header else 0,
                 text=Text(locale_id=callout_header_locale(module))
                 if detail.lookup_field_header else None,
             ),
             template=Template(text=Text(
                 xpath_function=detail.lookup_field_template)),
         )
     else:
         field = None
     return Lookup(
         name=detail.lookup_name or None,
         auto_launch=detail.lookup_autolaunch or False,
         action=detail.lookup_action,
         image=detail.lookup_image or None,
         extras=[Extra(**e) for e in detail.lookup_extras],
         responses=[Response(**r) for r in detail.lookup_responses],
         field=field,
     )
Ejemplo n.º 12
0
def _get_summary_details(config, domain, module):
    def _get_graph_fields():
        from corehq.apps.userreports.reports.specs import MultibarChartSpec
        from corehq.apps.app_manager.models import GraphConfiguration, GraphSeries

        def _locale_config(key):
            return id_strings.mobile_ucr_configuration(module, config.uuid,
                                                       key)

        def _locale_series_config(index, key):
            return id_strings.mobile_ucr_series_configuration(
                module, config.uuid, index, key)

        def _locale_annotation(index):
            return id_strings.mobile_ucr_annotation(module, config.uuid, index)

        for chart_config in config.report(domain).charts:
            if isinstance(chart_config, MultibarChartSpec):
                graph_config = config.complete_graph_configs.get(
                    chart_config.chart_id,
                    GraphConfiguration(series=[
                        GraphSeries() for c in chart_config.y_axis_columns
                    ], ))
                for index, column in enumerate(chart_config.y_axis_columns):
                    graph_config.series[index].data_path = (
                        graph_config.series[index].data_path
                        or get_data_path(config, domain))
                    graph_config.series[index].x_function = (
                        graph_config.series[index].x_function
                        or COLUMN_XPATH_TEMPLATE.format(
                            chart_config.x_axis_column))
                    graph_config.series[index].y_function = (
                        graph_config.series[index].y_function
                        or COLUMN_XPATH_TEMPLATE.format(column.column_id))
                yield Field(header=Header(text=Text()),
                            template=GraphTemplate.build(
                                'graph',
                                graph_config,
                                locale_config=_locale_config,
                                locale_series_config=_locale_series_config,
                                locale_annotation=_locale_annotation))

    def _get_description_text(report_config):
        if report_config.use_xpath_description:
            return Text(xpath=Xpath(function=config.xpath_description))
        else:
            return Text(locale=Locale(
                id=id_strings.report_description(report_config.uuid)))

    detail_id = 'reports.{}.summary'.format(config.uuid)
    detail = Detail(
        title=Text(locale=Locale(id=id_strings.report_menu()), ),
        fields=[
            Field(
                header=Header(text=Text(locale=Locale(
                    id=id_strings.report_name_header()))),
                template=Template(text=Text(locale=Locale(
                    id=id_strings.report_name(config.uuid)))),
            ),
            Field(
                header=Header(text=Text(locale=Locale(
                    id=id_strings.report_description_header()), )),
                template=Template(text=_get_description_text(config)),
            ),
        ] + [
            Field(
                header=Header(text=Text(locale=Locale(
                    id=id_strings.report_last_sync()))),
                template=Template(text=Text(xpath=Xpath(
                    function=
                    "format-date(date(instance('reports')/reports/@last_sync), '%Y-%m-%d %H:%M')"
                )))),
        ] + list(_get_graph_fields()),
    )
    if config.show_data_table:
        return models.Detail(custom_xml=Detail(
            id=detail_id,
            title=Text(locale=Locale(id=id_strings.report_menu()), ),
            details=[detail, _get_data_detail(config, domain)
                     ]).serialize().decode('utf-8'))
    else:
        detail.id = detail_id
        return models.Detail(custom_xml=detail.serialize().decode('utf-8'))
Ejemplo n.º 13
0
def _get_summary_details(config, domain):
    def _get_graph_fields():
        from corehq.apps.userreports.reports.specs import MultibarChartSpec
        # todo: make this less hard-coded
        for chart_config in config.report(domain).charts:
            if isinstance(chart_config, MultibarChartSpec):
                graph_config = config.graph_configs.get(
                    chart_config.chart_id, ReportGraphConfig())

                def _column_to_series(column):
                    return Series(nodeset=(
                        "instance('reports')/reports/report[@id='{}']/rows/row[@is_total_row='False']{}"
                        .format(
                            config.uuid,
                            _MobileSelectFilterHelpers.get_data_filter_xpath(
                                config, domain))),
                                  x_function="column[@id='{}']".format(
                                      chart_config.x_axis_column),
                                  y_function="column[@id='{}']".format(column),
                                  configuration=ConfigurationGroup(configs=[
                                      ConfigurationItem(id=key,
                                                        xpath_function=value)
                                      for key, value in graph_config.
                                      series_configs.get(column, {}).items()
                                  ]))

                yield Field(
                    header=Header(text=Text()),
                    template=GraphTemplate(
                        form='graph',
                        graph=Graph(
                            type=graph_config.graph_type,
                            series=[
                                _column_to_series(c.column_id)
                                for c in chart_config.y_axis_columns
                            ],
                            configuration=ConfigurationGroup(configs=[
                                ConfigurationItem(id=key, xpath_function=value)
                                for key, value in graph_config.config.items()
                            ]),
                        ),
                    ))

    def _get_description_text(report_config):
        if report_config.use_xpath_description:
            return Text(xpath=Xpath(function=config.xpath_description))
        else:
            return Text(locale=Locale(
                id=id_strings.report_description(report_config.uuid)))

    return models.Detail(custom_xml=Detail(
        id='reports.{}.summary'.format(config.uuid),
        title=Text(locale=Locale(id=id_strings.report_menu()), ),
        details=[
            Detail(
                title=Text(locale=Locale(id=id_strings.report_menu()), ),
                fields=[
                    Field(
                        header=Header(text=Text(locale=Locale(
                            id=id_strings.report_name_header()))),
                        template=Template(text=Text(locale=Locale(
                            id=id_strings.report_name(config.uuid)))),
                    ),
                    Field(
                        header=Header(text=Text(locale=Locale(
                            id=id_strings.report_description_header()), )),
                        template=Template(text=_get_description_text(config)),
                    ),
                ] + [
                    Field(
                        header=Header(text=Text(locale=Locale(id=id_strings.
                                                              report_last_sync(
                                                              )))),
                        template=Template(text=Text(xpath=Xpath(
                            function=
                            "format-date(date(instance('reports')/reports/@last_sync), '%Y-%m-%d %H:%M')"
                        )))),
                ] + list(_get_graph_fields()),
            ),
            _get_data_detail(config, domain),
        ],
    ).serialize().decode('utf-8'))
Ejemplo n.º 14
0
def _get_data_detail(config, domain, new_mobile_ucr_restore):
    """
    Adds a data table to the report
    """
    def get_xpath(column_id):
        if new_mobile_ucr_restore:
            return TextXPath(function="{}".format(column_id), )
        else:
            return TextXPath(function="column[@id='{}']".format(column_id), )

    def _column_to_field(column):
        def _get_xpath(col):
            def _get_conditional(condition, if_true, if_false):
                return 'if({condition}, {if_true}, {if_false})'.format(
                    condition=condition,
                    if_true=if_true,
                    if_false=if_false,
                )

            def _get_word_eval(word_translations, default_value):
                word_eval = default_value
                for lang, translation in word_translations.items():
                    word_eval = _get_conditional(
                        "$lang = '{lang}'".format(lang=lang, ),
                        "'{translation}'".format(
                            translation=translation.replace("'", "''"), ),
                        word_eval)
                return word_eval

            try:
                transform = col['transform']
            except KeyError:
                transform = {}

            if transform.get('type') == 'translation':
                if new_mobile_ucr_restore:
                    default_val = "{column_id}"
                else:
                    default_val = "column[@id='{column_id}']"
                xpath_function = default_val
                for word, translations in transform['translations'].items():
                    if isinstance(translations, str):
                        # This is a flat mapping, not per-language translations
                        word_eval = "'{}'".format(translations)
                    else:
                        word_eval = _get_word_eval(translations, default_val)
                    xpath_function = _get_conditional(
                        "{value} = '{word}'".format(
                            value=default_val,
                            word=word,
                        ), word_eval, xpath_function)
                return TextXPath(
                    function=xpath_function.format(column_id=col.column_id),
                    variables=[
                        XPathVariable(name='lang', locale_id='lang.current')
                    ],
                )
            else:
                return get_xpath(col.column_id)

        return Field(
            header=Header(
                text=Text(locale=Locale(id=id_strings.report_column_header(
                    config.uuid, column.column_id)), )),
            template=Template(text=Text(xpath=_get_xpath(column), )),
        )

    nodeset_string = 'row{}' if new_mobile_ucr_restore else 'rows/row{}'
    if toggles.ADD_ROW_INDEX_TO_MOBILE_UCRS.enabled(domain):
        fields = [
            Field(header=Header(
                text=Text(),
                width=0,
            ),
                  template=Template(
                      text=Text(),
                      width=0,
                  ),
                  sort_node=Sort(
                      type='int',
                      direction='ascending',
                      order='1',
                      text=Text(xpath=get_xpath("row_index")),
                  ))
        ]
    else:
        fields = []
    return Detail(
        id='reports.{}.data'.format(config.uuid),
        nodeset=(nodeset_string.format(
            MobileSelectFilterHelpers.get_data_filter_xpath(
                config, domain, new_mobile_ucr_restore))),
        title=Text(locale=Locale(id=id_strings.report_data_table()), ),
        fields=fields + [
            _column_to_field(c) for c in config.report(domain).report_columns
            if c.type != 'expanded' and c.visible
        ])
Ejemplo n.º 15
0
def _get_summary_details(config, domain, module, new_mobile_ucr_restore=False):
    def _get_graph_fields():
        from corehq.apps.userreports.reports.specs import MultibarChartSpec
        from corehq.apps.app_manager.models import GraphConfiguration, GraphSeries

        def _locale_config(key):
            return id_strings.mobile_ucr_configuration(module, config.uuid,
                                                       key)

        def _locale_series_config(index, key):
            return id_strings.mobile_ucr_series_configuration(
                module, config.uuid, index, key)

        def _locale_annotation(index):
            return id_strings.mobile_ucr_annotation(module, config.uuid, index)

        for chart_config in config.report(domain).charts:
            if isinstance(chart_config, MultibarChartSpec):
                graph_config = config.complete_graph_configs.get(
                    chart_config.chart_id,
                    GraphConfiguration(series=[
                        GraphSeries() for c in chart_config.y_axis_columns
                    ], ))

                # Reconcile graph_config.series with any additions/deletions in chart_config.y_axis_columns
                while len(chart_config.y_axis_columns) > len(
                        graph_config.series):
                    graph_config.series.append(GraphSeries())
                if len(chart_config.y_axis_columns) < len(graph_config.series):
                    graph_config.series = graph_config.series[:len(
                        chart_config.y_axis_columns)]

                for index, column in enumerate(chart_config.y_axis_columns):
                    graph_config.series[index].data_path = (
                        graph_config.series[index].data_path or get_data_path(
                            config, domain, new_mobile_ucr_restore))
                    graph_config.series[index].x_function = (
                        graph_config.series[index].x_function
                        or _get_column_xpath_template(new_mobile_ucr_restore).
                        format(chart_config.x_axis_column))
                    graph_config.series[index].y_function = (
                        graph_config.series[index].y_function
                        or _get_column_xpath_template(
                            new_mobile_ucr_restore).format(column.column_id))
                yield Field(header=Header(text=Text()),
                            template=GraphTemplate.build(
                                'graph',
                                graph_config,
                                locale_config=_locale_config,
                                locale_series_config=_locale_series_config,
                                locale_annotation=_locale_annotation))

    def _get_last_sync(report_config):
        if new_mobile_ucr_restore:
            last_sync_string = "format-date(date(instance('commcare-reports:{}')/@last_sync), '%Y-%m-%d %H:%M')"
            last_sync_string = last_sync_string.format(
                report_config.instance_id)
        else:
            last_sync_string = "format-date(date(instance('reports')/reports/@last_sync), '%Y-%m-%d %H:%M')"

        return Text(xpath=TextXPath(function=last_sync_string))

    def _get_description_text(report_config):
        if report_config.use_xpath_description:
            return Text(xpath=TextXPath(function=config.xpath_description))
        else:
            return Text(locale=Locale(
                id=id_strings.report_description(report_config.uuid)))

    detail_id = 'reports.{}.summary'.format(config.uuid)
    fields = [
        Field(
            header=Header(text=Text(locale=Locale(
                id=id_strings.report_name_header()))),
            template=Template(text=Text(locale=Locale(
                id=id_strings.report_name(config.uuid)))),
        ),
        Field(
            header=Header(text=Text(locale=Locale(
                id=id_strings.report_description_header()), )),
            template=Template(text=_get_description_text(config)),
        ),
    ]

    if not getattr(module, 'report_context_tile', False):
        # Don't add "Last Sync" if the module already contains the similar-looking
        # "Reports last updated on" tile
        fields.append(
            Field(header=Header(text=Text(locale=Locale(
                id=id_strings.report_last_sync()))),
                  template=Template(text=_get_last_sync(config))))
    fields += list(_get_graph_fields())

    detail = Detail(
        title=Text(locale=Locale(id=id_strings.report_menu()), ),
        fields=fields,
    )
    if config.show_data_table:
        return models.Detail(custom_xml=Detail(
            id=detail_id,
            title=Text(locale=Locale(id=id_strings.report_menu()), ),
            details=[
                detail,
                _get_data_detail(config, domain, new_mobile_ucr_restore)
            ]).serialize().decode('utf-8'))
    else:
        detail.id = detail_id
        return models.Detail(custom_xml=detail.serialize().decode('utf-8'))