Пример #1
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
Пример #2
0
    def get_section_elements(self):
        r = []
        if not self.app.use_custom_suite:
            for module in self.modules:
                for detail_type, detail, enabled in module.get_details():
                    if enabled:
                        if detail.custom_xml:
                            d = load_xmlobject_from_string(
                                detail.custom_xml,
                                xmlclass=Detail
                            )
                            r.append(d)
                        else:
                            detail_column_infos = get_detail_column_infos(
                                detail,
                                include_sort=detail_type.endswith('short'),
                            )
                            if detail_column_infos:
                                if detail.use_case_tiles:
                                    r.append(self.build_case_tile_detail(
                                        module, detail, detail_type
                                    ))
                                else:
                                    d = self.build_detail(
                                        module,
                                        detail_type,
                                        detail,
                                        detail_column_infos,
                                        list(detail.get_tabs()),
                                        id_strings.detail(module, detail_type),
                                        Text(locale_id=id_strings.detail_title_locale(
                                            module, detail_type
                                        )),
                                        0,
                                        len(detail_column_infos)
                                    )
                                    if d:
                                        r.append(d)
                if module.fixture_select.active:
                    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
                    r.append(d)
        return r
Пример #3
0
 def get_select_details(config, filter_slug, domain):
     detail = 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()
     return models.Detail(custom_xml=detail.decode('utf-8'))
Пример #4
0
def _get_data_detail(config, domain):
    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 in word_translations.items():
                    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():
                    if isinstance(translations, basestring):
                        # 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(
                        u"{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:
                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), )),
        )

    return Detail(
        id='reports.{}.data'.format(config.uuid),
        nodeset='rows/row{}'.format(
            _MobileSelectFilterHelpers.get_data_filter_xpath(config, domain)),
        title=Text(locale=Locale(id=id_strings.report_data_table()), ),
        fields=[
            _column_to_field(c) for c in config.report(domain).report_columns
        ])
Пример #5
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())
                     ],
                 ))),
             )
         ])
Пример #6
0
 def get_select_details(config, filter_slug, domain):
     detail = 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()
     return models.Detail(custom_xml=detail.decode('utf-8'))
Пример #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
Пример #8
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'))
Пример #9
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)),
                       )
                   ])
Пример #10
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=Xpath(
                function=last_sync_string
            )
        )

    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=_get_last_sync(config))
            ),
        ] + 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, new_mobile_ucr_restore)]
        ).serialize().decode('utf-8'))
    else:
        detail.id = detail_id
        return models.Detail(custom_xml=detail.serialize().decode('utf-8'))
