예제 #1
0
class ConfigurableDataSourceFromAppForm(forms.Form):

    def __init__(self, domain, *args, **kwargs):
        super(ConfigurableDataSourceFromAppForm, self).__init__(*args, **kwargs)
        self.app_source_helper = ApplicationDataSourceUIHelper()
        self.app_source_helper.bootstrap(domain)
        report_source_fields = self.app_source_helper.get_fields()
        self.fields.update(report_source_fields)
        self.helper = FormHelper()
        self.helper.form_id = "data-source-config"

        self.helper.form_method = 'POST'
        self.helper.form_class = 'form-horizontal'
        self.helper.form_action = '#'

        self.helper.label_class = 'col-sm-3 col-md-2'
        self.helper.field_class = 'col-sm-9 col-md-9'

        self.helper.layout = crispy.Layout(
            crispy.Fieldset(
                _("Create Data Source from Application"),
                *report_source_fields.keys()
            ),
            hqcrispy.FormActions(
                twbscrispy.StrictButton(
                    _("Create Data Source"),
                    type="submit",
                    css_class="btn btn-primary",
                ),
            ),
        )
예제 #2
0
class ConfigurableDataSourceFromAppForm(forms.Form):
    def __init__(self, domain, *args, **kwargs):
        super(ConfigurableDataSourceFromAppForm,
              self).__init__(*args, **kwargs)
        self.app_source_helper = ApplicationDataSourceUIHelper()
        self.app_source_helper.bootstrap(domain)
        report_source_fields = self.app_source_helper.get_fields()
        self.fields.update(report_source_fields)
        self.helper = FormHelper()
        self.helper.form_id = "data-source-config"

        self.helper.form_method = 'POST'
        self.helper.form_class = 'form-horizontal'
        self.helper.form_action = '#'

        self.helper.label_class = 'col-sm-3 col-md-2'
        self.helper.field_class = 'col-sm-9 col-md-9'

        self.helper.layout = crispy.Layout(
            crispy.Fieldset(_("Create Data Source from Application"),
                            *list(report_source_fields)),
            hqcrispy.FormActions(
                twbscrispy.StrictButton(
                    _("Create Data Source"),
                    type="submit",
                    css_class="btn btn-primary",
                ), ),
        )
예제 #3
0
파일: forms.py 프로젝트: ekush/commcare-hq
class ConfigurableDataSourceFromAppForm(forms.Form):
    def __init__(self, domain, *args, **kwargs):
        super(ConfigurableDataSourceFromAppForm, self).__init__(*args, **kwargs)
        self.app_source_helper = ApplicationDataSourceUIHelper()
        self.app_source_helper.bootstrap(domain)
        report_source_fields = self.app_source_helper.get_fields()
        self.fields.update(report_source_fields)
        self.helper = FormHelper()
        self.helper.form_id = "data-source-config"
        self.helper.layout = crispy.Layout(
            crispy.Div(*report_source_fields.keys() + [Submit("submit", _("Save Changes"))])
        )
예제 #4
0
class ConfigurableDataSourceFromAppForm(forms.Form):
    def __init__(self, domain, *args, **kwargs):
        super(ConfigurableDataSourceFromAppForm,
              self).__init__(*args, **kwargs)
        self.app_source_helper = ApplicationDataSourceUIHelper()
        self.app_source_helper.bootstrap(domain)
        report_source_fields = self.app_source_helper.get_fields()
        self.fields.update(report_source_fields)
        self.helper = FormHelper()
        self.helper.form_id = "data-source-config"
        self.helper.layout = crispy.Layout(
            crispy.Div(*report_source_fields.keys() +
                       [Submit('submit', _('Save Changes'))]))
