class CaseExpressionRepeaterForm(GenericRepeaterForm): configured_filter = JsonField(expected_type=dict, help_text=help_text.CONFIGURED_FILTER) configured_expression = JsonField(expected_type=dict) url_template = CharField( required=False, help_text= _("Items to add to the end of the URL. Please see the documentation for more information." )) def get_ordered_crispy_form_fields(self): fields = super().get_ordered_crispy_form_fields() return fields + [ 'url_template', 'configured_filter', 'configured_expression' ] def clean_configured_expression(self): try: ExpressionFactory.from_spec( self.cleaned_data['configured_expression'], FactoryContext.empty()) except BadSpecError as e: raise ValidationError(e) return self.cleaned_data['configured_expression'] def clean_configured_filter(self): try: FilterFactory.from_spec(self.cleaned_data['configured_filter']) except BadSpecError as e: raise ValidationError(e) return self.cleaned_data['configured_filter']
class OpenmrsConfigForm(forms.Form): case_config = JsonField(expected_type=dict) form_configs = JsonField(expected_type=list) def __init__(self, *args, **kwargs): super(OpenmrsConfigForm, self).__init__(*args, **kwargs) self.helper = FormHelper() self.helper.add_input(Submit('submit', _('Save Changes')))
class ConfigurableDataSourceEditForm(DocumentFormBase): table_id = forms.CharField(label=_("Table ID"), help_text=help_text.TABLE_ID) referenced_doc_type = forms.ChoiceField(choices=DOC_TYPE_CHOICES, label=_("Source Type")) display_name = forms.CharField(label=_("Report Title"), help_text=help_text.DISPLAY_NAME) description = forms.CharField(required=False, help_text=help_text.DESCRIPTION) base_item_expression = JsonField(expected_type=dict, help_text=help_text.BASE_ITEM_EXPRESSION) configured_filter = JsonField(expected_type=dict, help_text=help_text.CONFIGURED_FILTER) configured_indicators = JsonField( expected_type=list, help_text=help_text.CONFIGURED_INDICATORS) named_filters = JsonField(required=False, expected_type=dict, label=_("Named filters (optional)"), help_text=help_text.NAMED_FILTER) def __init__(self, domain, *args, **kwargs): self.domain = domain super(ConfigurableDataSourceEditForm, self).__init__(*args, **kwargs) def clean_table_id(self): # todo: validate table_id as [a-z][a-z0-9_]* table_id = self.cleaned_data['table_id'] table_name = get_table_name(self.domain, table_id) if len(table_name) > 63: # max table name length for postgres raise ValidationError( _('Table id is too long. Your table id and domain name must add up to fewer than 40 characters' )) for src in self.instance.by_domain(self.domain): if src.table_id == table_id and src.get_id != self.instance.get_id: raise ValidationError( _('A data source with this table id already exists. Table' ' ids must be unique')) return table_id def clean(self): cleaned_data = super(ConfigurableDataSourceEditForm, self).clean() # only call additional validation if initial validation has passed for all fields for field in self.fields: if field not in cleaned_data: return try: config = self.populate_instance(self.instance, cleaned_data) config.validate() except Exception, e: if settings.DEBUG: raise raise ValidationError( _(u'Problem with data source spec: {}').format(e)) return cleaned_data
class AdvancedPerformanceMessageEditForm(PerformanceFormMixin, forms.Form): recipient_id = forms.CharField() schedule = JsonField() template = forms.CharField(widget=forms.Textarea) template_variables = JsonField(expected_type=list) def __init__(self, domain, config, *args, **kwargs): self.domain = domain self.config = config super(AdvancedPerformanceMessageEditForm, self).__init__(initial=config.to_json(), *args, **kwargs) self.fields['recipient_id'] = GroupField(domain=domain, label=_('Recipient Group')) 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_schedule(self): return ScheduleConfiguration.wrap(self.cleaned_data['schedule']) def _apply_updates_to_config(self, config, cleaned_data): config.recipient_id = cleaned_data['recipient_id'] config.schedule = cleaned_data['schedule'] config.template = cleaned_data['template'] config.template_variables = cleaned_data['template_variables'] return config def clean_template_variables(self): template_vars = self.cleaned_data['template_variables'] if not isinstance(template_vars, list): raise forms.ValidationError( _('Template variables must be a list!')) wrapped_vars = [] for var in template_vars: try: wrapped = TemplateVariable.wrap(var) wrapped.validate() wrapped_vars.append(wrapped) except Exception as e: raise forms.ValidationError( _(u'Problem wrapping template variable! {}').format(e)) return wrapped_vars
class OpenmrsConfigForm(forms.Form): openmrs_provider = forms.CharField(label=_("Provider UUID"), required=False) patient_config = JsonField(expected_type=dict) encounters_config = JsonField(expected_type=list) def __init__(self, *args, **kwargs): super(OpenmrsConfigForm, self).__init__(*args, **kwargs) self.helper = FormHelper() self.helper.add_input(Submit('submit', _('Save Changes'))) def clean_patient_config(self): for key in self.cleaned_data['patient_config']['person_properties']: if key not in PERSON_PROPERTIES: raise ValidationError( _('person property key "%(key)s" is not valid.'), code='invalid', params={'key': key}) for key in self.cleaned_data['patient_config'][ 'person_preferred_name']: if key not in NAME_PROPERTIES: raise ValidationError( _('person preferred name key "%(key)s" is not valid.'), code='invalid', params={'key': key}) for key in self.cleaned_data['patient_config'][ 'person_preferred_address']: if key not in ADDRESS_PROPERTIES: raise ValidationError( _('person preferred address key "%(key)s" is not valid.'), code='invalid', params={'key': key}) for id_ in self.cleaned_data['patient_config']['match_on_ids']: if id_ not in self.cleaned_data['patient_config'][ 'patient_identifiers']: raise ValidationError(_( 'ID "%(id_)s" used in "match_on_ids" is missing from "patient_identifiers".' ), code='invalid', params={'id_': id_}) return self.cleaned_data['patient_config']
class ConfigureListReportForm(ConfigureNewReportBase): report_type = 'list' columns = JsonField(required=True) column_legend_fine_print = _( "Add columns to your report to display information from cases or form submissions. You may rearrange the order of the columns by dragging the arrows next to the column." ) @property def container_fieldset(self): return crispy.Fieldset("", self.column_fieldset, self.filter_fieldset) @property def column_fieldset(self): return crispy.Fieldset( _legend(_("Columns"), self.column_legend_fine_print), crispy.Div(crispy.HTML(self.column_config_template), id="columns-table", data_bind='with: columnsList'), crispy.Hidden('columns', None, data_bind="value: columnsList.serializedProperties")) @property @memoized def initial_columns(self): if self.existing_report: cols = [] for c in self.existing_report.columns: exists = self._column_exists(c['field']) cols.append( ColumnViewModel( display_text=c['display'], exists_in_current_version=exists, property=self._get_property_from_column(c['field']) if exists else None, data_source_field=c['field'] if not exists else None, )) return cols return [] @property def _report_columns(self): def _make_column(conf): return { "format": "default", "aggregation": "simple", "field": self.data_source_properties[conf['property']]['column_id'], "type": "field", "display": conf['display_text'] } return [_make_column(conf) for conf in self.cleaned_data['columns']] @property def _report_aggregation_cols(self): return ['doc_id']
class Dhis2ConfigForm(forms.Form): form_configs = JsonField(expected_type=list) def __init__(self, *args, **kwargs): super(Dhis2ConfigForm, self).__init__(*args, **kwargs) self.helper = FormHelper() self.helper.add_input(Submit('submit', _('Save Changes'))) def clean_form_configs(self): errors = _validate_form_configs(self.cleaned_data['form_configs']) if errors: raise ValidationError(errors) return self.cleaned_data['form_configs']
class Dhis2ConfigForm(forms.Form): form_configs = JsonField(expected_type=list) def __init__(self, *args, **kwargs): super(Dhis2ConfigForm, self).__init__(*args, **kwargs) self.helper = FormHelper() self.helper.add_input(Submit('submit', _('Save Changes'))) def clean_form_configs(self): errors = [] for form_config in self.cleaned_data['form_configs']: if form_config.get('xmlns'): required_msg = _('The "%(property)s" property is required for ' 'form "{}".').format(form_config['xmlns']) else: required_msg = _('The "%(property)s" property is required.') if not form_config.get('program_id'): errors.append( ValidationError( '{} {}'.format( required_msg, _('Please specify the DHIS2 Program of the event.') ), params={'property': 'program_id'}, code='required_property', )) if not form_config.get('event_date'): errors.append( ValidationError( '{} {}'.format( required_msg, _('Please provide a FormQuestion, FormQuestionMap or ' 'ConstantString to determine the date of the event.' )), params={'property': 'event_date'}, code='required_property', )) if not form_config.get('datavalue_maps'): errors.append( ValidationError( '{} {}'.format( required_msg, _('Please map CommCare values to OpenMRS data elements.' )), params={'property': 'datavalue_maps'}, code='required_property', )) if errors: raise ValidationError(errors) return self.cleaned_data['form_configs']
class ConfigurableReportEditForm(DocumentFormBase): config_id = forms.ChoiceField() # gets overridden on instantiation title = forms.CharField() visible = forms.ChoiceField(label=_('Visible to:'), choices=VISIBILITY_CHOICES) description = forms.CharField(required=False) aggregation_columns = JsonField(expected_type=list) filters = JsonField(expected_type=list) columns = JsonField(expected_type=list) configured_charts = JsonField(expected_type=list) sort_expression = JsonField(expected_type=list) def __init__(self, domain, instance=None, read_only=False, *args, **kwargs): super(ConfigurableReportEditForm, self).__init__(instance, read_only, *args, **kwargs) self.fields['config_id'] = ReportDataSourceField(domain=domain) def clean_visible(self): return self.cleaned_data['visible'] == 'True' def clean(self): cleaned_data = super(ConfigurableReportEditForm, self).clean() # only call additional validation if initial validation has passed for all fields for field in self.fields: if field not in cleaned_data: return try: config = self.populate_instance(self.instance, cleaned_data) config.validate() except Exception, e: raise ValidationError(_(u'Problem with report spec: {}').format(e)) return cleaned_data
class OpenmrsConfigForm(forms.Form): openmrs_provider = forms.CharField(label=_('Provider UUID'), required=False) case_config = JsonField(expected_type=dict) form_configs = JsonField(expected_type=list) def __init__(self, *args, **kwargs): super(OpenmrsConfigForm, self).__init__(*args, **kwargs) self.helper = FormHelper() self.helper.add_input(Submit('submit', _('Save Changes'))) def clean_case_config(self): for key in self.cleaned_data['case_config']['person_properties']: if key not in PERSON_PROPERTIES: raise ValidationError( _('person property key "%(key)s" is not valid.'), code='invalid', params={'key': key} ) for key in self.cleaned_data['case_config']['person_preferred_name']: if key not in NAME_PROPERTIES: raise ValidationError( _('person preferred name key "%(key)s" is not valid.'), code='invalid', params={'key': key} ) for key in self.cleaned_data['case_config']['person_preferred_address']: if key not in ADDRESS_PROPERTIES: raise ValidationError( _('person preferred address key "%(key)s" is not valid.'), code='invalid', params={'key': key} ) return self.cleaned_data['case_config']
class Dhis2EntityConfigForm(forms.Form): """ Dhis2EntityConfig.case_configs is a list. Dhis2EntityConfigForm has one case_config, and is used in a formset. """ case_config = JsonField() def clean_case_config(self): errors = [] case_config = self.cleaned_data['case_config'] if not isinstance(case_config, dict): raise ValidationError(_( 'The "case_type" property is a dictionary, not a "%(data_type)s".' ), params={ 'data_type': type(case_config).__name__ }) if not case_config.get('case_type'): errors.append( ValidationError( _('The "%(property)s" property is required.'), params={'property': 'case_type'}, code='required_property', )) if 'form_configs' not in case_config: errors.append( ValidationError( _('The "%(property)s" property is required.'), params={'property': 'form_configs'}, code='required_property', )) elif not isinstance(case_config['form_configs'], list): raise ValidationError(_( 'The "form_configs" property is a dictionary, not a "%(data_type)s".' ), params={ 'data_type': type( case_config['form_configs']).__name__ }) else: errors.extend(_validate_form_configs(case_config['form_configs'])) if errors: raise ValidationError(errors) return self.cleaned_data['case_config']
def __init__(self, request, *args, **kwargs): super().__init__(*args, **kwargs) self.domain = request.domain self.fields['description'] = forms.CharField(required=False) self.fields['definition'] = JsonField(initial={ "type": "property_name", "property_name": "name" }) self.helper = HQFormHelper() self.helper.layout = crispy.Layout( crispy.Fieldset( _('Expression'), crispy.Field('name'), crispy.Field('expression_type'), crispy.Field('description'), crispy.Field('definition'), )) self.helper.add_input(crispy.Submit('submit', _('Save'))) self.helper.render_required_fields = True
class ConfigurableReportEditForm(DocumentFormBase): config_id = forms.ChoiceField() # gets overridden on instantiation title = forms.CharField() visible = forms.ChoiceField(label=_('Visible to:'), choices=VISIBILITY_CHOICES) description = forms.CharField(required=False) aggregation_columns = JsonField(expected_type=list) filters = JsonField(expected_type=list) columns = JsonField(expected_type=list) configured_charts = JsonField(expected_type=list) sort_expression = JsonField(expected_type=list) def __init__(self, domain, instance=None, read_only=False, *args, **kwargs): super(ConfigurableReportEditForm, self).__init__(instance, read_only, *args, **kwargs) self.fields['config_id'] = ReportDataSourceField(domain=domain) self.helper = FormHelper() 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( _("Report Configuration"), 'config_id', 'title', 'visible', 'description', 'aggregation_columns', 'filters', 'columns', 'configured_charts', 'sort_expression', ), hqcrispy.FormActions( twbscrispy.StrictButton( _("Save Changes"), type="submit", css_class="btn btn-primary", ), ), ) def clean_visible(self): return self.cleaned_data['visible'] == 'True' def clean(self): cleaned_data = super(ConfigurableReportEditForm, self).clean() # only call additional validation if initial validation has passed for all fields for field in self.fields: if field not in cleaned_data: return try: config = self.populate_instance(self.instance, cleaned_data) config.validate() except Exception, e: raise ValidationError(_(u'Problem with report spec: {}').format(e)) return cleaned_data
class OpenmrsImporterForm(forms.Form): server_url = forms.CharField(label=_('OpenMRS URL'), required=True, help_text=_('e.g. "http://www.example.com/openmrs"')) username = forms.CharField(label=_('Username'), required=True) password = forms.CharField(label=_('Password'), widget=forms.PasswordInput, required=False) location_id = forms.CharField(label=_('Location ID'), required=False, help_text='If a project space has multiple OpenMRS servers to import from, for ' 'which CommCare location is this OpenMRS server authoritative?') import_frequency = forms.ChoiceField(label=_('Import Frequency'), choices=IMPORT_FREQUENCY_CHOICES, help_text=_('How often should cases be imported?'), required=False) log_level = forms.TypedChoiceField(label=_('Log Level'), required=False, choices=LOG_LEVEL_CHOICES, coerce=int) report_uuid = forms.CharField(label=_('Report UUID'), required=True, help_text=_('The OpenMRS UUID of the report of patients to be imported')) report_params = JsonField(label=_('Report Parameters'), required=False, expected_type=dict) case_type = forms.CharField(label=_('Case Type'), required=True) owner_id = forms.CharField(label=_owner_id_label, required=False, help_text=_('The ID of the mobile worker or location who will own new cases')) location_type_name = forms.CharField(label=_location_type_name_label, required=False, help_text=_('The Organization Level whose mobile worker will own new ' 'cases')) external_id_column = forms.CharField(label=_('External ID Column'), required=True, help_text=_("The column that contains the OpenMRS UUID of the patient")) name_columns = forms.CharField(label=_('Name Columns'), required=True, help_text=_('Space-separated column(s) to be concatenated to create the case ' 'name (e.g. "givenName familyName")')) column_map = JsonField(label=_('Map columns to properties'), required=True, expected_type=list, help_text=_('e.g. [{"column": "givenName", "property": "first_name"}, ...]')) def clean(self): cleaned_data = super(OpenmrsImporterForm, self).clean() if bool(cleaned_data.get('owner_id')) == bool(cleaned_data.get('location_type_name')): message = _( 'The owner of imported patient cases is determined using either "{owner_id}" or ' '"{location_type_name}". Please specify either one or the other.').format( owner_id=_owner_id_label, location_type_name=_location_type_name_label) self.add_error('owner_id', message) self.add_error('location_type_name', message) return self.cleaned_data def save(self, domain_name): try: importers = get_openmrs_importers_by_domain(domain_name) importer = importers[0] if importers else None # TODO: Support multiple if importer is None: importer = OpenmrsImporter(domain=domain_name) importer.server_url = self.cleaned_data['server_url'] importer.username = self.cleaned_data['username'] if self.cleaned_data['password']: # Don't save it if it hasn't been changed. importer.password = b64_aes_encrypt(self.cleaned_data['password']) importer.location_id = self.cleaned_data['location_id'] importer.import_frequency = self.cleaned_data['import_frequency'] importer.log_level = self.cleaned_data['log_level'] importer.report_uuid = self.cleaned_data['report_uuid'] importer.report_params = self.cleaned_data['report_params'] importer.case_type = self.cleaned_data['case_type'] importer.owner_id = self.cleaned_data['owner_id'] importer.location_type_name = self.cleaned_data['location_type_name'] importer.external_id_column = self.cleaned_data['external_id_column'] importer.name_columns = self.cleaned_data['name_columns'] importer.column_map = list(map(ColumnMapping.wrap, self.cleaned_data['column_map'])) importer.save() return True except Exception as err: logging.error('Unable to save OpenMRS Importer: %s' % err) return False
class OpenmrsImporterForm(forms.Form): server_url = forms.CharField( label=_('OpenMRS URL'), required=True, help_text=_('e.g. "http://www.example.com/openmrs"')) username = forms.CharField(label=_('Username'), required=True) password = forms.CharField(label=_('Password'), widget=forms.PasswordInput, required=False) notify_addresses_str = forms.CharField( label=_('Addresses to send notifications'), required=False, help_text=_('A comma-separated list of email addresses to send error ' 'notifications')) location_id = forms.CharField( label=_('Location ID'), required=False, help_text=_( 'If a project space has multiple OpenMRS servers to import from, ' 'for which CommCare location is this OpenMRS server authoritative?' )) import_frequency = forms.ChoiceField( label=_('Import Frequency'), choices=IMPORT_FREQUENCY_CHOICES, help_text=_('How often should cases be imported?'), required=False) log_level = forms.TypedChoiceField(label=_('Log Level'), required=False, choices=LOG_LEVEL_CHOICES, coerce=int) timezone = forms.CharField( label=_('Timezone'), required=False, help_text= _("Timezone name. If not specified, the domain's timezone will be used." )) report_uuid = forms.CharField( label=_('Report UUID'), required=True, help_text=_( 'The OpenMRS UUID of the report of patients to be imported')) report_params = JsonField(label=_('Report Parameters'), required=False, expected_type=dict) case_type = forms.CharField(label=_('Case Type'), required=True) owner_id = forms.CharField( label=_owner_id_label, required=False, help_text=_( 'The ID of the mobile worker or location who will own new cases')) location_type_name = forms.CharField( label=_location_type_name_label, required=False, help_text=_('The Organization Level whose mobile worker will own new ' 'cases')) external_id_column = forms.CharField( label=_('External ID Column'), required=True, help_text=_( "The column that contains the OpenMRS UUID of the patient")) name_columns = forms.CharField( label=_('Name Columns'), required=True, help_text=_( 'Space-separated column(s) to be concatenated to create the case ' 'name (e.g. "givenName familyName")')) column_map = JsonField( label=_('Map columns to properties'), required=True, expected_type=list, help_text=_( 'e.g. [{"column": "givenName", "property": "first_name"}, ...]'))
class ConfigurableDataSourceEditForm(DocumentFormBase): _id = forms.CharField(required=False, disabled=True, label=_('Data Source ID'), help_text=help_text.DATA_SOURCE_ID) table_id = forms.CharField(label=_("Table ID"), help_text=help_text.TABLE_ID) referenced_doc_type = forms.ChoiceField(choices=DOC_TYPE_CHOICES, label=_("Source Type")) display_name = forms.CharField(label=_("Data Source Display Name"), help_text=help_text.DISPLAY_NAME) description = forms.CharField(required=False, help_text=help_text.DESCRIPTION) base_item_expression = JsonField(expected_type=dict, help_text=help_text.BASE_ITEM_EXPRESSION) configured_filter = JsonField(expected_type=dict, help_text=help_text.CONFIGURED_FILTER) configured_indicators = JsonField( expected_type=list, help_text=help_text.CONFIGURED_INDICATORS) named_expressions = JsonField(required=False, expected_type=dict, label=_("Named expressions (optional)"), help_text=help_text.NAMED_EXPRESSIONS) named_filters = JsonField(required=False, expected_type=dict, label=_("Named filters (optional)"), help_text=help_text.NAMED_FILTER) asynchronous = forms.BooleanField( initial=False, required=False, label="", widget=BootstrapCheckboxInput(inline_label="Asynchronous processing")) def __init__(self, domain, data_source_config, read_only, *args, **kwargs): self.domain = domain super(ConfigurableDataSourceEditForm, self).__init__(data_source_config, read_only, *args, **kwargs) if toggles.LOCATIONS_IN_UCR.enabled(domain): choices = self.fields['referenced_doc_type'].choices choices.append(('Location', _('locations'))) self.fields['referenced_doc_type'].choices = choices self.helper = FormHelper() 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' fields = [ 'table_id', 'referenced_doc_type', 'display_name', 'description', 'base_item_expression', 'configured_filter', 'configured_indicators', 'named_expressions', 'named_filters', 'asynchronous', ] if data_source_config.get_id: fields.append('_id') self.helper.layout = crispy.Layout( crispy.Fieldset(_("Edit Data Source"), *fields), hqcrispy.FormActions( twbscrispy.StrictButton( _("Save Changes"), type="submit", css_class="btn btn-primary", ), ), ) def clean_table_id(self): # todo: validate table_id as [a-z][a-z0-9_]* table_id = self.cleaned_data['table_id'] table_name = get_table_name(self.domain, table_id) if len(table_name) > 63: # max table name length for postgres raise ValidationError( _('Table id is too long. Your table id and domain name must add up to fewer than 40 characters' )) for src in self.instance.by_domain(self.domain): if src.table_id == table_id and src.get_id != self.instance.get_id: raise ValidationError( _('A data source with this table id already exists. Table' ' ids must be unique')) return table_id def clean(self): cleaned_data = super(ConfigurableDataSourceEditForm, self).clean() # only call additional validation if initial validation has passed for all fields for field in self.fields: if field not in cleaned_data: return try: config = self.populate_instance(self.instance, cleaned_data) config.validate() except Exception as e: if settings.DEBUG: raise raise ValidationError( _('Problem with data source spec: {}').format(e)) return cleaned_data def save(self, commit=False): self.instance.meta.build.finished = False self.instance.meta.build.initiated = None return super(ConfigurableDataSourceEditForm, self).save(commit)
class ConfigurableReportEditForm(DocumentFormBase): _id = forms.CharField(required=False, disabled=True, label=_('Report ID'), help_text=help_text.REPORT_ID) config_id = forms.ChoiceField() # gets overridden on instantiation title = forms.CharField() visible = forms.ChoiceField(label=_('Visible to:'), choices=VISIBILITY_CHOICES) description = forms.CharField(required=False) aggregation_columns = JsonField(expected_type=list) filters = JsonField(expected_type=list) columns = JsonField(expected_type=list) configured_charts = JsonField(expected_type=list) sort_expression = JsonField(expected_type=list) def __init__(self, domain, instance=None, read_only=False, *args, **kwargs): super(ConfigurableReportEditForm, self).__init__(instance, read_only, *args, **kwargs) self.fields['config_id'] = ReportDataSourceField(domain=domain) self.helper = FormHelper() 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' fields = [ 'config_id', 'title', 'visible', 'description', 'aggregation_columns', 'filters', 'columns', 'configured_charts', 'sort_expression', ] if instance.config_id: fields.append('_id') self.helper.layout = crispy.Layout( crispy.Fieldset(_("Report Configuration"), *fields), ) # Restrict edit for static reports if not read_only: self.helper.layout.append( hqcrispy.FormActions( twbscrispy.StrictButton( _("Save Changes"), type="submit", css_class="btn btn-primary", ), )) def clean_visible(self): return self.cleaned_data['visible'] == 'True' def clean(self): cleaned_data = super(ConfigurableReportEditForm, self).clean() # only call additional validation if initial validation has passed for all fields for field in self.fields: if field not in cleaned_data: return try: config = self.populate_instance(self.instance, cleaned_data) config.validate() except Exception as e: raise ValidationError(_('Problem with report spec: {}').format(e)) return cleaned_data def save(self, commit=False): self.instance.report_meta.edited_manually = True if toggles.AGGREGATE_UCRS.enabled(self.instance.domain): # hack - if the ID looks like a guid, assume it is non-aggregate, else aggregate try: UUID(self.instance.config_id) self.instance.data_source_type = DATA_SOURCE_TYPE_STANDARD except ValueError: self.instance.data_source_type = DATA_SOURCE_TYPE_AGGREGATE return super(ConfigurableReportEditForm, self).save(commit)
class OpenmrsImporterForm(forms.Form): server_url = forms.CharField(label=_('OpenMRS URL'), required=True, help_text=_('e.g. "http://www.example.com/openmrs"')) username = forms.CharField(label=_('Username'), required=True) password = forms.CharField(label=_('Password'), widget=forms.PasswordInput, required=False) import_frequency = forms.ChoiceField(label=_('Import Frequency'), choices=IMPORT_FREQUENCY_CHOICES, help_text=_('How often should cases be imported?'), required=False) log_level = forms.TypedChoiceField(label=_('Log Level'), required=False, choices=LOG_LEVEL_CHOICES, coerce=int) report_uuid = forms.CharField(label=_('Report UUID'), required=True, help_text=_('The OpenMRS UUID of the report of patients to be imported')) report_params = JsonField(label=_('Report Parameters'), required=False, expected_type=dict) case_type = forms.CharField(label=_('Case Type'), required=True) owner_id = forms.CharField(label=_('Owner ID'), required=False, help_text=_('The ID of the mobile worker or location who will own new cases')) location_type_name = forms.CharField(label=_('Organization Level'), required=False, help_text=_('The Organization Level whose owners will own new cases')) external_id_column = forms.CharField(label=_('External ID Column'), required=True, help_text=_("The column that stores the case's external ID")) name_columns = forms.CharField(label=_('Name Columns'), required=True, help_text=_('Space-separated column(s) to be concatenated to create the case ' 'name (e.g. "givenName familyName")')) column_map = JsonField(label=_('Map columns to properties'), required=True, expected_type=list, help_text=_('e.g. [{"column": "givenName", "property": "first_name"}, ...]')) def __init__(self, *args, **kwargs): super(OpenmrsImporterForm, self).__init__(*args, **kwargs) self.helper = FormHelper() self.helper.form_class = 'form-horizontal' 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.layout = crispy.Layout( crispy.Fieldset( _('Edit OpenMRS Importer'), crispy.Field('server_url'), crispy.Field('username'), crispy.Field('password'), crispy.Field('import_frequency'), crispy.Field('log_level'), crispy.Field('report_uuid'), crispy.Field('report_params'), crispy.Field('case_type'), crispy.Field('owner_id'), crispy.Field('location_type_name'), crispy.Field('external_id_column'), crispy.Field('name_columns'), crispy.Field('column_map'), ), hqcrispy.FormActions( StrictButton( _("Update OpenMRS Importer"), type="submit", css_class='btn-primary', ), StrictButton( _('Import Now'), type='button', id='btn-import-now', css_class='btn-default', ), ), ) def save(self, domain_name): try: importers = get_openmrs_importers_by_domain(domain_name) importer = importers[0] if importers else None # TODO: Support multiple if importer is None: importer = OpenmrsImporter(domain=domain_name) importer.server_url = self.cleaned_data['server_url'] importer.username = self.cleaned_data['username'] if self.cleaned_data['password']: # Don't save it if it hasn't been changed. importer.password = b64_aes_encrypt(self.cleaned_data['password']) importer.import_frequency = self.cleaned_data['import_frequency'] importer.log_level = self.cleaned_data['log_level'] importer.report_uuid = self.cleaned_data['report_uuid'] importer.report_params = self.cleaned_data['report_params'] importer.case_type = self.cleaned_data['case_type'] importer.owner_id = self.cleaned_data['owner_id'] importer.location_type_name = self.cleaned_data['location_type_name'] importer.external_id_column = self.cleaned_data['external_id_column'] importer.name_columns = self.cleaned_data['name_columns'] importer.column_map = map(ColumnMapping.wrap, self.cleaned_data['column_map']) importer.save() return True except Exception as err: logging.error('Unable to save OpenMRS Importer: %s' % err) return False