Пример #11
0
    def build_detail(self,
                     module,
                     detail_type,
                     detail,
                     detail_column_infos,
                     tabs=None,
                     id=None,
                     title=None,
                     nodeset=None,
                     print_template=None,
                     start=0,
                     end=None,
                     relevant=None):
        """
        Recursively builds the Detail object.
        (Details can contain other details for each of their tabs)
        """
        from corehq.apps.app_manager.detail_screen import get_column_generator
        d = Detail(id=id,
                   title=title,
                   nodeset=nodeset,
                   print_template=print_template,
                   relevant=relevant)
        self._add_custom_variables(detail, d)
        if tabs:
            tab_spans = detail.get_tab_spans()
            for tab in tabs:
                # relevant should be set to None even in case its ''
                tab_relevant = None
                if tab.relevant and toggles.DISPLAY_CONDITION_ON_TABS.enabled(
                        module.get_app().domain):
                    tab_relevant = tab.relevant

                sub_detail = self.build_detail(
                    module,
                    detail_type,
                    detail,
                    detail_column_infos,
                    title=Text(locale_id=id_strings.detail_tab_title_locale(
                        module, detail_type, tab)),
                    nodeset=tab.nodeset if tab.has_nodeset else None,
                    start=tab_spans[tab.id][0],
                    end=tab_spans[tab.id][1],
                    relevant=tab_relevant,
                )
                if sub_detail:
                    d.details.append(sub_detail)
            if len(d.details):
                helper = EntriesHelper(self.app)
                datums = helper.get_datum_meta_module(module)
                d.variables.extend([
                    DetailVariable(name=datum.datum.id,
                                   function=datum.datum.value)
                    for datum in datums
                ])
                return d
            else:
                return None

        # Base case (has no tabs)
        else:
            # Add lookup
            if detail.lookup_enabled and detail.lookup_action:
                d.lookup = self._get_lookup_element(detail, module)

            # Add variables
            variables = list(
                schedule_detail_variables(module, detail, detail_column_infos))
            if variables:
                d.variables.extend(variables)

            # Add fields
            if end is None:
                end = len(detail_column_infos)
            for column_info in detail_column_infos[start:end]:
                # column_info is an instance of DetailColumnInfo named tuple. It has the following properties:
                #   column_info.column: an instance of app_manager.models.DetailColumn
                #   column_info.sort_element: an instance of app_manager.models.SortElement
                #   column_info.order: an integer
                fields = get_column_generator(self.app,
                                              module,
                                              detail,
                                              parent_tab_nodeset=nodeset,
                                              detail_type=detail_type,
                                              *column_info).fields
                for field in fields:
                    d.fields.append(field)

            # Add actions
            if detail_type.endswith('short') and not module.put_in_root:
                if module.case_list_form.form_id:
                    target_form = self.app.get_form(
                        module.case_list_form.form_id)
                    if target_form.is_registration_form(module.case_type):
                        d.actions.append(self._get_reg_form_action(module))

                if module_offers_search(module):
                    d.actions.append(
                        self._get_case_search_action(module,
                                                     in_search="search" in id))

            try:
                if not self.app.enable_multi_sort:
                    d.fields[0].sort = 'default'
            except IndexError:
                pass
            else:
                # only yield the Detail if it has Fields
                return d
Пример #12
0
    def build_detail(self, module, detail_type, detail, detail_column_infos,
                     tabs, id, title, start, end):
        """
        Recursively builds the Detail object.
        (Details can contain other details for each of their tabs)
        """
        from corehq.apps.app_manager.detail_screen import get_column_generator
        d = Detail(id=id, title=title)
        if tabs:
            tab_spans = detail.get_tab_spans()
            for tab in tabs:
                sub_detail = self.build_detail(
                    module,
                    detail_type,
                    detail,
                    detail_column_infos,
                    [],
                    None,
                    Text(locale_id=id_strings.detail_tab_title_locale(
                        module, detail_type, tab
                    )),
                    tab_spans[tab.id][0],
                    tab_spans[tab.id][1]
                )
                if sub_detail:
                    d.details.append(sub_detail)
            if len(d.details):
                return d
            else:
                return None

        # Base case (has no tabs)
        else:
            # Add lookup
            if detail.lookup_enabled and detail.lookup_action:
                d.lookup = Lookup(
                    name=detail.lookup_name or None,
                    action=detail.lookup_action,
                    image=detail.lookup_image or None,
                )
                d.lookup.extras = [Extra(**e) for e in detail.lookup_extras]
                d.lookup.responses = [Response(**r) for r in detail.lookup_responses]

            # Add variables
            variables = list(
                schedule_detail_variables(module, detail, detail_column_infos)
            )
            if variables:
                d.variables.extend(variables)

            # Add fields
            for column_info in detail_column_infos[start:end]:
                fields = get_column_generator(
                    self.app, module, detail,
                    detail_type=detail_type, *column_info
                ).fields
                d.fields.extend(fields)

            # Add actions
            if module.case_list_form.form_id and detail_type.endswith('short')\
                    and not module.put_in_root:
                target_form = self.app.get_form(module.case_list_form.form_id)
                if target_form.is_registration_form(module.case_type):
                    self._add_action_to_detail(d, module)

            try:
                if not self.app.enable_multi_sort:
                    d.fields[0].sort = 'default'
            except IndexError:
                pass
            else:
                # only yield the Detail if it has Fields
                return d