예제 #5
0
class PerformanceMessageEditForm(forms.Form):
    recipient_id = forms.CharField()
    schedule = forms.ChoiceField(choices=[(choice, ugettext_lazy(choice)) for choice in SCHEDULE_CHOICES])
    template = forms.CharField(widget=forms.Textarea)
    time_range = forms.ChoiceField(
        choices=[(choice.slug, choice.description) for choice in get_simple_dateranges()]
    )

    def __init__(self, domain, config, *args, **kwargs):
        self.domain = domain
        self.config = config

        def _to_initial(config):
            initial = copy.copy(config._doc)
            initial['schedule'] = config.schedule.interval
            if config.template_variables:
                initial['application'] = config.template_variables[0].app_id
                initial['source'] = config.template_variables[0].source_id
                initial['time_range'] = config.template_variables[0].time_range
            return initial

        super(PerformanceMessageEditForm, self).__init__(initial=_to_initial(config), *args, **kwargs)

        self.fields['recipient_id'] = GroupField(domain=domain, label=_('Recipient Group'))

        self.app_source_helper = ApplicationDataSourceUIHelper(enable_cases=False)
        self.app_source_helper.bootstrap(self.domain)
        data_source_fields = self.app_source_helper.get_fields()
        self.fields.update(data_source_fields)

        self.helper = _get_default_form_helper()
        form_layout = self.fields.keys()
        form_layout.append(
            hqcrispy.FormActions(
                StrictButton(
                    _("Save Changes"),
                    type="submit",
                    css_class="btn btn-primary",
                ),
            )
        )
        self.helper.layout = Layout(
            *form_layout
        )

    def clean_template(self):
        return _clean_template(self.cleaned_data['template'])

    def clean_schedule(self):
        # todo: support other scheduling options
        return ScheduleConfiguration(interval=self.cleaned_data['schedule'])

    def save(self, commit=True):
        self.config.recipient_id = self.cleaned_data['recipient_id']
        self.config.schedule = self.cleaned_data['schedule']
        self.config.template = self.cleaned_data['template']
        template_variable = TemplateVariable(
            type=self.cleaned_data['source_type'],
            time_range=self.cleaned_data['time_range'],
            source_id=self.cleaned_data['source'],
            app_id=self.cleaned_data['application'],
        )
        self.config.template_variables = [template_variable]
        if commit:
            self.config.save()
        return self.config

    @property
    def app_id(self):
        if self.config.template_variables:
            return self.config.template_variables[0].app_id
        return ''

    @property
    def source_id(self):
        if self.config.template_variables:
            return self.config.template_variables[0].source_id
        return ''
예제 #6
0
class DataSourceForm(forms.Form):
    report_name = forms.CharField()
    chart_type = forms.ChoiceField(
        choices=[
            ('bar', _('Bar')),
            ('pie', _("Pie")),
        ],
    )

    def __init__(self, domain, report_type, *args, **kwargs):
        super(DataSourceForm, self).__init__(*args, **kwargs)
        self.domain = domain
        self.report_type = report_type

        self.app_source_helper = ApplicationDataSourceUIHelper()
        self.app_source_helper.bootstrap(self.domain)
        report_source_fields = self.app_source_helper.get_fields()
        report_source_help_texts = {
            "source_type": _("<strong>Form</strong>: display data from form submissions.<br/><strong>Case</strong>: display data from your cases. You must be using case management for this option."),
            "application": _("Which application should the data come from?"),
            "source": _("Choose the case type or form from which to retrieve data for this report."),
        }
        self.fields.update(report_source_fields)

        self.fields['chart_type'].required = self.report_type == "chart"

        self.helper = FormHelper()
        self.helper.form_class = "form-horizontal"
        self.helper.form_id = "report-builder-form"

        chart_type_crispy_field = None
        if self.report_type == 'chart':
            chart_type_crispy_field = FieldWithHelpBubble('chart_type', help_bubble_text=_("<strong>Bar</strong> shows one vertical bar for each value in your case or form. <strong>Pie</strong> shows what percentage of the total each value is."))
        report_source_crispy_fields = []
        for k in report_source_fields.keys():
            if k in report_source_help_texts:
                report_source_crispy_fields.append(FieldWithHelpBubble(
                    k, help_bubble_text=report_source_help_texts[k]
                ))
            else:
                report_source_crispy_fields.append(k)


        self.helper.layout = crispy.Layout(
            crispy.Fieldset(
                _('{} Report'.format(self.report_type.capitalize())),
                FieldWithHelpBubble('report_name', help_bubble_text=_('Web users will see this name in the "Reports" section of CommCareHQ and can click to view the report')),
                chart_type_crispy_field
            ),
            crispy.Fieldset(
                _('Data'), *report_source_crispy_fields
            ),
            FormActions(
                crispy.ButtonHolder(
                    crispy.Submit(
                        'create_new_report_builder_btn',
                        _('Next'),
                    )
                ),
            ),
        )

    @property
    def sources_map(self):
        return self.app_source_helper.all_sources

    def get_selected_source(self):
        return self.app_source_helper.get_app_source(self.cleaned_data)

    def clean(self):
        """
        Raise a validation error if there are already 5 data sources and this
        report won't be able to use one of the existing ones.
        """
        cleaned_data = super(DataSourceForm, self).clean()
        source_type = cleaned_data.get('source_type')
        report_source = cleaned_data.get('report_source')
        app_id = cleaned_data.get('application')

        if report_source and source_type and app_id:

            app = Application.get(app_id)
            ds_builder = DataSourceBuilder(self.domain, app, source_type, report_source)

            existing_sources = DataSourceConfiguration.by_domain(self.domain)
            if len(existing_sources) >= 5:
                if not ds_builder.get_existing_match():
                    raise forms.ValidationError(_(
                        "Too many data sources!\n"
                        "Creating this report would cause you to go over the maximum "
                        "number of data sources allowed in this domain. The current "
                        "limit is 5. "
                        "To continue, delete all of the reports using a particular "
                        "data source (or the data source itself) and try again. "
                    ))

        return cleaned_data
