Beispiel #1
0
 def add_fields(self, form, index):
     """A hook for adding extra fields on to each form instance."""
     initial_form_count = self.initial_form_count()
     if self.can_order:
         # Only pre-fill the ordering field for initial forms.
         if index is not None and index < initial_form_count:
             form.fields[ORDERING_FIELD_NAME] = IntegerField(
                 label=_('Order'),
                 initial=index + 1,
                 required=False,
                 widget=self.get_ordering_widget(),
             )
         else:
             form.fields[ORDERING_FIELD_NAME] = IntegerField(
                 label=_('Order'),
                 required=False,
                 widget=self.get_ordering_widget(),
             )
     if self.can_delete and (self.can_delete_extra
                             or index < initial_form_count):
         form.fields[DELETION_FIELD_NAME] = BooleanField(label=_('Delete'),
                                                         required=False)
Beispiel #2
0
class MobileContactCreateForm(ContactQuickForm):
    is_favorite = BooleanField(label=pgettext_lazy('mobile-contact',
                                                   'Is favorite'),
                               required=False)

    class Meta(ContactQuickForm.Meta):
        fields = ('last_name', 'first_name', 'phone', 'mobile', 'email')
        widgets = {
            'phone': PhoneInput,
            'mobile': PhoneInput,
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.instance.user = self.user
        # del self.fields['user']

        errors = self.errors

        for fname, field in self.fields.items():
            if fname != 'is_favorite':
                attrs = field.widget.attrs
                attrs['class'] = 'form-input' if fname not in errors else \
                                 'form-input form-input-invalid'

                if field.required:
                    attrs['required'] = ''

    def clean(self):
        self.cleaned_data['user'] = self.user  # NB: used in super().clean()
        return super().clean()

    def save(self, *args, **kwargs):
        contact = super().save(*args, **kwargs)

        if self.cleaned_data['is_favorite']:
            MobileFavorite.objects.create(entity=contact, user=self.user)

        return contact
Beispiel #3
0
class MessageCreateForm(ModelForm):
    close_it = BooleanField(required=False)

    class Meta:
        model = Message
        fields = ['text', 'close_it']

    def __init__(self, request, ticket, *args, **kwargs):
        super(MessageCreateForm, self).__init__(*args, **kwargs)
        self.request = request
        self.ticket = ticket
        self.fields['close_it'].initial = False

    def save(self, commit=True):
        obj = super(MessageCreateForm, self).save(commit=False)
        obj.owner = self.request.user
        obj.ticket = self.ticket
        obj.save()
        if self.request.user.is_staff and self.cleaned_data['close_it']:
            obj.ticket.close(self.request.user)
        else:
            obj.ticket.touch(self.request.user)
        return obj
Beispiel #4
0
class SnapshotApplicationForm(forms.Form):
    publish = BooleanField(label=ugettext_noop("Publish?"), required=False)
    name = CharField(label=ugettext_noop("Name"), required=True)
    description = CharField(label=ugettext_noop("Description"), required=False, widget=forms.Textarea,
        help_text=ugettext_noop("A detailed technical description of the application"))
    deployment_date = CharField(label=ugettext_noop("Deployment date"), required=False)
    phone_model = CharField(label=ugettext_noop("Phone model"), required=False)
    user_type = CharField(label=ugettext_noop("User type"), required=False,
        help_text=ugettext_noop("e.g. CHW, ASHA, RA, etc"))
    attribution_notes = CharField(label=ugettext_noop("Attribution notes"), required=False,
        help_text=ugettext_noop("Enter any special instructions to users here. This will be shown just before users copy your project."), widget=forms.Textarea)

    def __init__(self, *args, **kwargs):
        super(SnapshotApplicationForm, self).__init__(*args, **kwargs)
        self.fields.keyOrder = [
            'publish',
            'name',
            'description',
            'deployment_date',
            'phone_model',
            'user_type',
            'attribution_notes'
        ]
Beispiel #5
0
class WorkoutFormCreate(ModelForm):
    duration = DecimalField(
        min_value=0,
        max_value=40,
        max_digits=5,
        label="Duration (15 min blocks)",
        help_text="e.g., for a 30 minute workout, enter '2'.")

    with_other_class = BooleanField(
        label="With different class?",
        help_text="BONUS POINTS! Select this if you worked out with" +
        "a teammates from a different graduating class, like a" +
        "Sophomore with a Junior.")

    workout_date = DateField(initial=datetime.today,
                             widget=SelectDateWidget(years=(2015, 2016)),
                             label="Workout Date",
                             help_text="When did you do the workout?")

    activity = ModelChoiceField(
        queryset=Activity.objects.order_by('description'))

    class Meta:
        model = Workout
        fields = [  # Appears in the form in this order:
            'workout_date',
            'activity',
            'with_other_class',
            'duration',
        ]
        exclude = [
            'user',
        ]

    def __init__(self, user=None, *args, **kwargs):
        super(WorkoutFormCreate, self).__init__(*args, **kwargs)
        self._user = user
Beispiel #6
0
def import_common_template(request):
    if not request.is_trust:
        return JsonResponse({
            'result': False,
            'message': 'you have no permission to call this api.'
        })

    try:
        req_data = json.loads(request.body)
    except Exception:
        return JsonResponse({
            'result': False,
            'message': 'invalid json format'
        })

    template_data = req_data.get('template_data', None)
    if not template_data:
        return JsonResponse({
            'result': False,
            'message': 'template data can not be none'
        })
    r = read_encoded_template_data(template_data)
    if not r['result']:
        return JsonResponse(r)

    override = BooleanField().to_python(req_data.get('override', False))

    try:
        import_result = CommonTemplate.objects.import_templates(r['data']['template_data'], override)
    except Exception as e:
        logger.exception(e)
        return JsonResponse({
            'result': False,
            'message': 'invalid flow data or error occur, please contact administrator'
        })

    return JsonResponse(import_result)
Beispiel #7
0
class FormularioLogin(forms.Form):
    """!
    Clase que permite crear el formulario de ingreso a la aplicación

    @author Ing. Leonel P. Hernandez M. (leonelphm at gmail.com)
    @copyright <a href='https://www.gnu.org/licenses/gpl-3.0.en.html'>GNU Public License versión 3 (GPLv3)</a>
    @date 09-01-2017
    @version 1.0.0
    """
    contrasena = CharField()
    usuario = CharField()
    remember_me = BooleanField()
    captcha = CaptchaField()

    class Meta:
        fields = ('usuario', 'contrasena', 'remember_me' 'captcha')

    def __init__(self, *args, **kwargs):
        super(FormularioLogin, self).__init__(*args, **kwargs)
        self.fields['contrasena'].widget = PasswordInput()
        self.fields['contrasena'].widget.attrs.update({
            'class':
            'form-control',
            'placeholder':
            'Contraseña'
        })
        self.fields['usuario'].widget.attrs.update({
            'class':
            'form-control',
            'placeholder':
            'Nombre de Usuario'
        })
        self.fields['remember_me'].label = "Recordar"
        self.fields['remember_me'].widget = CheckboxInput()
        self.fields['remember_me'].required = False
        self.fields['captcha'].required = True
Beispiel #8
0
class SecurityForm(BaseModelForm):
    new_password = CharField(widget=PasswordInput, required=False)
    repeat_new_password = CharField(widget=PasswordInput, required=False)
    change_password = BooleanField(required=False)
    current_password = CharField(widget=PasswordInput, required=True)

    def clean_current_password(self):
        current_password = self.cleaned_data.get('current_password', '')
        if not self.request.user.check_password(current_password):
            raise ValidationError(_('The current password is incorrect.'))
        return current_password

    def clean_new_password(self):
        new_password = self.cleaned_data.get('new_password')
        if self.cleaned_data['change_password'] and not new_password:
            raise ValidationError(_('The password can not be empty.'))
        return new_password

    def clean_repeat_new_password(self):
        new_password = self.cleaned_data.get('new_password', '')
        repeat_new_password = self.cleaned_data.get('repeat_new_password', '')
        if self.cleaned_data[
                'change_password'] and new_password != repeat_new_password:
            raise ValidationError(_('Password do not match.'))
        return repeat_new_password

    def save(self, commit=True):
        if self.cleaned_data.get('change_password'):
            new_password = self.cleaned_data['new_password']
            self.instance.set_password(new_password)
        super(SecurityForm, self).save()

    class Meta:
        fields = ('email', 'change_password', 'new_password',
                  'repeat_new_password')
        model = get_user_model()
Beispiel #9
0
class MarkerForm(ModelForm):
    title = CharField(
        label=_("Marker Title"),
        widget=widgets.TextInput(attrs={'size': 60}),
        help_text=_(
            "Please choose a title, then go to the map to set a marker pin"))

    use_icon = BooleanField(
        label=_("Use customized marker icon"),
        initial=False,
        required=False,
    )

    marker_image = ModelChoiceField(
        queryset=Image.objects.all(),
        label=_("Marker Image"),
        required=False,
    )

    marker_width = GlossaryFormField(
        widget=CascadingSizeWidget(allowed_units=['px'], required=False),
        label=_("Marker Width"),
        required=False,
        help_text=_("Width of the marker icon in pixels."),
    )

    marker_anchor = GlossaryFormField(
        widget=MultipleCascadingSizeWidget(['left', 'top'],
                                           allowed_units=['px', '%'],
                                           required=False),
        required=False,
        label=_("Marker Anchor"),
        help_text=
        _("The coordinates of the icon's anchor (relative to its top left corner)."
          ),
    )

    popup_text = HTMLFormField(
        required=False,
        help_text=_("Optional rich text to display in popup."),
    )

    position = Field(widget=widgets.HiddenInput)

    glossary_field_order = [
        'title', 'marker_width', 'marker_anchor', 'popup_text'
    ]

    class Meta:
        exclude = ['glossary']

    def __init__(self, *args, **kwargs):
        try:
            initial = dict(kwargs['instance'].glossary)
            has_original = True
        except (KeyError, AttributeError):
            initial = {}
            has_original = False
        initial.update(kwargs.pop('initial', {}))
        self.base_fields['position'].initial = json.dumps(
            initial.pop('position', {}))
        for key in self.glossary_field_order:
            self.base_fields[key].initial = initial.get(key)
        try:
            self.base_fields['marker_image'].initial = initial['image']['pk']
        except KeyError:
            self.base_fields['marker_image'].initial = None
            self.base_fields['use_icon'].initial = False
        else:
            self.base_fields['use_icon'].initial = True
        self.base_fields['marker_image'].widget = AdminFileWidget(
            ManyToOneRel(FilerImageField, Image, 'file_ptr'), site)
        super(MarkerForm, self).__init__(*args, **kwargs)
        if has_original:
            self.fields['title'].help_text = None

    def clean(self):
        try:
            position = self.cleaned_data['position']
            if isinstance(position, six.string_types):
                position = json.loads(position)
            elif not isinstance(position, dict):
                raise ValueError
        except (ValueError, KeyError):
            raise ValidationError(
                "Invalid internal position data. Check your Javascript imports."
            )
        else:
            if 'lat' not in position or 'lng' not in position:
                # place the marker in the center of the current map
                position = {
                    k: v
                    for k, v in self.instance.cascade_element.
                    glossary['map_position'].items() if k in ['lat', 'lng']
                }
            self.instance.glossary.update(position=position)

        marker_image = self.cleaned_data.pop('marker_image', None)
        if marker_image:
            image_data = {'pk': marker_image.pk, 'model': 'filer.Image'}
            self.instance.glossary.update(image=image_data)
        else:
            self.instance.glossary.pop('image', None)

        popup_text = self.cleaned_data.pop('popup_text', None)
        if strip_tags(popup_text):
            popup_text = strip_spaces_between_tags(popup_text)
            self.cleaned_data.update(popup_text=popup_text)

        for key in self.glossary_field_order:
            self.instance.glossary.update({key: self.cleaned_data.get(key)})
Beispiel #10
0
class SnapshotSettingsForm(SnapshotSettingsMixin):
    title = CharField(label=ugettext_noop("Title"),
                      required=True,
                      max_length=100)
    project_type = CharField(label=ugettext_noop("Project Category"),
                             required=True,
                             help_text=ugettext_noop("e.g. MCH, HIV, etc."))
    license = ChoiceField(label=ugettext_noop("License"),
                          required=True,
                          choices=LICENSES.items(),
                          widget=Select(attrs={'class': 'input-xxlarge'}))
    description = CharField(
        label=ugettext_noop("Long Description"),
        required=False,
        widget=forms.Textarea,
        help_text=ugettext_noop(
            "A high-level overview of your project as a whole"))
    short_description = CharField(
        label=ugettext_noop("Short Description"),
        required=False,
        widget=forms.Textarea(attrs={'maxlength': 200}),
        help_text=ugettext_noop(
            "A brief description of your project (max. 200 characters)"))
    share_multimedia = BooleanField(
        label=ugettext_noop("Share all multimedia?"),
        required=False,
        help_text=ugettext_noop(
            "This will allow any user to see and use all multimedia in this project"
        ))
    share_reminders = BooleanField(
        label=ugettext_noop("Share Reminders?"),
        required=False,
        help_text=ugettext_noop(
            "This will publish reminders along with this project"))
    image = forms.ImageField(
        label=ugettext_noop("Exchange image"),
        required=False,
        help_text=ugettext_noop(
            "An optional image to show other users your logo or what your app looks like"
        ))
    video = CharField(
        label=ugettext_noop("Youtube Video"),
        required=False,
        help_text=ugettext_noop(
            "An optional youtube clip to tell users about your app. Please copy and paste a URL to a youtube video"
        ))
    cda_confirmed = BooleanField(
        required=False, label=ugettext_noop("Content Distribution Agreement"))

    def __init__(self, *args, **kw):
        super(SnapshotSettingsForm, self).__init__(*args, **kw)
        self.fields.keyOrder = [
            'title',
            'short_description',
            'description',
            'project_type',
            'image',
            'video',
            'share_multimedia',
            'share_reminders',
            'license',
            'cda_confirmed',
        ]
        self.fields['license'].help_text = \
            render_to_string('domain/partials/license_explanations.html', {
                'extra': _("All un-licensed multimedia files in "
                           "your project will be given this license")
            })
        self.fields['cda_confirmed'].help_text = \
            render_to_string('domain/partials/cda_modal.html')

    def clean_cda_confirmed(self):
        data_cda = self.cleaned_data['cda_confirmed']
        data_publish = self.data.get('publish_on_submit', "no") == "yes"
        if data_publish and data_cda is False:
            raise forms.ValidationError(
                'You must agree to our Content Distribution Agreement to publish your project.'
            )
        return data_cda

    def clean_video(self):
        video = self.cleaned_data['video']
        if not video:
            return video

        def video_id(value):
            # http://stackoverflow.com/questions/4356538/how-can-i-extract-video-id-from-youtubes-link-in-python#answer-7936523
            """
            Examples:
            - http://youtu.be/SA2iWivDJiE
            - http://www.youtube.com/watch?v=_oPAwA_Udwc&feature=feedu
            - http://www.youtube.com/embed/SA2iWivDJiE
            - http://www.youtube.com/v/SA2iWivDJiE?version=3&amp;hl=en_US
            """
            query = urlparse(value)
            if query.hostname == 'youtu.be':
                return query.path[1:]
            if query.hostname in ('www.youtube.com', 'youtube.com'):
                if query.path == '/watch':
                    p = parse_qs(query.query)
                    return p['v'][0]
                if query.path[:7] == '/embed/':
                    return query.path.split('/')[2]
                if query.path[:3] == '/v/':
                    return query.path.split('/')[2]
                    # fail?
            return None

        v_id = video_id(video)
        if not v_id:
            raise forms.ValidationError(
                'This is not a correctly formatted youtube URL. Please use a different URL.'
            )
        return v_id

    def clean(self):
        cleaned_data = self.cleaned_data
        sm = cleaned_data["share_multimedia"]
        license = cleaned_data["license"]
        app_ids = self._get_apps_to_publish()

        if sm and license not in self.dom.most_restrictive_licenses(
                apps_to_check=app_ids):
            license_choices = [
                LICENSES[l] for l in self.dom.most_restrictive_licenses(
                    apps_to_check=app_ids)
            ]
            msg = render_to_string('domain/partials/restrictive_license.html',
                                   {'licenses': license_choices})
            self._errors["license"] = self.error_class([msg])

            del cleaned_data["license"]

        sr = cleaned_data["share_reminders"]
        if sr:  # check that the forms referenced by the events in each reminders exist in the project
            referenced_forms = CaseReminderHandler.get_referenced_forms(
                domain=self.dom.name)
            if referenced_forms:
                apps = [Application.get(app_id) for app_id in app_ids]
                app_forms = [
                    f.unique_id for forms in [app.get_forms() for app in apps]
                    for f in forms
                ]
                nonexistent_forms = filter(lambda f: f not in app_forms,
                                           referenced_forms)
                nonexistent_forms = [
                    FormBase.get_form(f) for f in nonexistent_forms
                ]
                if nonexistent_forms:
                    msg = """
                        Your reminders reference forms that are not being published.
                        Make sure the following forms are being published: %s
                    """ % str([f.default_name()
                               for f in nonexistent_forms]).strip('[]')
                    self._errors["share_reminders"] = self.error_class([msg])

        return cleaned_data

    def _get_apps_to_publish(self):
        app_ids = []
        for d, val in self.data.iteritems():
            d = d.split('-')
            if len(d) < 2:
                continue
            if d[1] == 'publish' and val == 'on':
                app_ids.append(d[0])

        return app_ids
Beispiel #11
0
class DomainMetadataForm(DomainGlobalSettingsForm, SnapshotSettingsMixin):
    customer_type = ChoiceField(label=_("Customer Type"),
                                choices=(('basic', _('Basic')), ('plus',
                                                                 _('Plus')),
                                         ('full', _('Full'))))
    is_test = ChoiceField(label=_("Test Project"),
                          choices=(('true', _('Test')), ('false', _('Real')),
                                   ('none', _('Not Sure'))))
    commconnect_enabled = BooleanField(
        label=_("CommConnect Enabled"),
        required=False,
        help_text=_("CommConnect is a CommCareHQ module for SMS messages, "
                    "reminders and data collection."))
    survey_management_enabled = BooleanField(
        label=_("Survey Management Enabled"),
        required=False,
        help_text=_("Survey Management is a CommCareHQ module for SMS and "
                    "Call Center based surveys for large samples.  It is "
                    "under active development. Do not enable for your domain "
                    "unless you're piloting it."))
    sms_case_registration_enabled = BooleanField(
        label=_("Enable Case Registration Via SMS"), required=False)
    sms_case_registration_type = CharField(
        label=_("SMS Case Registration Type"), required=False)
    sms_case_registration_owner_id = ChoiceField(
        label=_("SMS Case Registration Owner"), required=False, choices=[])
    sms_case_registration_user_id = ChoiceField(
        label=_("SMS Case Registration Submitting User"),
        required=False,
        choices=[])
    default_sms_backend_id = CharField(
        label=_("Default SMS Backend"),
        required=False,
        help_text=_("This SMS backend will be used if a contact has no "
                    "backend specified."))
    call_center_enabled = BooleanField(
        label=_("Call Center Application"),
        required=False,
        help_text=_("Call Center mode is a CommCareHQ module for managing "
                    "call center workflows. It is still under "
                    "active development. Do not enable for your domain unless "
                    "you're actively piloting it."))
    call_center_case_owner = ChoiceField(
        label=_("Call Center Case Owner"),
        initial=None,
        required=False,
        help_text=_("Select the person who will be listed as the owner "
                    "of all cases created for call center users."))
    call_center_case_type = CharField(
        label=_("Call Center Case Type"),
        required=False,
        help_text=_(
            "Enter the case type to be used for FLWs in call center apps"))
    restrict_superusers = BooleanField(
        label=_("Restrict Superuser Access"),
        required=False,
        help_text=_("If access to a domain is restricted only users added " +
                    "to the domain and staff members will have access."))
    ota_restore_caching = BooleanField(
        label=_("Enable Restore Caching (beta)"),
        required=False,
        help_text=_(
            "Speed up phone restores. Useful if you have users with "
            "large case lists and are getting timeouts during restore. "
            "This feature is still in testing. Don't enable unless "
            "you are an advanced user."))
    secure_submissions = BooleanField(
        label=_("Only accept secure submissions"),
        required=False,
        help_text=_(
            "Turn this on to prevent others from impersonating your "
            "mobile workers. To use, all of your deployed applications "
            "must be using secure submissions."),
    )
    cloudcare_releases = ChoiceField(
        label=_("CloudCare should use"),
        initial=None,
        required=False,
        choices=(
            ('stars', _('Latest starred version')),
            ('nostars', _('Every version (not recommended)')),
        ),
        help_text=_("Choose whether CloudCare should use the latest "
                    "starred build or every build in your application."))

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user', None)
        domain = kwargs.pop('domain', None)
        super(DomainMetadataForm, self).__init__(*args, **kwargs)

        if not (user and user.is_previewer):
            self.fields['call_center_enabled'].widget = forms.HiddenInput()
            self.fields['call_center_case_owner'].widget = forms.HiddenInput()
            self.fields['call_center_case_type'].widget = forms.HiddenInput()

        if not (user and user.is_staff):
            self.fields['restrict_superusers'].widget = forms.HiddenInput()

        project = Domain.get_by_name(domain)
        if project.cloudcare_releases == 'default' or not domain_has_privilege(
                domain, privileges.CLOUDCARE):
            # if the cloudcare_releases flag was just defaulted, don't bother showing
            # this setting at all
            self.fields['cloudcare_releases'].widget = forms.HiddenInput()

        if domain is not None:
            groups = Group.get_case_sharing_groups(domain)
            users = CommCareUser.by_domain(domain)

            domain_group_choices = [(group._id, group.name)
                                    for group in groups]
            domain_user_choices = [(user._id, user.raw_username)
                                   for user in users]
            domain_owner_choices = domain_group_choices + domain_user_choices

            self.fields[
                "sms_case_registration_owner_id"].choices = domain_owner_choices
            self.fields[
                "sms_case_registration_user_id"].choices = domain_user_choices

            call_center_user_choices = [
                (user._id, user.raw_username + ' [user]') for user in users
            ]
            call_center_group_choices = [(group._id, group.name + ' [group]')
                                         for group in groups]

            self.fields["call_center_case_owner"].choices = \
                [('', '')] + \
                call_center_user_choices + \
                call_center_group_choices

    def _validate_sms_registration_field(self, field_name, error_msg):
        value = self.cleaned_data.get(field_name)
        if value is not None:
            value = value.strip()
        if self.cleaned_data.get("sms_case_registration_enabled", False):
            if value is None or value == "":
                raise forms.ValidationError(error_msg)
        return value

    def clean_sms_case_registration_type(self):
        return self._validate_sms_registration_field(
            "sms_case_registration_type",
            _("Please enter a default case type for cases that register themselves via sms."
              ))

    def clean_sms_case_registration_owner_id(self):
        return self._validate_sms_registration_field(
            "sms_case_registration_owner_id",
            _("Please enter a default owner for cases that register themselves via sms."
              ))

    def clean_sms_case_registration_user_id(self):
        return self._validate_sms_registration_field(
            "sms_case_registration_user_id",
            _("Please enter a default submitting user for cases that register themselves via sms."
              ))

    def save(self, request, domain):
        res = DomainGlobalSettingsForm.save(self, request, domain)

        if not res:
            return False
        try:
            domain.project_type = self.cleaned_data['project_type']
            domain.customer_type = self.cleaned_data['customer_type']
            domain.is_test = self.cleaned_data['is_test']
            domain.commconnect_enabled = self.cleaned_data.get(
                'commconnect_enabled', False)
            domain.survey_management_enabled = self.cleaned_data.get(
                'survey_management_enabled', False)
            domain.sms_case_registration_enabled = self.cleaned_data.get(
                'sms_case_registration_enabled', False)
            domain.sms_case_registration_type = self.cleaned_data.get(
                'sms_case_registration_type')
            domain.sms_case_registration_owner_id = self.cleaned_data.get(
                'sms_case_registration_owner_id')
            domain.sms_case_registration_user_id = self.cleaned_data.get(
                'sms_case_registration_user_id')
            domain.default_sms_backend_id = self.cleaned_data.get(
                'default_sms_backend_id')
            domain.call_center_config.enabled = self.cleaned_data.get(
                'call_center_enabled', False)
            if domain.call_center_config.enabled:
                domain.internal.using_call_center = True
                domain.call_center_config.case_owner_id = self.cleaned_data.get(
                    'call_center_case_owner', None)
                domain.call_center_config.case_type = self.cleaned_data.get(
                    'call_center_case_type', None)
            domain.restrict_superusers = self.cleaned_data.get(
                'restrict_superusers', False)
            domain.ota_restore_caching = self.cleaned_data.get(
                'ota_restore_caching', False)
            cloudcare_releases = self.cleaned_data.get('cloudcare_releases')
            if cloudcare_releases and domain.cloudcare_releases != 'default':
                # you're never allowed to change from default
                domain.cloudcare_releases = cloudcare_releases
            secure_submissions = self.cleaned_data.get('secure_submissions',
                                                       False)
            apps_to_save = []
            if secure_submissions != domain.secure_submissions:
                for app in ApplicationBase.by_domain(domain.name):
                    if app.secure_submissions != secure_submissions:
                        app.secure_submissions = secure_submissions
                        apps_to_save.append(app)
            domain.secure_submissions = secure_submissions
            domain.save()
            if apps_to_save:
                ApplicationBase.bulk_save(apps_to_save)
            return True
        except Exception, e:
            logging.exception("couldn't save project settings - error is %s" %
                              e)
            return False
Beispiel #12
0
class MarkerForm(EntangledModelForm):
    title = CharField(
        label=_("Marker Title"),
        widget=widgets.TextInput(attrs={'size': 60}),
        help_text=_(
            "Please choose a title, then go to the map to set a marker pin"))

    use_icon = BooleanField(
        label=_("Use customized marker icon"),
        initial=False,
        required=False,
    )

    marker_image = AdminImageFormField(
        ManyToOneRel(FilerImageField, Image, 'file_ptr'),
        Image.objects.all(),
        label=_("Marker Image"),
        required=False,
        to_field_name='image_file',
    )

    marker_width = SizeField(
        label=_("Marker Width"),
        allowed_units=['px'],
        required=False,
        help_text=_("Width of the marker icon in pixels."),
    )

    marker_anchor = MultiSizeField(
        ['left', 'top'],
        label=_("Marker Anchor"),
        allowed_units=['px', '%'],
        required=False,
        help_text=
        _("The coordinates of the icon's anchor (relative to its top left corner)."
          ),
    )

    popup_text = HTMLFormField(
        required=False,
        help_text=_("Optional rich text to display in popup."),
    )

    position = HiddenDictField()

    class Meta:
        entangled_fields = {
            'glossary': [
                'title', 'use_icon', 'marker_image', 'marker_width',
                'marker_anchor', 'popup_text', 'position'
            ]
        }

    def clean(self):
        cleaned_data = super().clean()
        try:
            position = cleaned_data['position']
            if isinstance(position, str):
                position = json.loads(position)
            elif not isinstance(position, dict):
                raise ValueError
        except (ValueError, KeyError):
            raise ValidationError(
                "Invalid internal position data. Check your Javascript imports."
            )
        else:
            if 'lat' not in position or 'lng' not in position:
                # place the marker in the center of the current map
                position = {
                    k: v
                    for k, v in self.instance.cascade_element.
                    glossary['map_position'].items() if k in ['lat', 'lng']
                }
                cleaned_data['position'] = position

        popup_text = cleaned_data.pop('popup_text', '')
        if strip_tags(popup_text):
            cleaned_data['popup_text'] = strip_spaces_between_tags(popup_text)
        return cleaned_data
Beispiel #13
0
class PLMObjectCreationForm(forms.ModelForm):

    auto = BooleanField(
        required=False,
        initial=True,
        help_text=
        _("Checking this box, you allow OpenPLM to set the reference of the object."
          ))

    clean_reference = _clean_reference
    clean_revision = _clean_revision

    def __init__(self, user, start, inbulk_cache, *args, **kwargs):
        data = kwargs.get("data")
        if data is None:
            initial = get_initial_creation_data(user, self.Meta.model, start,
                                                inbulk_cache)
            initial.update(kwargs.pop("initial", {}))
            kwargs["initial"] = initial
        self.start = start
        self.inbulk_cache = inbulk_cache
        self.user = user
        super(PLMObjectCreationForm, self).__init__(*args, **kwargs)
        # lifecycles and groups are cached if inbulk_cache is a dictionary
        # this is an optimization if several creation forms are displayed
        # in one request
        # for example, the decomposition of a STEP file can display
        # a lot of creation forms

        # display only valid groups
        field = self.fields["group"]
        field.cache_choices = inbulk_cache is not None

        if inbulk_cache is None or "group" not in inbulk_cache:
            groups = user.groups.all().values_list("id", flat=True)
            field.queryset = m.GroupInfo.objects.filter(
                id__in=groups).order_by("name")
            if inbulk_cache is not None:
                # a bit ugly but ModelChoiceField reevalute the
                # queryset if cache_choices is False and choice_cache
                # is not populated
                inbulk_cache["group"] = field.queryset
                list(field.choices)  # populates choice_cache
                inbulk_cache["gr_cache"] = field.choice_cache
        else:
            field.queryset = inbulk_cache["group"]
            field.choice_cache = inbulk_cache["gr_cache"]
        field.error_messages["invalid_choice"] = INVALID_GROUP
        if data is None and "group" not in initial:
            # set initial value of group to the last selected group
            try:
                field.initial = inbulk_cache["gr_initial"]
            except (KeyError, TypeError):
                try:
                    last_created_object = m.PLMObject.objects.filter(
                        creator=user).order_by("-ctime")[0]
                    last_group = last_created_object.group
                except IndexError:
                    last_group = field.queryset[0] if field.queryset else None
                if last_group in field.queryset:
                    field.initial = last_group
                if inbulk_cache:
                    inbulk_cache["gr_initial"] = field.initial

        # do not accept the cancelled lifecycle
        field = self.fields["lifecycle"]
        field.cache_choices = inbulk_cache is not None
        if inbulk_cache is None or "lifecycles" not in inbulk_cache:
            lifecycles = m.Lifecycle.objects.filter(type=m.Lifecycle.STANDARD).\
                    exclude(pk=m.get_cancelled_lifecycle().pk).order_by("name")
            self.fields["lifecycle"].queryset = lifecycles
            if inbulk_cache is not None:
                inbulk_cache["lifecycles"] = lifecycles
                list(field.choices)
                inbulk_cache["lc_cache"] = field.choice_cache
        else:
            lifecycles = inbulk_cache["lifecycles"]
            self.fields["lifecycle"].queryset = lifecycles
            field.choice_cache = inbulk_cache["lc_cache"]

    def clean(self):
        cleaned_data = self.cleaned_data
        ref = cleaned_data.get("reference", "")
        rev = cleaned_data.get("revision", "")
        auto = cleaned_data.get("auto", False)
        inbulk = getattr(self, "inbulk_cache")
        cls = self.Meta.model
        user = self.user
        if auto and not ref:
            cleaned_data["reference"] = ref = get_new_reference(
                user, cls, self.start, inbulk)
        if not auto and not ref:
            self.errors['reference'] = [
                _("You did not check the Auto box: the reference is required.")
            ]
        if cls.objects.filter(type=cls.__name__, revision=rev,
                              reference=ref).exists():
            if not auto:
                raise ValidationError(
                    _("An object with the same type, reference and revision already exists"
                      ))
            else:
                cleaned_data["reference"] = get_new_reference(
                    user, cls, self.start, inbulk)
        elif cls.objects.filter(type=cls.__name__, reference=ref).exists():
            raise ValidationError(
                _("An object with the same type and reference exists, you may consider to revise it."
                  ))
        return cleaned_data
Beispiel #14
0
class HttpBackendForm(BackendForm):
    url = TrimmedCharField(
        label=ugettext_noop("URL"),
    )
    message_param = TrimmedCharField(
        label=ugettext_noop("Message Parameter"),
    )
    number_param = TrimmedCharField(
        label=ugettext_noop("Phone Number Parameter"),
    )
    include_plus = BooleanField(
        required=False,
        label=ugettext_noop("Include '+' in Phone Number"),
    )
    method = ChoiceField(
        label=ugettext_noop("HTTP Request Method"),
        choices=(
            ("GET", "GET"),
            ("POST", "POST")
        ),
    )
    additional_params = RecordListField(
        input_name="additional_params",
        label=ugettext_noop("Additional Parameters"),
    )

    def __init__(self, *args, **kwargs):
        if "initial" in kwargs and "additional_params" in kwargs["initial"]:
            additional_params_dict = kwargs["initial"]["additional_params"]
            kwargs["initial"]["additional_params"] = [
                {"name": key, "value": value}
                for key, value in additional_params_dict.items()
            ]
        super(HttpBackendForm, self).__init__(*args, **kwargs)

    def clean_url(self):
        value = self.cleaned_data.get("url")
        if is_url_or_host_banned(value):
            raise ValidationError(_("Invalid URL"))
        return value

    def clean_additional_params(self):
        value = self.cleaned_data.get("additional_params")
        result = {}
        for pair in value:
            name = pair["name"].strip()
            value = pair["value"].strip()
            if name == "" or value == "":
                raise ValidationError("Please enter both name and value.")
            if name in result:
                raise ValidationError("Parameter name entered twice: %s" % name)
            result[name] = value
        return result

    @property
    def gateway_specific_fields(self):
        return crispy.Fieldset(
            _("HTTP Settings"),
            'url',
            'method',
            'message_param',
            'number_param',
            'include_plus',
            'additional_params',
        )
Beispiel #15
0
class DomainMetadataForm(DomainGlobalSettingsForm, SnapshotSettingsMixin):
    customer_type = ChoiceField(label='Customer Type',
                                choices=(('basic', 'Basic'), ('plus', 'Plus'),
                                         ('full', 'Full')))
    is_test = ChoiceField(label='Test Project',
                          choices=tf_choices('Test', 'Real'))
    survey_management_enabled = BooleanField(label='Survey Management Enabled',
                                             required=False)
    sms_case_registration_enabled = BooleanField(
        label='Enable Case Registration Via SMS', required=False)
    sms_case_registration_type = CharField(label='SMS Case Registration Type',
                                           required=False)
    sms_case_registration_owner_id = ChoiceField(
        label='SMS Case Registration Owner', required=False, choices=[])
    sms_case_registration_user_id = ChoiceField(
        label='SMS Case Registration Submitting User',
        required=False,
        choices=[])
    default_sms_backend_id = CharField(
        label="Default SMS Backend",
        required=False,
        help_text=
        "This SMS backend will be used if a contact has no backend specified.")
    commtrack_enabled = BooleanField(
        label='CommTrack Enabled',
        required=False,
        help_text=
        'CommTrack is a CommCareHQ module for logistics, inventory tracking, and supply chain management. It is still under active development. Do not enable for your domain unless you\'re actively piloting it.'
    )

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user', None)
        domain = kwargs.pop('domain', None)
        super(DomainMetadataForm, self).__init__(*args, **kwargs)
        if not (user and user.is_previewer):
            # commtrack is pre-release
            self.fields['commtrack_enabled'].widget = forms.HiddenInput()

        if domain is not None:
            groups = Group.get_case_sharing_groups(domain)
            users = CommCareUser.by_domain(domain)

            domain_owner_choices = [(group._id, group.name)
                                    for group in groups]
            domain_user_choices = [(user._id, user.raw_username)
                                   for user in users]
            domain_owner_choices += domain_user_choices

            self.fields[
                "sms_case_registration_owner_id"].choices = domain_owner_choices
            self.fields[
                "sms_case_registration_user_id"].choices = domain_user_choices

    def _validate_sms_registration_field(self, field_name, error_msg):
        value = self.cleaned_data.get(field_name)
        if value is not None:
            value = value.strip()
        if self.cleaned_data.get("sms_case_registration_enabled", False):
            if value is None or value == "":
                raise forms.ValidationError(error_msg)
        return value

    def clean_sms_case_registration_type(self):
        return self._validate_sms_registration_field(
            "sms_case_registration_type",
            _("Please enter a default case type for cases that register themselves via sms."
              ))

    def clean_sms_case_registration_owner_id(self):
        return self._validate_sms_registration_field(
            "sms_case_registration_owner_id",
            _("Please enter a default owner for cases that register themselves via sms."
              ))

    def clean_sms_case_registration_user_id(self):
        return self._validate_sms_registration_field(
            "sms_case_registration_user_id",
            _("Please enter a default submitting user for cases that register themselves via sms."
              ))

    def save(self, request, domain):
        res = DomainGlobalSettingsForm.save(self, request, domain)
        if not res:
            return False
        try:
            domain.project_type = self.cleaned_data['project_type']
            domain.customer_type = self.cleaned_data['customer_type']
            domain.is_test = self.cleaned_data['is_test'] == 'true'
            domain.survey_management_enabled = self.cleaned_data.get(
                'survey_management_enabled', False)
            domain.sms_case_registration_enabled = self.cleaned_data.get(
                'sms_case_registration_enabled', False)
            domain.sms_case_registration_type = self.cleaned_data.get(
                'sms_case_registration_type')
            domain.sms_case_registration_owner_id = self.cleaned_data.get(
                'sms_case_registration_owner_id')
            domain.sms_case_registration_user_id = self.cleaned_data.get(
                'sms_case_registration_user_id')
            domain.default_sms_backend_id = self.cleaned_data.get(
                'default_sms_backend_id')
            domain.commtrack_enabled = self.cleaned_data.get(
                'commtrack_enabled', False)
            commtrack_util.bootstrap_default(domain)
            domain.save()
            return True
        except Exception:
            return False
Beispiel #16
0
class ConfirmTOSForm(Form):
    confirm = BooleanField(required=True)
Beispiel #17
0
def add_delete_field_to_form():
    DeadlineForm.base_fields["DELETE"] = BooleanField(required=False)
    yield
    del DeadlineForm.base_fields["DELETE"]
Beispiel #18
0
class KeywordForm(Form):
    domain = None
    keyword_id = None
    keyword = CharField(label=gettext_noop("Keyword"))
    description = TrimmedCharField(label=gettext_noop("Description"))
    override_open_sessions = BooleanField(
        required=False,
        initial=False,
        label=gettext_noop("Override open SMS Surveys"),
    )
    allow_keyword_use_by = ChoiceField(
        required=False,
        label=gettext_noop("Allow Keyword Use By"),
        initial='any',
        choices=(
            ('any', gettext_noop("Both Mobile Workers and Cases")),
            ('users', gettext_noop("Mobile Workers Only")),
            ('cases', gettext_noop("Cases Only")),
        ))
    sender_content_type = ChoiceField(label=gettext_noop("Send to Sender"), )
    sender_message = TrimmedCharField(
        required=False,
        label=gettext_noop("Message"),
    )
    sender_app_and_form_unique_id = ChoiceField(
        required=False,
        label=gettext_noop("Survey"),
    )
    other_recipient_content_type = ChoiceField(
        required=False,
        label=gettext_noop("Notify Another Person"),
        initial=NO_RESPONSE,
    )
    other_recipient_type = ChoiceField(
        required=False,
        initial=False,
        label=gettext_noop("Recipient"),
        choices=KEYWORD_RECIPIENT_CHOICES,
    )
    other_recipient_id = ChoiceField(
        required=False,
        label=gettext_noop("Group Name"),
    )
    other_recipient_message = TrimmedCharField(
        required=False,
        label=gettext_noop("Message"),
    )
    other_recipient_app_and_form_unique_id = ChoiceField(
        required=False,
        label=gettext_noop("Survey"),
    )
    process_structured_sms = BooleanField(
        required=False,
        label=gettext_noop(
            "Process incoming keywords as a Structured Message"),
    )
    structured_sms_app_and_form_unique_id = ChoiceField(
        required=False,
        label=gettext_noop("Survey"),
    )
    use_custom_delimiter = BooleanField(
        required=False,
        label=gettext_noop("Use Custom Delimiter"),
    )
    delimiter = TrimmedCharField(
        required=False,
        label=gettext_noop("Please Specify Delimiter"),
    )
    use_named_args_separator = BooleanField(
        required=False,
        label=gettext_noop("Use Joining Character"),
    )
    use_named_args = BooleanField(
        required=False,
        label=gettext_noop("Use Named Answers"),
    )
    named_args_separator = TrimmedCharField(
        required=False,
        label=gettext_noop("Please Specify Joining Characcter"),
    )
    named_args = RecordListField(
        input_name="named_args",
        initial=[],
    )

    def __init__(self, *args, **kwargs):
        if 'domain' in kwargs:
            self.domain = kwargs.pop('domain')

        if 'keyword_id' in kwargs:
            self.keyword_id = kwargs.pop('keyword_id')

        self.process_structured_sms = False
        if 'process_structured' in kwargs:
            self.process_structured_sms = kwargs.pop('process_structured')

        super(KeywordForm, self).__init__(*args, **kwargs)

        self.fields['sender_content_type'].choices = self.content_type_choices
        self.fields[
            'other_recipient_content_type'].choices = self.content_type_choices

        self.fields['other_recipient_id'].choices = self.group_choices
        self.fields[
            'sender_app_and_form_unique_id'].choices = self.form_choices
        self.fields[
            'other_recipient_app_and_form_unique_id'].choices = self.form_choices
        self.fields[
            'structured_sms_app_and_form_unique_id'].choices = self.form_choices

        from corehq.apps.reminders.views import KeywordsListView
        self.helper = FormHelper()
        self.helper.form_class = "form 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'

        layout_fields = [
            crispy.Fieldset(
                _('Basic Information'),
                crispy.Field(
                    'keyword',
                    data_bind="value: keyword, "
                    "valueUpdate: 'afterkeydown', "
                    "event: {keyup: updateExampleStructuredSMS}",
                ),
                crispy.Field(
                    'description',
                    data_bind="text: description",
                ),
            ),
        ]
        if self.process_structured_sms:
            layout_fields.append(
                crispy.Fieldset(
                    _("Structured Message Options"),
                    crispy.Field(
                        'structured_sms_app_and_form_unique_id',
                        data_bind="value: structuredSmsAppAndFormUniqueId",
                        css_class="hqwebapp-select2",
                    ),
                    hqcrispy.B3MultiField(
                        _("Delimiters"),
                        crispy.Div(
                            crispy.Div(InlineField(
                                twbscrispy.PrependedText(
                                    'use_custom_delimiter',
                                    '',
                                    data_bind="checked: useCustomDelimiter, "
                                    "click: updateExampleStructuredSMS"),
                                block_css_class="span2",
                            ),
                                       css_class='col-md-4 col-lg-4'),
                            crispy.Div(InlineField(
                                'delimiter',
                                data_bind="value: delimiter, "
                                "valueUpdate: 'afterkeydown', "
                                "event: {keyup: updateExampleStructuredSMS},"
                                "visible: useCustomDelimiter",
                                block_css_class="span4",
                            ),
                                       css_class='col-md-4 col-lg-4')),
                    ),
                    hqcrispy.B3MultiField(
                        _("Named Answers"),
                        crispy.Div(InlineField(
                            twbscrispy.PrependedText(
                                'use_named_args',
                                '',
                                data_bind="checked: useNamedArgs, "
                                "click: updateExampleStructuredSMS"), ),
                                   css_class='col-md-4 col-lg-4'),
                        hqcrispy.ErrorsOnlyField('named_args'),
                        crispy.Div(data_bind="template: {"
                                   " name: 'ko-template-named-args', "
                                   " data: $data"
                                   "}, "
                                   "visible: useNamedArgs", ),
                    ),
                    hqcrispy.B3MultiField(
                        _("Joining Characters"),
                        crispy.Div(
                            crispy.Div(InlineField(
                                twbscrispy.PrependedText(
                                    'use_named_args_separator',
                                    '',
                                    data_bind="checked: useNamedArgsSeparator, "
                                    "click: updateExampleStructuredSMS"), ),
                                       css_class='col-md-4 col-lg-4'),
                            crispy.Div(InlineField(
                                'named_args_separator',
                                data_bind="value: namedArgsSeparator, "
                                "valueUpdate: 'afterkeydown', "
                                "event: {keyup: updateExampleStructuredSMS},"
                                "visible: useJoiningCharacter",
                            ),
                                       css_class='col-md-6 col-lg-4')),
                        data_bind="visible: useNamedArgs",
                    ),
                    hqcrispy.B3MultiField(
                        _("Example Structured Message"),
                        crispy.HTML('<pre style="background: white;" '
                                    'data-bind="text: exampleStructuredSms">'
                                    '</pre>'),
                    ),
                ), )
        layout_fields.extend([
            crispy.Fieldset(
                _("Response"),
                crispy.Field(
                    'sender_content_type',
                    data_bind="value: senderContentType",
                ),
                crispy.Div(
                    crispy.Field(
                        'sender_message',
                        data_bind="text: senderMessage",
                    ),
                    data_bind="visible: isMessageSMS",
                ),
                crispy.Div(
                    crispy.Field(
                        'sender_app_and_form_unique_id',
                        data_bind="value: senderAppAndFormUniqueId",
                        css_class="hqwebapp-select2",
                    ),
                    data_bind="visible: isMessageSurvey",
                ),
                crispy.Field(
                    'other_recipient_content_type',
                    data_bind="value: otherRecipientContentType",
                ),
                hqcrispy.B3MultiField(
                    "",
                    crispy.Div(
                        crispy.HTML(
                            '<h4 style="margin-bottom: 20px;">%s</h4>' %
                            _("Recipient Information"), ),
                        crispy.Field(
                            'other_recipient_type',
                            data_bind="value: otherRecipientType",
                        ),
                        crispy.Div(
                            crispy.Field(
                                'other_recipient_id',
                                data_bind="value: otherRecipientId",
                            ),
                            data_bind="visible: showRecipientGroup",
                        ),
                        crispy.Div(
                            crispy.Field(
                                'other_recipient_message',
                                data_bind="value: otherRecipientMessage",
                            ),
                            data_bind=
                            "visible: otherRecipientContentType() == 'sms'",
                        ),
                        crispy.Div(
                            crispy.Field(
                                'other_recipient_app_and_form_unique_id',
                                data_bind=
                                "value: otherRecipientAppAndFormUniqueId",
                                css_class="hqwebapp-select2",
                            ),
                            data_bind=
                            "visible: otherRecipientContentType() == 'survey'",
                        ),
                        css_class="well",
                        data_bind="visible: notifyOthers",
                    ),
                ),
            ),
            crispy.Fieldset(
                _("Advanced Options"),
                twbscrispy.PrependedText(
                    'override_open_sessions',
                    '',
                    data_bind="checked: overrideOpenSessions",
                ),
                'allow_keyword_use_by',
            ),
            hqcrispy.FormActions(
                twbscrispy.StrictButton(
                    _("Save"),
                    css_class='btn-primary',
                    type='submit',
                ),
                crispy.HTML(
                    '<a href="%s" class="btn btn-default">Cancel</a>' %
                    reverse(KeywordsListView.urlname, args=[self.domain]))),
        ])
        self.helper.layout = crispy.Layout(*layout_fields)

    @property
    def content_type_choices(self):
        return KEYWORD_CONTENT_CHOICES

    @property
    @memoized
    def group_choices(self):
        group_ids = Group.ids_by_domain(self.domain)
        groups = []
        for group_doc in iter_docs(Group.get_db(), group_ids):
            groups.append((group_doc['_id'], group_doc['name']))
        return groups

    @property
    @memoized
    def form_choices(self):
        available_forms = get_form_list(self.domain)
        return [('', '')] + [(form['code'], form['name'])
                             for form in available_forms]

    @property
    def current_values(self):
        values = {}
        for field_name in self.fields.keys():
            values[field_name] = self[field_name].value()
        return values

    def clean_keyword(self):
        value = self.cleaned_data.get("keyword")
        if value is not None:
            value = value.strip().upper()
        if value is None or value == "":
            raise ValidationError(_("This field is required."))
        if len(value.split()) > 1:
            raise ValidationError(_("Keyword should be one word."))
        duplicate = Keyword.get_keyword(self.domain, value)
        if duplicate and duplicate.couch_id != self.keyword_id:
            raise ValidationError(_("Keyword already exists."))
        return value

    def clean_sender_message(self):
        value = self.cleaned_data.get("sender_message")
        if self.cleaned_data.get("sender_content_type") == METHOD_SMS:
            if value is None or value == "":
                raise ValidationError(_("This field is required."))
            return value
        else:
            return None

    def clean_sender_app_and_form_unique_id(self):
        value = self.cleaned_data.get("sender_app_and_form_unique_id")
        if self.cleaned_data.get("sender_content_type") == METHOD_SMS_SURVEY:
            if value is None:
                raise ValidationError(
                    _("Please create a form first, and then add a keyword "
                      "for it."))
            validate_app_and_form_unique_id(value, self.domain)
            return value
        else:
            return None

    def clean_other_recipient_message(self):
        value = self.cleaned_data.get("other_recipient_message")
        if self.cleaned_data.get("other_recipient_content_type") == METHOD_SMS:
            if value is None or value == "":
                raise ValidationError(_("This field is required."))
            return value
        else:
            return None

    def clean_other_recipient_app_and_form_unique_id(self):
        value = self.cleaned_data.get("other_recipient_app_and_form_unique_id")
        if self.cleaned_data.get(
                "other_recipient_content_type") == METHOD_SMS_SURVEY:
            if value is None:
                raise ValidationError(
                    _("Please create a form first, and then "
                      "add a keyword for it."))
            validate_app_and_form_unique_id(value, self.domain)
            return value
        else:
            return None

    def clean_structured_sms_app_and_form_unique_id(self):
        value = self.cleaned_data.get("structured_sms_app_and_form_unique_id")
        if self.process_structured_sms:
            if value is None:
                raise ValidationError(
                    _("Please create a form first, and then add a "
                      "keyword for it."))
            validate_app_and_form_unique_id(value, self.domain)
            return value
        else:
            return None

    def clean_delimiter(self):
        value = self.cleaned_data.get("delimiter", None)
        if self.process_structured_sms and self.cleaned_data[
                "use_custom_delimiter"]:
            if value is None or value == "":
                raise ValidationError(_("This field is required."))
            return value
        else:
            return None

    def clean_named_args(self):
        if self.process_structured_sms and self.cleaned_data["use_named_args"]:
            use_named_args_separator = self.cleaned_data[
                "use_named_args_separator"]
            value = self.cleaned_data.get("named_args")
            data_dict = {}
            for d in value:
                name = d["name"].strip().upper()
                xpath = d["xpath"].strip()
                if name == "" or xpath == "":
                    raise ValidationError(
                        _("Name and xpath are both required fields."))
                for k, v in data_dict.items():
                    if (not use_named_args_separator
                            and (k.startswith(name) or name.startswith(k))):
                        raise ValidationError(
                            _("Cannot have two names overlap: ") + "(%s, %s)" %
                            (k, name))
                    if use_named_args_separator and k == name:
                        raise ValidationError(
                            _("Cannot use the same name twice: ") + name)
                    if v == xpath:
                        raise ValidationError(
                            _("Cannot reference the same xpath twice: ") +
                            xpath)
                data_dict[name] = xpath
            return data_dict
        else:
            return {}

    def clean_named_args_separator(self):
        value = self.cleaned_data["named_args_separator"]
        if (self.process_structured_sms and self.cleaned_data["use_named_args"]
                and self.cleaned_data["use_named_args_separator"]):
            if value is None or value == "":
                raise ValidationError(_("This field is required."))
            if value == self.cleaned_data["delimiter"]:
                raise ValidationError(
                    _("Delimiter and joining character cannot be the same."))
            return value
        else:
            return None

    def clean_other_recipient_type(self):
        if self.cleaned_data['other_recipient_content_type'] == NO_RESPONSE:
            return None
        value = self.cleaned_data["other_recipient_type"]
        if value == RECIPIENT_OWNER:
            if self.cleaned_data['allow_keyword_use_by'] != 'cases':
                raise ValidationError(
                    _("In order to send to the case's owner you must restrict "
                      "keyword initiation only to cases."))
        return value

    def clean_other_recipient_id(self):
        if self.cleaned_data['other_recipient_content_type'] == NO_RESPONSE:
            return None
        value = self.cleaned_data["other_recipient_id"]
        recipient_type = self.cleaned_data.get("other_recipient_type", None)
        if recipient_type == RECIPIENT_USER_GROUP:
            try:
                g = Group.get(value)
                assert g.doc_type == "Group"
                assert g.domain == self.domain
            except Exception:
                raise ValidationError("Invalid Group.")
            return value
        else:
            return None
Beispiel #19
0
class BackendForm(Form):
    domain = None
    backend_id = None
    name = CharField(label=ugettext_noop("Name"))
    display_name = CharField(
        label=ugettext_noop("Display Name"),
        required=False,
    )
    description = CharField(
        label=ugettext_noop("Description"),
        widget=forms.Textarea,
        required=False,
    )
    give_other_domains_access = BooleanField(
        required=False, label=ugettext_noop("Give other domains access."))
    authorized_domains = CharField(
        required=False,
        label=ugettext_noop("List of authorized domains"),
        help_text=ugettext_lazy("A comma-separated list of domain names"))
    reply_to_phone_number = CharField(
        required=False,
        label=ugettext_noop("Reply-To Phone Number"),
    )
    inbound_api_key = CharField(
        required=False,
        label=ugettext_lazy("Inbound API Key"),
        disabled=True,
    )
    opt_out_keywords = CharField(
        required=False,
        label=ugettext_noop("List of opt out keywords"),
        help_text=ugettext_lazy("A comma-separated list of keywords"))
    opt_in_keywords = CharField(
        required=False,
        label=ugettext_noop("List of opt in keywords"),
        help_text=ugettext_lazy("A comma-separated list of keywords"))

    @property
    def is_global_backend(self):
        return self.domain is None

    @property
    def general_fields(self):
        fields = [
            crispy.Field('name', css_class='input-xxlarge'),
            crispy.Field('display_name', css_class='input-xxlarge'),
            crispy.Field('description', css_class='input-xxlarge', rows="3"),
            crispy.Field('reply_to_phone_number', css_class='input-xxlarge'),
            crispy.Field('opt_out_keywords'),
            crispy.Field('opt_in_keywords')
        ]

        if not self.is_global_backend:
            fields.extend([
                crispy.Field(
                    twbscrispy.PrependedText(
                        'give_other_domains_access',
                        '',
                        data_bind="checked: share_backend")),
                crispy.Div(
                    'authorized_domains',
                    data_bind="visible: showAuthorizedDomains",
                ),
            ])

        if self.backend_id:
            backend = SQLMobileBackend.load(self.backend_id)
            if backend.show_inbound_api_key_during_edit:
                self.fields[
                    'inbound_api_key'].initial = backend.inbound_api_key
                fields.append(crispy.Field('inbound_api_key'))

        return fields

    def __init__(self, *args, **kwargs):
        button_text = kwargs.pop('button_text', _("Create SMS Gateway"))
        self.domain = kwargs.pop('domain')
        self.backend_id = kwargs.pop('backend_id')
        super(BackendForm, self).__init__(*args, **kwargs)
        self.helper = HQFormHelper()
        self.helper.form_method = 'POST'
        self.helper.layout = crispy.Layout(
            crispy.Fieldset(_('General Settings'), *self.general_fields),
            self.gateway_specific_fields,
            crispy.Fieldset(
                _("Phone Numbers"),
                crispy.Div(data_bind="template: {"
                           " name: 'ko-load-balancing-template', "
                           " data: $data"
                           "}", ),
                data_bind="visible: use_load_balancing",
            ),
            hqcrispy.FormActions(
                StrictButton(button_text,
                             type="submit",
                             css_class='btn-primary'), ),
        )

        if self.backend_id:
            #   When editing, don't allow changing the name because name might be
            # referenced as a contact-level backend preference.
            #   By setting disabled to True, Django makes sure the value won't change
            # even if something else gets posted.
            self.fields['name'].disabled = True

    @property
    def gateway_specific_fields(self):
        return crispy.Div()

    def clean_name(self):
        value = self.cleaned_data.get("name")
        if value is not None:
            value = value.strip().upper()
        if value is None or value == "":
            raise ValidationError(_("This field is required."))
        if re.compile(r"\s").search(value) is not None:
            raise ValidationError(_("Name may not contain any spaces."))

        if self.is_global_backend:
            # We're using the form to create a global backend, so
            # ensure name is not duplicated among other global backends
            is_unique = SQLMobileBackend.name_is_unique(
                value, backend_id=self.backend_id)
        else:
            # We're using the form to create a domain-level backend, so
            # ensure name is not duplicated among other backends owned by this domain
            is_unique = SQLMobileBackend.name_is_unique(
                value, domain=self.domain, backend_id=self.backend_id)

        if not is_unique:
            raise ValidationError(_("Name is already in use."))

        return value

    def clean_authorized_domains(self):
        if not self.cleaned_data.get("give_other_domains_access"):
            return []
        else:
            value = self.cleaned_data.get("authorized_domains")
            if value is None or value.strip() == "":
                return []
            else:
                return [domain.strip() for domain in value.split(",")]

    def clean_opt_out_keywords(self):
        keywords = self.cleaned_data.get('opt_out_keywords')
        if not keywords:
            return []
        else:
            return [kw.strip().upper() for kw in keywords.split(',')]

    def clean_opt_in_keywords(self):
        keywords = self.cleaned_data.get('opt_in_keywords')
        if not keywords:
            return []
        else:
            return [kw.strip().upper() for kw in keywords.split(',')]

    def clean_reply_to_phone_number(self):
        value = self.cleaned_data.get("reply_to_phone_number")
        if value is None:
            return None
        else:
            value = value.strip()
            if value == "":
                return None
            else:
                return value
Beispiel #20
0
    def __init__(self, action, *args, **kwargs):

        # build the forms from the action attributes
        try:
            self.action_item = Action.objects.get(name=action)
        except ObjectDoesNotExist:
            self.action_item = Action(name=action, )

        attributes = self.action_item.attributes.all()

        from django.forms.models import fields_for_model
        model_fields = fields_for_model(Translation)

        model_fields = {}

        #for field in model_fields_list:
        #    print(field)
        #    model_fields[ field ] = model_fields_list[field]

        #for attr in attributes:
        #    if attr.datatype in model_fields:
        #        self.Meta.fields.append(attr.datatype)

        #if self.action_item.target_type:
        #    if not 'target' in self.Meta.fields:
        #        self.Meta.fields.append('target')

        super(BaseActionForm, self).__init__(*args, **kwargs)

        # build fields from attributes
        attributes = self.action_item.attributes.all()

        for attr in attributes:

            if attr.datatype == 'target':
                qs = Item.objects.filter(id__in=list(
                    get_targets(self.instance, self.action_item.target_type)))
                att_field = TargetModelChoiceField(queryset=qs, )

            elif attr.datatype == 'query':
                qs = Item.objects.filter(id__in=list(
                    get_targets(self.instance, self.action_item.target_type)))
                att_field = TargetQueryField(queryset=qs, initial=None)

            elif attr.datatype == 'string':
                att_field = CharField(max_length=1024)

            elif attr.datatype == 'markdown':
                att_field = CharField(max_length=25600, widget=Textarea)

            elif attr.datatype == 'description':
                att_field = CharField(max_length=25600000, widget=Textarea)

            elif attr.datatype == 'boolean':
                att_field = BooleanField()

            elif attr.datatype == 'integer':
                att_field = IntegerField()

            elif attr.datatype == 'number':
                att_field = FloatField()

            elif attr.datatype == 'email':
                att_field = EmailField()

            elif attr.datatype == 'slug':
                att_field = SlugField()

            elif attr.datatype == 'url':
                att_field = URLField()

            #elif attr.datatype in model_fields:
            #    att_field = model_fields[ attr.datatype ]

            elif attr.datatype == 'image':
                att_field = MediaUploadField()

            else:
                #continue
                att_field = CharField(max_length=1024)

            att_field.initial = attr.default
            att_field.required = attr.required
            att_field.label = attr.label
            att_field.help_text = attr.help

            self.fields[attr.name] = att_field

            if attr.hidden:
                self.fields[attr.name].widget = forms.HiddenInput()

            if attr.regexp:
                validator = RegexValidator(attr.regexp,
                                           message=attr.regexp_error)
                if not att_field.validators:
                    att_field.validators = []
                att_field.validators.append(validator)

        self.set_form_control_class()
Beispiel #21
0
class CSVPRocessorForm(Form):
    header = BooleanField(label='Header', initial=False, required=False)
    validate = BooleanField(label='Form validation',
                            initial=False,
                            required=False)
    preview_all = BooleanField(label='Preview all records',
                               initial=False,
                               required=False)
    create_missing = BooleanField(label='Create missing rows',
                                  initial=False,
                                  required=False)

    def _head(self, rows=10):
        with open_csv(self._filename) as csv:
            output = []
            for i in range(rows):
                output.append(csv.next())
        return output

    def clean(self):
        found = False
        # todo: we should try to create a dummy model to force some validation ??
        for i, f in enumerate(self._fields):
            fld = 'fld_%s' % i
            col = 'col_%s' % i
            lkf = 'lkf_%s' % i
            column = self.cleaned_data[col]
            field_name = self.cleaned_data[fld]
            lookup_name = self.cleaned_data[lkf]
            if column >= 0 or field_name:
                found = True
                if not (column >= 0 and field_name):
                    self._errors[fld] = self.error_class(
                        [_("Please set both 'column' and 'field'")])
                    raise ValidationError("Please fix errors below")
                Field, _u, _u, _u = self._model._meta.get_field_by_name(
                    field_name)
                if isinstance(Field, ForeignKey):
                    if not lookup_name:
                        self._errors[fld] = self.error_class([
                            _('Please set lookup field name for "%s"') %
                            field_name
                        ])
                    else:
                        try:
                            Field.rel.to._meta.get_field_by_name(lookup_name)
                        except Exception as e:
                            self._errors[fld] = self.error_class([e])

            if not found:
                raise ValidationError("Please set columns mapping")
        return self.cleaned_data

    def _html_output(self, normal_row, error_row, row_ender, help_text_html,
                     errors_on_separate_row):
        top_errors = self.non_field_errors(
        )  # Errors that should be displayed above all fields.
        output, hidden_fields = [], []
        for name in ('header', 'preview_all', 'validate', 'create_missing'):
            field = self.fields[name]
            bf = BoundField(self, field, name)
            bf_errors = self.error_class([
                conditional_escape(error) for error in bf.errors
            ])  # Escape and cache in local variable.
            if bf_errors:
                top_errors.extend([
                    u'(Hidden field %s) %s' % (name, force_unicode(e))
                    for e in bf_errors
                ])
            output.append(
                '<tr><td class="label" colspan="4">%s</td><td>%s</td></tr>' %
                (bf.label, unicode(bf)))

        output.append(
            u'<tr><th>%s</th><th>%s</th><th class="rex">%s</th><th class="lkf">%s</th><th class="key">%s</th></tr>'
            %
            (_('Column'), _('Field'), _('Regex'), _('Lookup Field'), _('pk')))

        for i, f in enumerate(self._fields):
            line = []
            error_line = []
            rowid = self.fields['col_%s' % i].label
            for n in ('col_%s', 'fld_%s', 'rex_%s', 'lkf_%s', 'key_%s'):
                name = n % i
                field = self.fields[name]
                bf = BoundField(self, field, name)
                bf_errors = self.error_class([
                    conditional_escape(error) for error in bf.errors
                ])  # Escape and cache in local variable.
                error_line.append(force_unicode(bf_errors), )
                line.append('<td class=%(class)s>%(field)s</td>' % {
                    'field': unicode(bf),
                    'class': n[:3]
                })
            output.append('<tr><td colspan="5">%s</td></tr>' %
                          ''.join(error_line))
            output.append('<tr>%(line)s</tr>' % {
                'line': ''.join(line),
                'rowid': rowid
            })

        if top_errors:
            output.insert(0, error_row % force_unicode(top_errors))

        return mark_safe(u'\n'.join(output))

    def as_hidden(self):
        output, hidden_fields = [], []
        for name, field in self.fields.items():
            field.widget = HiddenInput({'readonly': 'readonly'})
            bf = BoundField(self, field, name)
            output.append(unicode(bf))
        return mark_safe(u'\n'.join(output))

    def as_table(self):
        "Returns this form rendered as HTML <tr>s -- excluding the <table></table>."
        return self._html_output(
            normal_row=
            u'<tr%(html_class_attr)s><th>%(label)s</th><td>%(errors)s%(field)s%(help_text)s</td></tr>',
            error_row=u'<tr><td colspan="4">%s</td></tr>',
            row_ender=u'</td></tr>',
            help_text_html=u'<br /><span class="helptext">%s</span>',
            errors_on_separate_row=False)
Beispiel #22
0
    class InvoiceMassImportForm(ImportForm4CremeEntity):
        source = EntityExtractorField(
            models_info=[(Organisation, 'name')],
            choices=choices,
            label=pgettext_lazy('billing', 'Source organisation'),
        )
        target = EntityExtractorField(
            models_info=[(Organisation, 'name'), (Contact, 'last_name')],
            choices=choices,
            label=pgettext_lazy('billing', 'Target'),
        )

        override_billing_addr = BooleanField(
            label=_('Update the billing address'),
            required=False,
            help_text=_(
                'In update mode, update the billing address from the target.'))
        override_shipping_addr = BooleanField(
            label=_('Update the shipping address'),
            required=False,
            help_text=_(
                'In update mode, update the shipping address from the target.')
        )

        def _post_instance_creation(self, instance, line, updated):
            super()._post_instance_creation(instance, line, updated)
            cdata = self.cleaned_data
            user = self.user

            append_error = self.append_error
            source, err_msg = cdata['source'].extract_value(line, user)
            append_error(err_msg)

            target, err_msg = cdata['target'].extract_value(line, user)
            append_error(err_msg)

            create_rel = partial(
                Relation.objects.safe_create,
                subject_entity=instance,
                user=instance.user,
            )

            # TODO: move this intelligence in models.Base.save() (see regular Forms)
            if not updated:
                create_rel(type_id=REL_SUB_BILL_ISSUED, object_entity=source)
                create_rel(type_id=REL_SUB_BILL_RECEIVED, object_entity=target)

                instance.billing_address = copy_or_create_address(
                    target.billing_address, instance, _('Billing address'))
                instance.shipping_address = copy_or_create_address(
                    target.shipping_address, instance, _('Shipping address'))
                instance.save()
            else:  # Update mode
                relations = Relation.objects.filter(
                    subject_entity=instance.pk,
                    type__in=(REL_SUB_BILL_ISSUED, REL_SUB_BILL_RECEIVED))

                issued_relation = find_first(
                    relations, (lambda r: r.type_id == REL_SUB_BILL_ISSUED),
                    None)
                received_relation = find_first(
                    relations, (lambda r: r.type_id == REL_SUB_BILL_RECEIVED),
                    None)

                assert issued_relation is not None
                assert received_relation is not None

                if issued_relation.object_entity_id != source:
                    issued_relation.delete()
                    create_rel(type_id=REL_SUB_BILL_ISSUED,
                               object_entity=source)

                if received_relation.object_entity_id != target:
                    received_relation.delete()
                    create_rel(type_id=REL_SUB_BILL_RECEIVED,
                               object_entity=target)

                b_change = s_change = False

                if cdata['override_billing_addr']:
                    b_change = _copy_or_update_address(
                        target,
                        instance,
                        'billing_address',
                        _('Billing address'),
                    )

                if cdata['override_shipping_addr']:
                    s_change = _copy_or_update_address(
                        target,
                        instance,
                        'shipping_address',
                        _('Shipping address'),
                    )

                if b_change or s_change:
                    instance.save()
Beispiel #23
0
class EntityEmailForm(base_forms.CremeModelForm):
    """Mails are related to the selected contacts/organisations & the 'current' entity.
    Mails are send to selected contacts/organisations.
    """
    sender = EmailField(label=_('Sender'))

    c_recipients = MultiCreatorEntityField(label=_('Contacts'),
                                           required=False,
                                           model=Contact,
                                           q_filter={'email__gt': ''})
    o_recipients = MultiCreatorEntityField(label=_('Organisations'),
                                           required=False,
                                           model=Organisation,
                                           q_filter={'email__gt': ''})

    send_me = BooleanField(label=_('Send me a copy of this mail'),
                           required=False)

    error_messages = {
        'no_person': _('Select at least a Contact or an Organisation'),
    }

    blocks = base_forms.FieldBlockManager(
        ('recipients', _('Who'),
         ['user', 'sender', 'send_me', 'c_recipients', 'o_recipients']),
        ('content', _('What'), ['subject', 'body', 'body_html']),
        ('extra', _('With'), ['signature', 'attachments']),
    )

    class Meta:
        model = EntityEmail
        fields = ('user', 'sender', 'subject', 'body', 'body_html',
                  'signature', 'attachments')

    def __init__(self, entity, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.entity = entity

        if isinstance(entity, (Contact, Organisation)):
            fn, msg = ('c_recipients', _('Beware: the contact «{}» has no email address!')) \
                      if isinstance(entity, Contact) else \
                      ('o_recipients', _('Beware: the organisation «{}» has no email address!'))
            field = self.fields[fn]

            if entity.email:
                field.initial = [entity.pk]
            else:
                field.help_text = msg.format(entity)

        self.user_contact = contact = self.user.linked_contact

        if contact.email:
            self.fields['sender'].initial = contact.email

        def finalize_recipient_field(name, model):
            if FieldsConfig.get_4_model(model).is_fieldname_hidden('email'):
                self.fields[name] = CharField(
                    label=self.fields[name].label,
                    required=False,
                    widget=Label,
                    initial=gettext(
                        'Beware: the field «Email address» is hidden ;'
                        ' please contact your administrator.'),
                )

        finalize_recipient_field('c_recipients', Contact)
        finalize_recipient_field('o_recipients', Organisation)

    def _clean_recipients(self, field_name):
        if isinstance(self.fields[field_name].widget, Label):
            return []

        recipients = self.cleaned_data.get(field_name) or []
        bad_entities = []

        for entity in recipients:
            try:
                validate_email(entity.email)
            except ValidationError:
                bad_entities.append(entity)

        if bad_entities:
            msg_format = gettext('The email address for {} is invalid')
            user = self.user

            for entity in bad_entities:
                self.add_error(field_name,
                               msg_format.format(entity.allowed_str(user)))

        return recipients

    def clean_c_recipients(self):
        return self._clean_recipients('c_recipients')

    def clean_o_recipients(self):
        return self._clean_recipients('o_recipients')

    def clean(self):
        cdata = super().clean()

        if not self._errors and not cdata['c_recipients'] and not cdata[
                'o_recipients']:
            raise ValidationError(self.error_messages['no_person'],
                                  code='no_person')

        return cdata

    def save(self):
        cdata = self.cleaned_data
        get_data = cdata.get

        sender = get_data('sender')
        subject = get_data('subject')
        body = get_data('body')
        body_html = get_data('body_html')
        signature = get_data('signature')
        attachments = get_data('attachments')
        user = get_data('user')

        sending_error = False

        def create_n_send_mail(recipient_address):
            nonlocal sending_error

            email = EntityEmail.create_n_send_mail(
                sender=sender,
                recipient=recipient_address,
                subject=subject,
                user=user,
                body=body,
                body_html=body_html,
                signature=signature,
                attachments=attachments,
            )

            if email.status == MAIL_STATUS_SENDINGERROR:
                sending_error = True

            return email

        with atomic():
            if get_data('send_me'):
                create_n_send_mail(sender)

            user_contact = self.user_contact
            create_relation = partial(Relation.objects.create, user=user)

            for recipient in chain(cdata['c_recipients'],
                                   cdata['o_recipients']):
                email = create_n_send_mail(recipient.email)

                create_relation(subject_entity=email,
                                type_id=REL_SUB_MAIL_SENDED,
                                object_entity=user_contact)
                create_relation(subject_entity=email,
                                type_id=REL_SUB_MAIL_RECEIVED,
                                object_entity=recipient)

        if sending_error:
            entity_emails_send_type.refresh_job()
Beispiel #24
0
class ReminderForm(Form):
    frequency_period = ChoiceField(
        choices=(('week', _('Week')), ('month', _('Month'))),
        widget=forms.Select,
        required=False,
    )
    deadline_month = ChoiceField(
        choices=(tuple([(n, convert_to_ordinal(n)) for n in range(1, 31)] +
                       [(31, ugettext_lazy('Last Day'))])),
        widget=forms.Select,
        required=False)
    deadline_week = ChoiceField(
        choices=(get_translated_weekdays()),
        widget=forms.Select(attrs={'data-bind': 'random'}),
        required=False)
    deadline_type_week = ChoiceField(
        choices=(('Same', _('Same week')), ('Following', _('Following week'))),
        widget=forms.Select(attrs={'class': 'deadline_type'}),
        required=False)

    deadline_type_month = ChoiceField(
        choices=(('Same', _('Same month')), ('Following',
                                             _('Following month'))),
        widget=forms.Select(attrs={'class': 'deadline_type'}),
        required=False)

    deadline_type = ChoiceField(choices=(('Same', _('Same')),
                                         ('Following', _('Following'))),
                                widget=forms.Select,
                                required=False)

    should_send_reminders_before_deadline = BooleanField(required=False,
                                                         initial=False)
    number_of_days_before_deadline = DecimalField(
        label=ugettext_lazy("days before deadline"), required=False)
    reminder_text_before_deadline = CharField(widget=forms.Textarea,
                                              required=False,
                                              label=ugettext_lazy("SMS Text"))

    should_send_reminders_on_deadline = BooleanField(
        label=ugettext_lazy("The day of the deadline"),
        required=False,
        initial=False)
    reminder_text_on_deadline = CharField(widget=forms.Textarea,
                                          required=False,
                                          label=ugettext_lazy("SMS Text"))

    should_send_reminders_after_deadline = BooleanField(
        label=ugettext_lazy("days after the deadline"),
        required=False,
        initial=False)
    number_of_days_after_deadline = DecimalField(
        required=False, label=ugettext_lazy("number of days after deadline"))
    reminder_text_after_deadline = CharField(widget=forms.Textarea,
                                             required=False,
                                             label=ugettext_lazy("SMS Text"))

    whom_to_send_message = BooleanField(label=ugettext_lazy(
        "Only send reminders to senders who have not already submitted data for the current deadline."
    ),
                                        required=False,
                                        initial=True)

    def __init__(self, *args, **kwargs):
        super(ReminderForm, self).__init__(*args, **kwargs)
        deadline_month = ChoiceField(
            choices=(tuple([(n, convert_to_ordinal(n)) for n in range(1, 31)] +
                           [(31, ugettext_lazy('Last Day'))])),
            widget=forms.Select,
            required=False)
        self.fields["deadline_month"] = deadline_month

    def clean(self):

        msg = _("This field is required")

        if self.cleaned_data.get('should_send_reminders_before_deadline'):
            if self.cleaned_data.get('number_of_days_before_deadline') is None:
                self._errors[
                    'number_of_days_before_deadline'] = self.error_class([msg])
            if self.cleaned_data.get('reminder_text_before_deadline') == '':
                self.errors[
                    'reminder_text_before_deadline'] = self.error_class([msg])

        if self.cleaned_data.get(
                'should_send_reminders_on_deadline') and self.cleaned_data.get(
                    'reminder_text_on_deadline') == '':
            self.errors['reminder_text_on_deadline'] = self.error_class([msg])

        if self.cleaned_data.get('should_send_reminders_after_deadline'):
            if self.cleaned_data.get('number_of_days_after_deadline') is None:
                self.errors[
                    'number_of_days_after_deadline'] = self.error_class([msg])
            if self.cleaned_data.get('reminder_text_after_deadline') == '':
                self.errors['reminder_text_after_deadline'] = self.error_class(
                    [msg])

        return self.cleaned_data
Beispiel #25
0
 def empty_form(self):
   f = self.form(prefix=self.make_prefix("TEMPLATE"))
   f.fields["_exists"] = BooleanField(initial=True, widget=HiddenInput)
   f.fields["_deleted"] = BooleanField(initial=True, required=False, widget=SubmitButton)
   return f
Beispiel #26
0
class MessageForm(Form):
    schedule_name = CharField(
        required=True,
        label=_('Schedule Name'),
        max_length=1000,
    )
    send_frequency = ChoiceField(required=True,
                                 label=_('Send'),
                                 choices=(('immediately', _('Immediately')), ))
    recipients = MessageRecipientField(
        label=_("Recipient(s)"),
        help_text=_("Type a username, group name or location"),
    )
    content = ChoiceField(
        required=True,
        label=_("Content"),  # seems like a weird label?
        choices=
        (('sms', _('SMS')),
         # ('email', _('Email')),
         # ('sms_survey', _('SMS Survey')),
         # ('ivr_survey', _('IVR Survey')),
         ))
    translate = BooleanField(label=_("Translate this message"), required=False)

    def __init__(self, *args, **kwargs):
        self.domain = kwargs.pop('domain')
        initial = kwargs.get('initial')
        readonly = False
        if initial:
            readonly = (initial.get('send_frequency') == 'immediately')
            message = initial.get('message', {})
            kwargs['initial']['translate'] = '*' not in message
            kwargs['initial']['non_translated_message'] = message.get('*', '')
            for lang in self.project_languages:
                kwargs['initial']['message_%s' % lang] = message.get(lang, '')

        super(MessageForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_class = 'form form-horizontal'
        self.helper.label_class = 'col-sm-2 col-md-2 col-lg-2'
        self.helper.field_class = 'col-sm-10 col-md-3 col-lg-3'
        self.add_content_fields()

        if readonly:
            for field_name, field in self.fields.items():
                field.disabled = True

        layout_fields = [
            crispy.Field('schedule_name'),
            crispy.Field('send_frequency'),
            crispy.Field(
                'recipients',
                # type='hidden',
                data_bind='value: message_recipients.value',
                placeholder=_("Select some recipients")),
            crispy.Field('content'),
            crispy.Field('translate', data_bind='checked: translate'),
            # todo this doesn't hide the label
            crispy.Field('non_translated_message',
                         data_bind='visible: !translate()'),
        ] + [
            crispy.Field('message_%s' % lang, data_bind='visible: translate')
            for lang in self.project_languages
        ]

        if not readonly:
            layout_fields += [
                hqcrispy.FormActions(
                    twbscrispy.StrictButton(
                        _("Save"),
                        css_class='btn-primary',
                        type='submit',
                    ), ),
            ]
        self.helper.layout = crispy.Layout(*layout_fields)

    @cached_property
    def project_languages(self):
        doc = StandaloneTranslationDoc.get_obj(self.domain, 'sms')
        return getattr(doc, 'langs', ['en'])

    def add_content_fields(self):
        self.fields['non_translated_message'] = CharField(label=_("Message"),
                                                          required=False)

        for lang in self.project_languages:
            # TODO support RTL languages
            self.fields['message_%s' % lang] = CharField(
                label="{} ({})".format(_("Message"), lang), required=False)

    @property
    def current_values(self):
        values = {}
        for field_name in self.fields.keys():
            values[field_name] = self[field_name].value()
        return values

    def clean_recipients(self):
        data = self.cleaned_data['recipients']
        # TODO Will need to add more than user ids
        # TODO batch id verification
        for user_id in data:
            user = CommCareUser.get_db().get(user_id)
            assert user[
                'domain'] == self.domain, "User must be in the same domain"

        return data
Beispiel #27
0
    class InvoiceMassImportForm(ImportForm4CremeEntity):
        source = EntityExtractorField(
            models_info=[(Organisation, 'name')],
            choices=choices,
            label=pgettext_lazy('billing', 'Source organisation'),
        )
        target = EntityExtractorField(
            models_info=[
                (Organisation, 'name'),
                (Contact, 'last_name'),
            ],
            choices=choices, label=pgettext_lazy('billing', 'Target'),
        )

        override_billing_addr = BooleanField(
            label=_('Update the billing address'), required=False,
            help_text=_('In update mode, update the billing address from the target.'),
        )
        override_shipping_addr = BooleanField(
            label=_('Update the shipping address'), required=False,
            help_text=_('In update mode, update the shipping address from the target.'),
        )

        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)

            model = self._meta.model
            if model.generate_number_in_create:
                self.fields['number'].help_text = _(
                    'If you chose an organisation managed by Creme as source organisation, '
                    'a number will be automatically generated for created «{}».'
                ).format(model._meta.verbose_name_plural)

        def _pre_instance_save(self, instance, line):
            cdata = self.cleaned_data
            append_error = self.append_error
            user = self.user

            for prop_name in ('source', 'target'):
                entity, err_msg = cdata[prop_name].extract_value(line, user)
                setattr(instance, prop_name, entity)

                # Error is really appended if 'err_msg' is not empty
                append_error(err_msg)

        def _post_instance_creation(self, instance, line, updated):
            super()._post_instance_creation(instance, line, updated)

            if updated:
                cdata = self.cleaned_data
                target = instance.target
                b_change = s_change = False

                if cdata['override_billing_addr']:
                    b_change = _copy_or_update_address(
                        target, instance, 'billing_address', _('Billing address'),
                    )

                if cdata['override_shipping_addr']:
                    s_change = _copy_or_update_address(
                        target, instance, 'shipping_address', _('Shipping address'),
                    )

                if b_change or s_change:
                    instance.save()
Beispiel #28
0
 def properties(self):
     return {
         "subprocess_has_update": BooleanField(),
         "has_subprocess": BooleanField()
     }
Beispiel #29
0
 def properties(self):
     return {
         'subprocess_has_update': BooleanField(),
         'has_subprocess': BooleanField()
     }
Beispiel #30
0
class LoginForm(forms.Form):
    """!
    Clase del formulario de logeo

    @date 01-03-2017
    @version 1.0.0
    """
    ## Campo de la constraseña
    contrasena = CharField()

    ## Nombre del usuario
    usuario = CharField()

    ## Formulario de recordarme
    remember_me = BooleanField()

    ## Campo del captcha
    #captcha = CaptchaField()

    def __init__(self, *args, **kwargs):
        """!
        Metodo que sobreescribe cuando se inicializa el formulario

        @date 01-03-2017
        @param self <b>{object}</b> Objeto que instancia la clase
        @param args <b>{list}</b> Lista de los argumentos
        @param kwargs <b>{dict}</b> Diccionario con argumentos
        @return Retorna el formulario validado
        """
        super(LoginForm, self).__init__(*args, **kwargs)
        self.fields['contrasena'].widget = PasswordInput()
        self.fields['contrasena'].widget.attrs.update({
            'class':
            'validate',
            'placeholder':
            'Contraseña'
        })
        self.fields['usuario'].widget.attrs.update({
            'class':
            'validate',
            'placeholder':
            'Nombre de Usuario'
        })
        self.fields['remember_me'].label = "Recordar"
        self.fields['remember_me'].widget = CheckboxInput()
        self.fields['remember_me'].required = False
        #self.fields['captcha'].label = "Captcha"
        #self.fields['captcha'].widget.attrs.update({'class': 'validate'})

    def clean(self):
        """!
        Método que valida si el usuario a autenticar es valido

        @date 21-04-2017
        @param self <b>{object}</b> Objeto que instancia la clase
        @return Retorna el campo con los errores
        """
        usuario = self.cleaned_data['usuario']
        contrasena = self.cleaned_data['contrasena']
        usuario = authenticate(username=usuario, password=contrasena)
        if (not usuario):
            msg = "Verifique su usuario o contraseña"
            self.add_error('usuario', msg)

    class Meta:
        fields = ('usuario', 'contrasena', 'remember_me')