Пример #13
0
    def build_detail(self,
                     module,
                     detail_type,
                     detail,
                     detail_column_infos,
                     tabs=None,
                     id=None,
                     title=None,
                     nodeset=None,
                     start=0,
                     end=None):
        """
        Recursively builds the Detail object.
        (Details can contain other details for each of their tabs)
        """
        from corehq.apps.app_manager.detail_screen import get_column_generator
        d = Detail(id=id, title=title, nodeset=nodeset)
        if tabs:
            tab_spans = detail.get_tab_spans()
            for tab in tabs:
                sub_detail = self.build_detail(
                    module,
                    detail_type,
                    detail,
                    detail_column_infos,
                    title=Text(locale_id=id_strings.detail_tab_title_locale(
                        module, detail_type, tab)),
                    nodeset=tab.nodeset if tab.has_nodeset else None,
                    start=tab_spans[tab.id][0],
                    end=tab_spans[tab.id][1])
                if sub_detail:
                    d.details.append(sub_detail)
            if len(d.details):
                helper = EntriesHelper(self.app)
                datums = helper.get_datum_meta_module(module)
                d.variables.extend([
                    DetailVariable(name=datum.datum.id,
                                   function=datum.datum.value)
                    for datum in datums
                ])
                return d
            else:
                return None

        # Base case (has no tabs)
        else:
            # Add lookup
            if detail.lookup_enabled and detail.lookup_action:
                d.lookup = self._get_lookup_element(detail, module)

            # Add variables
            variables = list(
                schedule_detail_variables(module, detail, detail_column_infos))
            if variables:
                d.variables.extend(variables)

            # Add fields
            if end is None:
                end = len(detail_column_infos)
            for column_info in detail_column_infos[start:end]:
                fields = get_column_generator(self.app,
                                              module,
                                              detail,
                                              detail_type=detail_type,
                                              *column_info).fields
                d.fields.extend(fields)

            # Add actions
            if module.case_list_form.form_id and detail_type.endswith('short')\
                    and not module.put_in_root:
                target_form = self.app.get_form(module.case_list_form.form_id)
                if target_form.is_registration_form(module.case_type):
                    d.actions.append(self._get_reg_form_action(module))
            if module_offers_search(module) and detail_type.endswith(
                    'short') and not module.put_in_root:
                d.actions.append(self._get_case_search_action(module))

            try:
                if not self.app.enable_multi_sort:
                    d.fields[0].sort = 'default'
            except IndexError:
                pass
            else:
                # only yield the Detail if it has Fields
                return d
Пример #14
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'))
Пример #15
0
    def build_detail(self, module, detail_type, detail, detail_column_infos,
                     tabs=None, id=None, title=None, nodeset=None, start=0, end=None):
        """
        Recursively builds the Detail object.
        (Details can contain other details for each of their tabs)
        """
        from corehq.apps.app_manager.detail_screen import get_column_generator
        d = Detail(id=id, title=title, nodeset=nodeset)
        self._add_custom_variables(detail, d)
        if tabs:
            tab_spans = detail.get_tab_spans()
            for tab in tabs:
                sub_detail = self.build_detail(
                    module,
                    detail_type,
                    detail,
                    detail_column_infos,
                    title=Text(locale_id=id_strings.detail_tab_title_locale(
                        module, detail_type, tab
                    )),
                    nodeset=tab.nodeset if tab.has_nodeset else None,
                    start=tab_spans[tab.id][0],
                    end=tab_spans[tab.id][1]
                )
                if sub_detail:
                    d.details.append(sub_detail)
            if len(d.details):
                helper = EntriesHelper(self.app)
                datums = helper.get_datum_meta_module(module)
                d.variables.extend([DetailVariable(name=datum.datum.id, function=datum.datum.value) for datum in datums])
                return d
            else:
                return None

        # Base case (has no tabs)
        else:
            # Add lookup
            if detail.lookup_enabled and detail.lookup_action:
                d.lookup = self._get_lookup_element(detail, module)

            # Add variables
            variables = list(
                schedule_detail_variables(module, detail, detail_column_infos)
            )
            if variables:
                d.variables.extend(variables)

            # Add fields
            if end is None:
                end = len(detail_column_infos)
            for column_info in detail_column_infos[start:end]:
                fields = get_column_generator(
                    self.app, module, detail,
                    detail_type=detail_type, *column_info
                ).fields
                d.fields.extend(fields)

            # Add actions
            if module.case_list_form.form_id and detail_type.endswith('short')\
                    and not module.put_in_root:
                target_form = self.app.get_form(module.case_list_form.form_id)
                if target_form.is_registration_form(module.case_type):
                    d.actions.append(self._get_reg_form_action(module))
            if module_offers_search(module) and detail_type.endswith('short') and not module.put_in_root:
                d.actions.append(self._get_case_search_action(module))

            try:
                if not self.app.enable_multi_sort:
                    d.fields[0].sort = 'default'
            except IndexError:
                pass
            else:
                # only yield the Detail if it has Fields
                return d