예제 #7
0
class CreateNewReportForm(forms.Form):
    """
    A form for the first page of the report builder.
    Allows user to specify report type, application, and source.
    """
    report_type = forms.ChoiceField(
        choices=[
            ('bar_chart', _("Bar Chart")),
            ('pie_chart', _("Pie Chart")),
            ('table', _("Table")),
        ],
    )

    def __init__(self, domain, *args, **kwargs):
        super(CreateNewReportForm, self).__init__(*args, **kwargs)
        self.domain = domain
        self.app_source_helper = ApplicationDataSourceUIHelper()
        self.app_source_helper.bootstrap(self.domain)
        report_source_fields = self.app_source_helper.get_fields()
        self.fields.update(report_source_fields)
        self.helper = FormHelper()
        self.helper.form_class = "form-horizontal"
        self.helper.form_id = "report-builder-form"
        self.helper.layout = crispy.Layout(
            crispy.Fieldset(
                _('Create New Report'),
                'report_type',
                *report_source_fields.keys()
            ),
            FormActions(
                crispy.ButtonHolder(
                    crispy.Submit(
                        'create_new_report_builder_btn',
                        _('Next'),
                    )
                ),
            ),
        )

    @property
    def sources_map(self):
        return self.app_source_helper.all_sources

    def get_selected_source(self):
        return self.app_source_helper.get_app_source(self.cleaned_data)

    def clean(self):
        """
        Raise a validation error if there are already 5 data sources and this
        report won't be able to use one of the existing ones.
        """
        cleaned_data = super(CreateNewReportForm, self).clean()
        source_type = cleaned_data.get('source_type')
        report_source = cleaned_data.get('report_source')
        app_id = cleaned_data.get('application')

        if report_source and source_type and app_id:

            app = Application.get(app_id)
            ds_builder = DataSourceBuilder(self.domain, app, source_type, report_source)

            existing_sources = DataSourceConfiguration.by_domain(self.domain)
            if len(existing_sources) >= 5:
                if not ds_builder.get_existing_match():
                    raise forms.ValidationError(_(
                        "Too many data sources!\n"
                        "Creating this report would cause you to go over the maximum "
                        "number of data sources allowed in this domain. The current "
                        "limit is 5. "
                        "To continue, delete all of the reports using a particular "
                        "data source (or the data source itself) and try again. "
                    ))

        return cleaned_data