Пример #16
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'))
Пример #17
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
        ])
Пример #18
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'))
Пример #19
0
    def build_detail(self, module, detail_type, detail, detail_column_infos, tabs=None, id=None,
                     title=None, nodeset=None, print_template=None, start=0, end=None, relevant=None):
        """
        Recursively builds the Detail object.
        (Details can contain other details for each of their tabs)
        """
        from corehq.apps.app_manager.detail_screen import get_column_generator
        d = Detail(id=id, title=title, nodeset=nodeset, print_template=print_template, relevant=relevant)
        self._add_custom_variables(detail, d)
        if tabs:
            tab_spans = detail.get_tab_spans()
            for tab in tabs:
                # relevant should be set to None even in case its ''
                tab_relevant = None
                if tab.relevant and toggles.DISPLAY_CONDITION_ON_TABS.enabled(module.get_app().domain):
                    tab_relevant = tab.relevant

                sub_detail = self.build_detail(
                    module,
                    detail_type,
                    detail,
                    detail_column_infos,
                    title=Text(locale_id=id_strings.detail_tab_title_locale(
                        module, detail_type, tab
                    )),
                    nodeset=tab.nodeset if tab.has_nodeset else None,
                    start=tab_spans[tab.id][0],
                    end=tab_spans[tab.id][1],
                    relevant=tab_relevant,
                )
                if sub_detail:
                    d.details.append(sub_detail)
            if len(d.details):
                helper = EntriesHelper(self.app)
                datums = helper.get_datum_meta_module(module)
                d.variables.extend([DetailVariable(name=datum.datum.id, function=datum.datum.value) for datum in datums])
                return d
            else:
                return None

        # Base case (has no tabs)
        else:
            # Add lookup
            if detail.lookup_enabled and detail.lookup_action:
                d.lookup = self._get_lookup_element(detail, module)

            # Add variables
            variables = list(
                schedule_detail_variables(module, detail, detail_column_infos)
            )
            if variables:
                d.variables.extend(variables)

            # Add fields
            if end is None:
                end = len(detail_column_infos)
            for column_info in detail_column_infos[start:end]:
                # column_info is an instance of DetailColumnInfo named tuple. It has the following properties:
                #   column_info.column: an instance of app_manager.models.DetailColumn
                #   column_info.sort_element: an instance of app_manager.models.SortElement
                #   column_info.order: an integer
                fields = get_column_generator(
                    self.app, module, detail, parent_tab_nodeset=nodeset,
                    detail_type=detail_type, *column_info
                ).fields
                for field in fields:
                    d.fields.append(field)

            # Add actions
            if detail_type.endswith('short') and not module.put_in_root:
                if module.case_list_form.form_id:
                    target_form = self.app.get_form(module.case_list_form.form_id)
                    if target_form.is_registration_form(module.case_type):
                        d.actions.append(self._get_reg_form_action(module))

                if module_offers_search(module) and "search" not in id:
                    # Add the search action only if this isn't a search detail
                    d.actions.append(self._get_case_search_action(module))

            try:
                if not self.app.enable_multi_sort:
                    d.fields[0].sort = 'default'
            except IndexError:
                pass
            else:
                # only yield the Detail if it has Fields
                return d