예제 #8
0
class PerformanceMessageEditForm(forms.Form):
    recipient_id = forms.CharField()
    schedule = forms.ChoiceField(choices=[(choice, ugettext_lazy(choice)) for choice in SCHEDULE_CHOICES])
    template = forms.CharField(widget=forms.Textarea)
    time_range = forms.ChoiceField(
        choices=[(choice.slug, choice.description) for choice in get_simple_dateranges()]
    )

    def __init__(self, domain, config, *args, **kwargs):
        self.domain = domain
        self.config = config

        def _to_initial(config):
            initial = copy.copy(config._doc)
            initial['schedule'] = config.schedule.interval
            if config.template_variables:
                # todo: needs to support multiple sources
                initial['application'] = config.template_variables[0].app_id
                initial['source'] = config.template_variables[0].source_id
                initial['time_range'] = config.template_variables[0].time_range
            return initial

        super(PerformanceMessageEditForm, self).__init__(initial=_to_initial(config), *args, **kwargs)

        self.fields['recipient_id'] = GroupField(domain=domain, label=_('Recipient Group'))

        self.app_source_helper = ApplicationDataSourceUIHelper(enable_cases=False)
        self.app_source_helper.bootstrap(self.domain)
        data_source_fields = self.app_source_helper.get_fields()
        self.fields.update(data_source_fields)

        self.helper = FormHelper()
        self.helper.label_class = 'col-sm-3 col-md-2'
        self.helper.field_class = 'col-sm-9 col-md-8 col-lg-6'
        self.helper.form_class = "form-horizontal"
        self.helper.form_id = "performance-form"

        self.helper.form_method = 'post'

        form_layout = self.fields.keys()
        form_layout.append(
            hqcrispy.FormActions(
                StrictButton(
                    _("Save Changes"),
                    type="submit",
                    css_class="btn btn-primary",
                ),
            )
        )
        self.helper.layout = Layout(
            *form_layout
        )

    def clean_template(self):
        template = self.cleaned_data['template']
        try:
            parser.validate(template)
        except InvalidParameterException as e:
            raise forms.ValidationError(unicode(e))
        return template

    def clean_schedule(self):
        # todo: support other scheduling options
        return ScheduleConfiguration(interval=self.cleaned_data['schedule'])

    def save(self, commit=True):
        self.config.recipient_id = self.cleaned_data['recipient_id']
        self.config.schedule = self.cleaned_data['schedule']
        self.config.template = self.cleaned_data['template']
        # todo: support more than one data source
        template_variable = TemplateVariable(
            type=self.cleaned_data['source_type'],
            time_range=self.cleaned_data['time_range'],
            source_id=self.cleaned_data['source'],
            app_id=self.cleaned_data['application'],
        )
        self.config.template_variables = [template_variable]
        if commit:
            self.config.save()
        return self.config

    @property
    def app_id(self):
        # todo: need to support multiple sources
        if self.config.template_variables:
            return self.config.template_variables[0].app_id
        return ''

    @property
    def source_id(self):
        if self.config.template_variables:
            return self.config.template_variables[0].source_id
        return ''
예제 #9
0
class DataSourceForm(forms.Form):
    report_name = forms.CharField()
    chart_type = forms.ChoiceField(
        choices=[
            ('bar', _('Bar')),
            ('pie', _("Pie")),
        ],
    )

    def __init__(self, domain, report_type, max_allowed_reports, *args, **kwargs):
        super(DataSourceForm, self).__init__(*args, **kwargs)
        self.domain = domain
        self.report_type = report_type
        self.max_allowed_reports = max_allowed_reports

        self.app_source_helper = ApplicationDataSourceUIHelper()
        self.app_source_helper.source_type_field.label = _('Forms or Cases')
        self.app_source_helper.source_type_field.choices = [("case", _("Cases")), ("form", _("Forms"))]
        self.app_source_helper.source_field.label = '<span data-bind="text: labelMap[sourceType()]"></span>'
        self.app_source_helper.bootstrap(self.domain)
        report_source_fields = self.app_source_helper.get_fields()
        report_source_help_texts = {
            "source_type": _("<strong>Form</strong>: display data from form submissions.<br/><strong>Case</strong>: display data from your cases. You must be using case management for this option."),
            "application": _("Which application should the data come from?"),
            "source": _("Choose the case type or form from which to retrieve data for this report."),
        }
        self.fields.update(report_source_fields)

        self.fields['chart_type'].required = self.report_type == "chart"

        self.helper = FormHelper()
        self.helper.form_class = "form form-horizontal"
        self.helper.form_id = "report-builder-form"
        self.helper.label_class = 'col-sm-3 col-md-2 col-lg-2'
        self.helper.field_class = 'col-sm-9 col-md-8 col-lg-6'

        chart_type_crispy_field = None
        if self.report_type == 'chart':
            chart_type_crispy_field = FieldWithHelpBubble('chart_type', help_bubble_text=_("<strong>Bar</strong> shows one vertical bar for each value in your case or form. <strong>Pie</strong> shows what percentage of the total each value is."))
        report_source_crispy_fields = []
        for k in report_source_fields.keys():
            if k in report_source_help_texts:
                report_source_crispy_fields.append(FieldWithHelpBubble(
                    k, help_bubble_text=report_source_help_texts[k]
                ))
            else:
                report_source_crispy_fields.append(k)

        top_fields = [
            FieldWithHelpBubble(
                'report_name',
                help_bubble_text=_('Web users will see this name in the "Reports" section of CommCareHQ and can click to view the report'))
        ]
        if chart_type_crispy_field:
            top_fields.append(chart_type_crispy_field)

        self.helper.layout = crispy.Layout(
            crispy.Fieldset(
                _('{} Report'.format(self.report_type.capitalize())),
                *top_fields
            ),
            crispy.Fieldset(
                _('Data'), *report_source_crispy_fields
            ),
            hqcrispy.FormActions(
                StrictButton(
                    _('Next'),
                    type="submit",
                    css_class="btn-primary",
                )
            ),
        )

    @property
    def sources_map(self):
        return self.app_source_helper.all_sources

    def get_selected_source(self):
        return self.app_source_helper.get_app_source(self.cleaned_data)

    def clean(self):
        """
        Raise a validation error if there are already 5 data sources and this
        report won't be able to use one of the existing ones.
        """
        cleaned_data = super(DataSourceForm, self).clean()

        existing_reports = ReportConfiguration.by_domain(self.domain)
        builder_reports = filter(lambda report: report.report_meta.created_by_builder, existing_reports)
        if len(builder_reports) >= self.max_allowed_reports:
            raise forms.ValidationError(_(
                "Too many reports!\n"
                "Creating this report would cause you to go over the maximum "
                "number of report builder reports allowed in this domain. Your"
                "limit is {number}. "
                "To continue, delete another report and try again. "
            ).format(number=self.max_allowed_reports))

        return cleaned_data
예제 #10
0
파일: forms.py 프로젝트: ekush/commcare-hq
class DataSourceForm(forms.Form):
    report_name = forms.CharField()
    chart_type = forms.ChoiceField(choices=[
        ('bar', _('Bar')),
        ('pie', _("Pie")),
    ], )

    def __init__(self, domain, report_type, *args, **kwargs):
        super(DataSourceForm, self).__init__(*args, **kwargs)
        self.domain = domain
        self.report_type = report_type

        self.app_source_helper = ApplicationDataSourceUIHelper()
        self.app_source_helper.bootstrap(self.domain)
        report_source_fields = self.app_source_helper.get_fields()
        report_source_help_texts = {
            "source_type":
            _("<strong>Form</strong>: display data from form submissions.<br/><strong>Case</strong>: display data from your cases. You must be using case management for this option."
              ),
            "application":
            _("Which application should the data come from?"),
            "source":
            _("Choose the case type or form from which to retrieve data for this report."
              ),
        }
        self.fields.update(report_source_fields)

        self.fields['chart_type'].required = self.report_type == "chart"

        self.helper = FormHelper()
        self.helper.form_class = "form-horizontal"
        self.helper.form_id = "report-builder-form"

        chart_type_crispy_field = None
        if self.report_type == 'chart':
            chart_type_crispy_field = FieldWithHelpBubble(
                'chart_type',
                help_bubble_text=
                _("<strong>Bar</strong> shows one vertical bar for each value in your case or form. <strong>Pie</strong> shows what percentage of the total each value is."
                  ))
        report_source_crispy_fields = []
        for k in report_source_fields.keys():
            if k in report_source_help_texts:
                report_source_crispy_fields.append(
                    FieldWithHelpBubble(
                        k, help_bubble_text=report_source_help_texts[k]))
            else:
                report_source_crispy_fields.append(k)

        self.helper.layout = crispy.Layout(
            crispy.Fieldset(
                _('{} Report'.format(self.report_type.capitalize())),
                FieldWithHelpBubble(
                    'report_name',
                    help_bubble_text=
                    _('Web users will see this name in the "Reports" section of CommCareHQ and can click to view the report'
                      )), chart_type_crispy_field),
            crispy.Fieldset(_('Data'), *report_source_crispy_fields),
            FormActions(
                crispy.ButtonHolder(
                    crispy.Submit(
                        'create_new_report_builder_btn',
                        _('Next'),
                    )), ),
        )

    @property
    def sources_map(self):
        return self.app_source_helper.all_sources

    def get_selected_source(self):
        return self.app_source_helper.get_app_source(self.cleaned_data)

    def clean(self):
        """
        Raise a validation error if there are already 5 data sources and this
        report won't be able to use one of the existing ones.
        """
        cleaned_data = super(DataSourceForm, self).clean()
        source_type = cleaned_data.get('source_type')
        report_source = cleaned_data.get('report_source')
        app_id = cleaned_data.get('application')

        if report_source and source_type and app_id:

            app = Application.get(app_id)
            ds_builder = DataSourceBuilder(self.domain, app, source_type,
                                           report_source)

            existing_sources = DataSourceConfiguration.by_domain(self.domain)
            if len(existing_sources) >= 5:
                if not ds_builder.get_existing_match():
                    raise forms.ValidationError(
                        _("Too many data sources!\n"
                          "Creating this report would cause you to go over the maximum "
                          "number of data sources allowed in this domain. The current "
                          "limit is 5. "
                          "To continue, delete all of the reports using a particular "
                          "data source (or the data source itself) and try again. "
                          ))

        return cleaned_data
예제 #11
0
class PerformanceMessageEditForm(forms.Form):
    recipient_id = forms.CharField()
    schedule = forms.ChoiceField(choices=[(choice, ugettext_lazy(choice))
                                          for choice in SCHEDULE_CHOICES])
    template = forms.CharField(widget=forms.Textarea)
    time_range = forms.ChoiceField(
        choices=[(choice.slug, choice.description)
                 for choice in get_simple_dateranges()])

    def __init__(self, domain, config, *args, **kwargs):
        self.domain = domain
        self.config = config

        def _to_initial(config):
            initial = copy.copy(config._doc)
            initial['schedule'] = config.schedule.interval
            if config.template_variables:
                initial['application'] = config.template_variables[0].app_id
                initial['source'] = config.template_variables[0].source_id
                initial['time_range'] = config.template_variables[0].time_range
            return initial

        super(PerformanceMessageEditForm,
              self).__init__(initial=_to_initial(config), *args, **kwargs)

        self.fields['recipient_id'] = GroupField(domain=domain,
                                                 label=_('Recipient Group'))

        self.app_source_helper = ApplicationDataSourceUIHelper(
            enable_cases=False)
        self.app_source_helper.bootstrap(self.domain)
        data_source_fields = self.app_source_helper.get_fields()
        self.fields.update(data_source_fields)

        self.helper = _get_default_form_helper()
        form_layout = self.fields.keys()
        form_layout.append(
            hqcrispy.FormActions(
                StrictButton(
                    _("Save Changes"),
                    type="submit",
                    css_class="btn btn-primary",
                ), ))
        self.helper.layout = Layout(*form_layout)

    def clean_template(self):
        return _clean_template(self.cleaned_data['template'])

    def clean_schedule(self):
        # todo: support other scheduling options
        return ScheduleConfiguration(interval=self.cleaned_data['schedule'])

    def save(self, commit=True):
        self.config.recipient_id = self.cleaned_data['recipient_id']
        self.config.schedule = self.cleaned_data['schedule']
        self.config.template = self.cleaned_data['template']
        template_variable = TemplateVariable(
            type=self.cleaned_data['source_type'],
            time_range=self.cleaned_data['time_range'],
            source_id=self.cleaned_data['source'],
            app_id=self.cleaned_data['application'],
        )
        self.config.template_variables = [template_variable]
        if commit:
            self.config.save()
        return self.config

    @property
    def app_id(self):
        if self.config.template_variables:
            return self.config.template_variables[0].app_id
        return ''

    @property
    def source_id(self):
        if self.config.template_variables:
            return self.config.template_variables[0].source_id
        return ''