예제 #1
0
파일: forms.py 프로젝트: barthlund/froide
class EscalationMessageForm(forms.Form):
    subject = forms.CharField(
        label=_("Subject"),
        max_length=230,
        widget=forms.TextInput(attrs={"class": "form-control"}))
    message = forms.CharField(
        widget=forms.Textarea(attrs={"class": "form-control"}),
        label=_("Your message"),
    )

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

    def clean_message(self):
        message = self.cleaned_data['message']
        message = message.replace('\r\n', '\n').strip()
        empty_form = self.foirequest.get_escalation_message_form()
        if message == empty_form.initial['message'].strip():
            raise forms.ValidationError(
                _('You need to fill in the blanks in the template!'))
        return message

    def clean(self):
        throttle_message = check_throttle(self.foirequest.user, FoiMessage)
        if throttle_message:
            raise forms.ValidationError(throttle_message)

    def save(self):
        self.foirequest.add_escalation_message(**self.cleaned_data)
예제 #2
0
 def __init__(self, *args, **kwargs):
     super(OpportunityForm, self).__init__(*args, **kwargs)
     self.fields['detail'].widget = forms.Textarea(
         attrs={
             'placeholder': _('enter details'),
             'cols': '72'
         })
예제 #3
0
 def __init__(self, *args, **kwargs):
     super(RoleForm, self).__init__(*args, **kwargs)
     # import ipdb; ipdb.set_trace()
     try:
         initial = self.instance.description.text
     except models.GroupDescription.DoesNotExist:
         initial = ""
     self.fields['description'] = forms.CharField(initial=initial,
                                                  widget=forms.Textarea(),
                                                  required=False)
예제 #4
0
class QuestionForm(forms.ModelForm):
    text = forms.CharField(required=True,
                           widget=forms.Textarea(
                               attrs={'rows': 2, 'placeholder': 'Enter your Question.'}),
                           max_length=4000,
                           help_text='The max length of the question is 4000.')

    class Meta:
        model = TmaQuestion
        fields = ('text',)
예제 #5
0
class ContatarAnuncianteForm(forms.Form):
    imovel_ref = forms.CharField(widget=forms.HiddenInput())
    email = forms.EmailField(
      widget=forms.TextInput(attrs={'placeholder': 'Digite seu email'}),
      label='E-mail')
    telefone = forms.CharField(
      widget=forms.TextInput(attrs={'placeholder': 'Digite seu telefone'}))
    nome = forms.CharField(
      widget=forms.TextInput(attrs={'placeholder': 'Digite seu nome'}),
      label='Nome')
    sobrenome = forms.CharField(
      widget=forms.TextInput(attrs={'placeholder': 'Digite seu sobrenome'}),
      label='Sobrenome')
    mensagem = forms.CharField(
      widget=forms.Textarea(attrs={'rows': 3,
                                   'cols': 45,
                                   'placeholder': 'Precisa mais informações do imóvel ou gostaria de agendar uma visita?'}, 
                                   ),
                            label='Mensagem',
                            required=False)

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

    def clean_telefone(self):
        telefone = self.cleaned_data['telefone']
        # not re.match(r'^(\(\d{2}\)) ?(\d{5}-\d{4}|\d{9}|\d{4}-\d{4}|\d{8})$',
        # telefone)
        if len(telefone) < 9:
            raise forms.ValidationError("Digite um telefone válido.")
        return telefone

    def envia_email(self):
        sender = MagicEmail("{0}".format(settings.DEFAULT_FROM_EMAIL))
        current_site = Site.objects.get_current()
        subject = "[SJC Vale Imóveis] Novo Contato: Ref: {0} ".format(
          self.cleaned_data['imovel_ref'])
        data = {'domain': current_site.domain,
                'body': subject,
                'imovel_ref': self.cleaned_data['imovel_ref'],
                'email': self.cleaned_data['email'],
                'telefone': self.cleaned_data['telefone'],
                'nome': self.cleaned_data['nome'],
                'sobrenome': self.cleaned_data['sobrenome'],
                'mensagem': self.cleaned_data['mensagem'],
                'url': reverse('buscador.lista.imovel_referencia',
                               args=[self.cleaned_data['imovel_ref'], ]), }

        email_contato = preferences.ImobiliariaPreferences.email_contato
        sender.using_template(
            "contato_cliente_imovel", data) \
            .with_subject(subject) \
            .reply_to(self.cleaned_data['email']) \
            .send_to([email_contato, ])
예제 #6
0
파일: form.py 프로젝트: Baasje85/openebs2
 class Meta(object):
     model = Kv15Scenario
     exclude = ['dataownercode']
     widgets = {
         'description':
         forms.Textarea(attrs={
             'cols': 40,
             'rows': 4,
             'class': 'col-lg-6'
         }),
     }
예제 #7
0
 class Meta:
     model = Step
     fields = ('text', )
     widgets = {
         'text':
         forms.Textarea(attrs={
             'rows': 3,
             'cols': 140,
             'style': 'resize: none;'
         })
     }
예제 #8
0
class ExamQuestionForm(forms.ModelForm):
    type = forms.ChoiceField(required=True, choices=TYPES, widget=forms.RadioSelect)
    text = forms.CharField(required=True,
                           widget=forms.Textarea(
                               attrs={'rows': 2, 'placeholder': 'Enter your Question.'}),
                           max_length=4000,
                           help_text='The max length of the question is 4000.')

    class Meta:
        model = ExamQuestion
        fields = ('text', 'type')
예제 #9
0
 class Meta:
     model = Post
     fields = [
         'message',
     ]
     widgets = {
         'message':
         forms.Textarea(attrs={
             'rows': 5,
             'placeholder': 'Enter your Question.'
         })
     }
예제 #10
0
 class Meta:
     model = ExpertReportAnnotation
     fields = ('tiger_certainty_category', 'aegypti_certainty_category',
               'tiger_certainty_notes', 'site_certainty_category',
               'site_certainty_notes', 'status', 'linked_id',
               'edited_user_notes', 'message_for_user', 'best_photo',
               'revise', 'validation_complete', 'tags')
     widgets = {
         'tiger_certainty_category': forms.HiddenInput,
         'aegypti_certainty_category': forms.HiddenInput,
         'best_photo': forms.HiddenInput,
         'revise': forms.HiddenInput,
         'tiger_certainty_notes': forms.Textarea(attrs={'rows': 4}),
         'site_certainty_notes': forms.Textarea(attrs={'rows': 4}),
         #'edited_user_notes': forms.Textarea(attrs={'rows': 4}),
         # Public Note
         'edited_user_notes': forms.HiddenInput,
         #'message_for_user': forms.Textarea(attrs={'rows': 4}),
         'message_for_user': forms.HiddenInput,
         'tags': forms.HiddenInput,
     }
예제 #11
0
class MessageForm(forms.Form):
    """A form for sending a message to web site owner"""
    message = forms.CharField(
        required=True,
        widget=forms.Textarea(attrs={
            'placeholder': _("Your message"),
        }))

    def clean_message(self):
        message = self.cleaned_data['message']
        if len(message) > 10000:
            raise forms.ValidationError(ugettext('Message is too long'))
        return message
예제 #12
0
class UserChangeForm(forms.Form):
    email = forms.EmailField(
        required=False,
        widget=forms.EmailInput(attrs={
            'placeholder': _('*****@*****.**'),
            'class': 'form-control'
        }),
        label=_('Your email address'))

    address = forms.CharField(
        max_length=300,
        label=_('Your mailing address'),
        help_text=_('Your address will never be displayed publicly.'),
        widget=forms.Textarea(attrs={
            'placeholder': _('Street, Post Code, City'),
            'class': 'form-control'
        }))

    field_order = ['email', 'newsletter', 'address']

    def __init__(self, user, *args, **kwargs):
        super(UserChangeForm, self).__init__(*args, **kwargs)
        self.user = user
        self.fields['address'].initial = self.user.address
        self.fields['email'].initial = self.user.email
        if HAVE_NEWSLETTER():
            self.fields['newsletter'] = forms.BooleanField(
                required=False, label=_("Newsletter"))
            self.fields['newsletter'].initial = self.user.newsletter
        self.order_fields(self.field_order)

    def clean_email(self):
        email = self.cleaned_data['email'].lower()
        if (self.user.email != email
                and get_user_model().objects.filter(email=email).exists()):
            raise forms.ValidationError(
                _('Another user with that email address already exists!'))
        return email

    def save(self):
        self.user.address = self.cleaned_data['address']
        if HAVE_NEWSLETTER():
            self.user.newsletter = self.cleaned_data['newsletter']

        self.user.save()
예제 #13
0
    def __init__(self, *args, **kwargs):
        kwargs.pop('entity', None)
        instance = kwargs.get('instance', None)
        action_type = kwargs.pop('action_type', None)
        super(ActionForm, self).__init__(*args, **kwargs)
        self.title = u""
        if instance:
            action_type = instance.type
        self.action_type = action_type

        is_amount_calculated = False
        if action_type:
            is_amount_calculated = action_type.is_amount_calculated
            self.calculated_amount = Decimal("0")
            for fieldset_name, fieldset_attrs in self.Meta.fieldsets:
                if fieldset_name == 'type':
                    fieldset_attrs['legend'] = action_type.name
                    break
            self.fields['type'].widget = forms.HiddenInput()
            self.fields['type'].initial = action_type
            if instance:
                self.title = ugettext(u"Edition {0}").format(action_type.name)
            else:
                self.title = ugettext(u"Creation {0}").format(action_type.name)
        else:
            self.title = ugettext(u"Edit action") if instance else ugettext(u"Create action")

        is_auto_generated = (action_type and action_type.number_auto_generated) or \
                            (instance and instance.type and instance.type.number_auto_generated)
        if is_auto_generated:
            self.fields['number'].widget.attrs['disabled'] = 'disabled'
            self.fields['number'].required = False

        self.fields['amount'].widget.attrs['step'] = 'any'
        if is_amount_calculated:
            self.fields['amount'].widget.attrs['disabled'] = 'disabled'
        self.is_amount_calculated = is_amount_calculated

        if action_type and action_type.allowed_status.count():
            # let javascript disable the blank value if default_status
            choices = [('', "---------")]
            allowed_status = action_type.allowed_status.all()
            if instance and instance.frozen:
                allowed_status = allowed_status.filter(allowed_on_frozen=True)
            self.fields['status'].choices = choices + [
                (status.id, status.name) for status in allowed_status
            ]
            if action_type.default_status:
                self.fields['status'].initial = action_type.default_status.id
            else:
                self.fields['status'].initial = ''

        if action_type and action_type.allowed_status2.count():
            # let javascript disable the blank value if default_status2
            allowed_status2 = action_type.allowed_status2.all()
            if instance and instance.frozen:
                allowed_status2 = allowed_status2.filter(allowed_on_frozen=True)
            choices = [('', "---------")]
            self.fields['status2'].choices = choices + [
                (status.id, status.name) for status in allowed_status2
            ]
            if action_type.default_status2:
                self.fields['status2'].initial = action_type.default_status2.id
            else:
                self.fields['status2'].initial = ''
        else:
            self.fields['status2'].widget = forms.HiddenInput()

        self.fields['opportunity'].widget = forms.HiddenInput()
        self.fields['detail'].widget = forms.Textarea(attrs={'placeholder': _('enter details'), 'cols': '72'})

        self._init_dt_field("planned_date", "date", "time")
        self._init_dt_field("end_datetime", "end_date", "end_time")
예제 #14
0
class ContactForm(forms.Form):
    """
    Contact Form
    """

    name = forms.CharField(required=True,
                           max_length=100,
                           label='Ihr Name',
                           widget=forms.TextInput(attrs={
                               'placeholder': 'Name',
                               'autofocus': 'autofocus'
                           }))
    email = forms.EmailField(
        required=True,
        max_length=100,
        label='Ihre Email',
        widget=forms.TextInput(attrs={'placeholder': 'Email'}))
    message = forms.CharField(
        required=True,
        label='Ihre Nachricht',
        widget=forms.Textarea(attrs={'placeholder': 'Nachricht'}))

    OUTGOING = u'Kontakt: Bestätigungsmail an den Kunden'
    INTERNAL = u'Weiterleitung Kontaktanfrage, bitte beantworten!'
    CONTACT_EMAIL = settings.MENTOKI_INFO_EMAIL

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

    def send_email_visitor(self):
        # send email to requesting email
        # this method is called with cleaned from data
        subject = "Ihre Nachricht an mentoki"
        to = [self.cleaned_data['email']]
        from_mail = '*****@*****.**'

        # prepare template
        context = {
            'name': self.cleaned_data['name'],
            'email': self.cleaned_data['email'],
            'message': self.cleaned_data['message'],
            'betreff': "Ihre Nachricht",
        }
        message = get_template('email/contact/to_customer.html').render(
            Context(context))
        to_customer = MailerMessage()
        to_customer.subject = "Ihre Nachricht an mentoki"
        to_customer.to_address = self.cleaned_data['email']
        to_customer.from_address = ContactForm.CONTACT_EMAIL
        to_customer.content = ContactForm.OUTGOING
        to_customer.html_content = message
        to_customer.reply_to = ContactForm.CONTACT_EMAIL
        to_customer.app = self.__module__
        to_customer.save()

    def send_email_self(self):
        """
        email is send to mentoki
        """
        context = {
            'name': self.cleaned_data['name'],
            'email': self.cleaned_data['email'],
            'message': self.cleaned_data['message'],
            'betreff': "Nachricht an mentoki",
        }
        message = get_template('email/contact/to_mentoki.html').render(
            Context(context))

        to_mentoki = MailerMessage()
        to_mentoki.subject = "Kontaktanfrage an mentoki"
        to_mentoki.to_address = ContactForm.CONTACT_EMAIL
        to_mentoki.from_address = self.cleaned_data['email']
        to_mentoki.content = ContactForm.INTERNAL
        to_mentoki.html_content = message
        to_mentoki.reply_to = self.cleaned_data['email']
        to_mentoki.app = self.__module__
        to_mentoki.save()
예제 #15
0
class NewUserBaseForm(forms.Form):
    first_name = forms.CharField(
        max_length=30,
        label=_('First name'),
        widget=forms.TextInput(attrs={
            'placeholder': _('First Name'),
            'class': 'form-control'
        }))
    last_name = forms.CharField(
        max_length=30,
        label=_('Last name'),
        widget=forms.TextInput(attrs={
            'placeholder': _('Last Name'),
            'class': 'form-control'
        }))
    address = forms.CharField(
        max_length=300,
        required=False,
        label=_('Mailing Address'),
        help_text=
        _('Optional. Your address will not be displayed publicly and is only needed in case a public body needs to send you paper.'
          ),
        widget=forms.Textarea(
            attrs={
                'rows': '3',
                'class': 'form-control',
                'placeholder': _('Street, Post Code, City'),
            }))
    user_email = forms.EmailField(
        label=_('Email address'),
        max_length=75,
        help_text=_('Not public. The given address will '
                    'need to be confirmed.'),
        widget=forms.EmailInput(attrs={
            'placeholder': _('*****@*****.**'),
            'class': 'form-control'
        }))

    if HAVE_ORGANIZATION:
        organization = forms.CharField(
            required=False,
            label=_("Organization"),
            help_text=_(
                'Optional. Affiliation will be shown next to your name'),
            widget=forms.TextInput(attrs={
                'placeholder': _('Organization'),
                'class': 'form-control'
            }))

    if USER_CAN_HIDE_WEB:
        private = forms.BooleanField(
            required=False,
            label=_("Hide my name on the web"),
            help_text=mark_safe(
                _("If you check this, your name will still appear in requests to public bodies, but we will do our best to not display it publicly. However, we cannot guarantee your anonymity"
                  )))

    def __init__(self, *args, **kwargs):
        super(NewUserBaseForm, self).__init__(*args, **kwargs)
        if ALLOW_PSEUDONYM:
            self.fields["last_name"].help_text = mark_safe(
                _('<a target="_blank" href="{url}">You may use a pseudonym if you don\'t need to receive postal messages</a>.'
                  ).format(url=reverse("help-privacy") + '#pseudonym'))

    def clean_first_name(self):
        return self.cleaned_data['first_name'].strip()

    def clean_last_name(self):
        return self.cleaned_data['last_name'].strip()

    def clean_user_email(self):
        email = self.cleaned_data['user_email']
        user_model = get_user_model()
        try:
            user = user_model.objects.get(email=email)
        except user_model.DoesNotExist:
            pass
        else:
            if user.is_active:
                raise forms.ValidationError(
                    mark_safe(
                        _('This email address already has an account. <a href="%(url)s?simple&email=%(email)s" class="btn btn-warning target-small">Click here to login using that email address.</a>'
                          ) % {
                              'url': reverse("account-login"),
                              'email': email
                          }))
            else:
                raise forms.ValidationError(
                    _('This email address is already registered, but not yet confirmed! Please click on the confirmation link in the mail we send you.'
                      ))
        return email
예제 #16
0
파일: forms.py 프로젝트: barthlund/froide
class PostalBaseForm(AttachmentSaverMixin, forms.Form):
    scan_help_text = mark_safe(
        _("Uploaded scans can be PDF, JPG or PNG. Please make sure to <strong>redact/black out all private information concerning you</strong>."
          ))
    public_body = forms.ModelChoiceField(label=_('Public body'),
                                         queryset=PublicBody.objects.all(),
                                         widget=PublicBodySelect)
    date = forms.DateField(
        widget=forms.TextInput(attrs={
            "class": "form-control",
            "placeholder": _('mm/dd/YYYY')
        }),
        label=_("Send Date"),
        help_text=_("Please give the date the reply was sent."),
        localize=True)
    subject = forms.CharField(
        label=_("Subject"),
        required=False,
        max_length=230,
        widget=forms.TextInput(attrs={
            "class": "form-control",
            "placeholder": _("Subject")
        }))
    text = forms.CharField(
        label=_("Letter"),
        widget=forms.Textarea(attrs={
            "placeholder": _("Letter text"),
            "class": "form-control"
        }),
        required=False,
        help_text=
        _("The text can be left empty, instead you can upload scanned documents."
          ))
    files = forms.FileField(label=_("Scanned Letter"),
                            required=False,
                            validators=[validate_upload_document],
                            help_text=scan_help_text,
                            widget=forms.FileInput(attrs={'multiple': True}))
    FIELD_ORDER = ['public_body', 'date', 'subject', 'text', 'files']

    def __init__(self, *args, **kwargs):
        self.foirequest = kwargs.pop('foirequest')
        super(PostalBaseForm, self).__init__(*args, **kwargs)
        self.fields['public_body'].label = self.PUBLIC_BODY_LABEL
        self.fields['public_body'].initial = self.foirequest.public_body
        self.order_fields(self.FIELD_ORDER)

    def clean_date(self):
        date = self.cleaned_data['date']
        now = timezone.now().date()
        if date > now:
            raise forms.ValidationError(
                _("Your reply date is in the future, that is not possible."))
        return date

    def clean_files(self):
        if 'files' not in self.files:
            return self.cleaned_data['files']
        files = self.files.getlist('files')
        names = set()
        for file in files:
            validate_upload_document(file)
            name = self.make_filename(file.name)
            if name in names:
                # FIXME: dont make this a requirement
                raise forms.ValidationError(
                    _('Upload files must have distinct names'))
            names.add(name)
        return self.cleaned_data['files']

    def clean(self):
        cleaned_data = self.cleaned_data
        text = cleaned_data.get("text")
        if 'files' in self.files:
            files = self.files.getlist('files')
        else:
            files = None
        if not (text or files):
            raise forms.ValidationError(
                _("You need to provide either the letter text or a scanned document."
                  ))
        return cleaned_data

    def save(self):
        foirequest = self.foirequest
        message = FoiMessage(
            request=foirequest,
            is_postal=True,
        )
        # TODO: Check if timezone support is correct
        date = datetime.datetime.combine(self.cleaned_data['date'],
                                         datetime.time())
        message.timestamp = timezone.get_current_timezone().localize(date)
        message.subject = self.cleaned_data.get('subject', '')
        message.subject_redacted = message.redact_subject()[:250]
        message.plaintext = ""
        if self.cleaned_data.get('text'):
            message.plaintext = self.cleaned_data.get('text')
        message.plaintext_redacted = message.get_content()
        message = self.contribute_to_message(message)
        message.save()
        foirequest.last_message = message.timestamp
        foirequest.status = 'awaiting_classification'
        foirequest.save()
        foirequest.add_postal_reply.send(sender=foirequest)

        if self.cleaned_data.get('files'):
            self.save_attachments(self.files.getlist('files'), message)
        return message
예제 #17
0
 class Meta:
     """form is defined from model"""
     model = models.Contact
     fields = ('gender', 'gender_title', 'lastname', 'firstname',
               'birth_date', 'title', 'role', 'job', 'email', 'phone',
               'mobile', 'favorite_language', 'street_number',
               'street_type', 'address', 'address2', 'address3', 'zip_code',
               'city', 'cedex', 'country', 'main_contact', 'email_verified',
               'has_left', 'accept_notifications', 'photo',
               'billing_street_number', 'billing_street_type',
               'billing_address', 'billing_address2', 'billing_address3',
               'billing_zip_code', 'billing_city', 'billing_cedex',
               'billing_country', 'same_as_suggestions')
     widgets = {
         'notes':
         forms.Textarea(attrs={
             'placeholder': _('enter notes about the contact'),
             'cols': '72'
         }),
         'role':
         forms.SelectMultiple(
             attrs={
                 'class': 'chosen-select',
                 'data-placeholder': _('Select roles'),
                 'style': "width: 100%;"
             }),
     }
     fieldsets = [
         ('name', {
             'fields': [
                 'gender', 'gender_title', 'lastname', 'firstname', 'email',
                 'same_as_suggestions', 'phone', 'mobile'
             ],
             'legend':
             _('Name')
         }),
         ('web', {
             'fields': [
                 'birth_date',
                 'title',
                 'role',
                 'job',
                 'favorite_language',
             ],
             'legend':
             _('Contact details')
         }),
         ('address', {
             'fields': [
                 'street_number', 'street_type', 'address', 'address2',
                 'address3', 'zip_code', 'city', 'cedex', 'country'
             ],
             'legend':
             _('Address')
         }),
         ('billing_address', {
             'fields': [
                 'billing_street_number', 'billing_street_type',
                 'billing_address', 'billing_address2', 'billing_address3',
                 'billing_zip_code', 'billing_city', 'billing_cedex',
                 'billing_country'
             ],
             'legend':
             _('Billing address')
         }),
         ('relationship', {
             'fields': [
                 'main_contact', 'email_verified', 'has_left',
                 'accept_notifications'
             ],
             'legend':
             _('Options')
         }),
         ('photo', {
             'fields': ['photo'],
             'legend': _('Photo')
         }),
     ]
예제 #18
0
파일: form.py 프로젝트: Baasje85/openebs2
    class Meta(object):
        model = Kv15ScenarioMessage
        exclude = ['dataownercode']
        widgets = {
            'scenario':
            forms.HiddenInput,
            'messagecontent':
            forms.Textarea(attrs={
                'cols': 40,
                'rows': 4,
                'class': 'col-lg-6'
            }),
            'reasoncontent':
            forms.Textarea(attrs={
                'cols': 40,
                'rows': 4,
                'class': 'col-lg-6'
            }),
            'effectcontent':
            forms.Textarea(attrs={
                'cols': 40,
                'rows': 4,
                'class': 'col-lg-6'
            }),
            'measurecontent':
            forms.Textarea(attrs={
                'cols': 40,
                'rows': 4,
                'class': 'col-lg-6'
            }),
            'advicecontent':
            forms.Textarea(attrs={
                'cols': 40,
                'rows': 4,
                'class': 'col-lg-6'
            }),

            # This is awful, but is neccesary because otherwise we don't get nice bootstrappy widgets
            'messagepriority':
            forms.RadioSelect,
            'messagetype':
            forms.RadioSelect,
            'messagedurationtype':
            forms.RadioSelect,
            'messagestarttime':
            forms.DateTimeInput,
            'messageendtime':
            forms.DateTimeInput,
            'reasontype':
            forms.RadioSelect,
            'subreasontype':
            forms.Select,
            'effecttype':
            forms.RadioSelect,
            'subeffecttype':
            forms.Select,
            'measuretype':
            forms.RadioSelect,
            'submeasuretype':
            forms.Select,
            'advicetype':
            forms.RadioSelect,
            'subadvicetype':
            forms.Select
        }
예제 #19
0
파일: forms.py 프로젝트: barthlund/froide
class RequestForm(forms.Form):
    public_body = forms.CharField(
        widget=PublicBodySelect,
        label=_("Search for a topic or a public body:"),
        required=False)
    subject = forms.CharField(
        label=_("Subject"),
        max_length=230,
        widget=forms.TextInput(attrs={
            'placeholder': _("Subject"),
            "class": "form-control"
        }))
    body = forms.CharField(
        label=_("Body"),
        widget=forms.Textarea(
            attrs={
                'placeholder': _("Specify your request here..."),
                "class": "form-control"
            }))
    full_text = forms.BooleanField(
        required=False,
        initial=False,
        label=_("Don't wrap in template"),
        widget=forms.CheckboxInput(attrs={'tabindex': '-1'}))
    public = forms.BooleanField(
        required=False,
        initial=True,
        label=_("This request is public."),
        help_text=_(
            "If you don't want your request to be public right now,"
            " uncheck this. You can always decide to make it public later."))
    reference = forms.CharField(widget=forms.HiddenInput, required=False)
    redirect_url = forms.CharField(widget=forms.HiddenInput, required=False)
    hide_public = forms.BooleanField(widget=forms.HiddenInput,
                                     initial=False,
                                     required=False)
    hide_similar = forms.BooleanField(widget=forms.HiddenInput,
                                      initial=False,
                                      required=False)

    def __init__(self,
                 user=None,
                 list_of_laws=(),
                 default_law=None,
                 hide_law_widgets=True,
                 **kwargs):
        super(RequestForm, self).__init__(**kwargs)
        self.user = user
        self.list_of_laws = list_of_laws
        self.indexed_laws = dict([(l.pk, l) for l in self.list_of_laws])
        self.default_law = default_law

        self.fields["public_body"].widget.set_initial_jurisdiction(
            kwargs.get('initial', {}).pop('jurisdiction', None))
        self.fields["public_body"].widget.set_initial_search(
            kwargs.get('initial', {}).pop('public_body_search', None))
        self.fields["law"] = forms.ChoiceField(
            label=_("Information Law"),
            required=False,
            widget=forms.Select if not hide_law_widgets else forms.HiddenInput,
            initial=default_law.pk,
            choices=((l.pk, l.name) for l in list_of_laws))

    def laws_to_json(self):
        return json.dumps(
            dict([(l.id, l.as_dict()) for l in self.list_of_laws]))

    def clean_public_body(self):
        pb = self.cleaned_data['public_body']
        if pb == "new":
            if not new_publicbody_allowed:
                raise forms.ValidationError(
                    _("You are not allowed to create a new public body"))
        elif pb == "":
            if not publicbody_empty:
                raise forms.ValidationError(
                    _("You must specify a public body"))
            pb = None
        else:
            try:
                pb_pk = int(pb)
            except ValueError:
                raise forms.ValidationError(_("Invalid value"))
            try:
                public_body = PublicBody.objects.get(pk=pb_pk)
            except PublicBody.DoesNotExist:
                raise forms.ValidationError(_("Invalid value"))
            self.public_body_object = public_body
            self.foi_law_object = public_body.default_law
        return pb

    public_body_object = None

    def clean_reference(self):
        ref = self.cleaned_data['reference']
        if not ref:
            return ''
        try:
            kind, value = ref.split(':', 1)
        except ValueError:
            return ''
        try:
            return '%s:%s' % (kind, value)
        except ValueError:
            return ''

    def clean_law_for_public_body(self, public_body):
        law = self.clean_law_without_public_body()
        if law is None:
            return None
        if law.jurisdiction.id != public_body.jurisdiction.id:
            self._errors["law"] = self.error_class(
                [_("Invalid Information Law")])
            return None
        return law

    def clean_law_without_public_body(self):
        try:
            law = self.cleaned_data['law']
            law = self.indexed_laws[int(law)]
        except (ValueError, KeyError):
            self._errors["law"] = self.error_class(
                [_("Invalid Information Law")])
            return None
        return law

    def clean(self):
        cleaned = self.cleaned_data
        public_body = cleaned.get("public_body")
        if public_body is not None and (public_body != "new"
                                        and public_body != ""):
            self.foi_law = self.clean_law_for_public_body(
                self.public_body_object)
        else:
            self.foi_law = self.clean_law_without_public_body()

        throttle_message = check_throttle(self.user, FoiRequest)
        if throttle_message:
            raise forms.ValidationError(throttle_message)

        return cleaned
예제 #20
0
파일: forms.py 프로젝트: barthlund/froide
class SendMessageForm(forms.Form):
    to = forms.TypedChoiceField(
        label=_("To"),
        choices=[],
        coerce=int,
        required=True,
        widget=forms.RadioSelect(attrs={"class": "form-control"}))
    subject = forms.CharField(
        label=_("Subject"),
        max_length=230,
        widget=forms.TextInput(attrs={"class": "form-control"}))
    message = forms.CharField(
        widget=forms.Textarea(attrs={"class": "form-control"}),
        label=_("Your message"))

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

        choices = [(0, _("Default address of %(publicbody)s") % {
            "publicbody": foirequest.public_body.name
        })]
        choices.extend([
            (m.id, m.reply_address_entry)
            for k, m in foirequest.possible_reply_addresses().items()
        ])
        self.fields['to'].choices = choices

        if foirequest.law and foirequest.law.email_only:
            self.fields['send_address'] = forms.BooleanField(
                label=_("Send physical address"),
                help_text=(_(
                    'If the public body is asking for your post '
                    'address, check this and we will append it to your message.'
                )),
                required=False)

    def clean(self):
        throttle_message = check_throttle(self.foirequest.user, FoiMessage)
        if throttle_message:
            raise forms.ValidationError(throttle_message)

    def save(self, user):
        if self.cleaned_data["to"] == 0:
            recipient_name = self.foirequest.public_body.name
            recipient_email = self.foirequest.public_body.email
            recipient_pb = self.foirequest.public_body
        else:
            message = list(
                filter(lambda x: x.id == self.cleaned_data["to"],
                       list(self.foirequest.messages)))[0]
            recipient_name = message.sender_name
            recipient_email = message.sender_email
            recipient_pb = message.sender_public_body
        return self.foirequest.add_message(user,
                                           recipient_name,
                                           recipient_email,
                                           self.cleaned_data["subject"],
                                           self.cleaned_data['message'],
                                           recipient_pb=recipient_pb,
                                           send_address=self.cleaned_data.get(
                                               'send_address', True))
예제 #21
0
파일: form.py 프로젝트: Baasje85/openebs2
    class Meta(object):
        model = Kv15Stopmessage
        exclude = [
            'messagecodenumber', 'status', 'stops', 'messagecodedate',
            'isdeleted', 'id', 'dataownercode', 'user'
        ]
        widgets = {
            'messagecontent':
            forms.Textarea(attrs={
                'cols': 50,
                'rows': 6,
                'class': 'col-lg-6',
                'maxlength': 255
            }),
            'reasoncontent':
            forms.Textarea(attrs={
                'cols': 40,
                'rows': 4,
                'class': 'col-lg-6'
            }),
            'effectcontent':
            forms.Textarea(attrs={
                'cols': 40,
                'rows': 4,
                'class': 'col-lg-6'
            }),
            'measurecontent':
            forms.Textarea(attrs={
                'cols': 40,
                'rows': 4,
                'class': 'col-lg-6'
            }),
            'advicecontent':
            forms.Textarea(attrs={
                'cols': 40,
                'rows': 4,
                'class': 'col-lg-6'
            }),

            # This is awful, but is neccesary because otherwise we don't get nice bootstrappy widgets
            'messagepriority':
            forms.RadioSelect,
            'messagedurationtype':
            forms.RadioSelect,
            'messagetype':
            forms.RadioSelect,
            'messagestarttime':
            forms.DateTimeInput,
            'messageendtime':
            forms.DateTimeInput,
            'reasontype':
            forms.RadioSelect,
            'subreasontype':
            forms.Select,
            'effecttype':
            forms.RadioSelect,
            'subeffecttype':
            forms.Select,
            'measuretype':
            forms.RadioSelect,
            'submeasuretype':
            forms.Select,
            'advicetype':
            forms.RadioSelect,
            'subadvicetype':
            forms.Select,
            'messagetimestamp':
            forms.DateTimeInput
        }
예제 #22
0
class Kv17ChangeForm(forms.ModelForm):
    # This is duplication, but should work
    operatingday = forms.ChoiceField(label=_("Datum"), required=True)
    begintime_part = forms.TimeField(label=_('Ingangstijd'),
                                     required=False,
                                     widget=forms.TimeInput(format='%H:%M:%S'))
    endtime_part = forms.TimeField(label=_('Eindtijd'),
                                   required=False,
                                   widget=forms.TimeInput(format='%H:%M:%S'))
    reasontype = forms.ChoiceField(choices=REASONTYPE,
                                   label=_("Type oorzaak"),
                                   required=False)
    subreasontype = forms.ChoiceField(choices=SUBREASONTYPE,
                                      label=_("Oorzaak"),
                                      required=False)
    reasoncontent = forms.CharField(max_length=255,
                                    label=_("Uitleg oorzaak"),
                                    required=False,
                                    widget=forms.Textarea(attrs={
                                        'cols': 40,
                                        'rows': 4,
                                        'class': 'col-lg-6'
                                    }))
    advicetype = forms.ChoiceField(choices=ADVICETYPE,
                                   label=_("Type advies"),
                                   required=False)
    subadvicetype = forms.ChoiceField(choices=SUBADVICETYPE,
                                      label=_("Advies"),
                                      required=False)
    advicecontent = forms.CharField(max_length=255,
                                    label=_("Uitleg advies"),
                                    required=False,
                                    widget=forms.Textarea(attrs={
                                        'cols': 40,
                                        'rows': 4,
                                        'class': 'col-lg-6'
                                    }))

    def clean(self):
        cleaned_data = super(Kv17ChangeForm, self).clean()
        operatingday = parse_date(self.data['operatingday'])
        if operatingday is None:
            raise ValidationError(_("Er staan geen ritten in de database"))

        if 'journeys' not in self.data:
            raise ValidationError(
                _("Een of meer geselecteerde ritten zijn ongeldig"))

        if self.data['begintime_part'] != '':
            hh, mm = self.data['begintime_part'].split(':')
            begintime = make_aware(
                datetime.combine(operatingday, time(int(hh), int(mm))))
        else:
            begintime = None

        if self.data['endtime_part'] != '':
            hh_e, mm_e = self.data['endtime_part'].split(':')
            endtime = make_aware(
                datetime.combine(operatingday, time(int(hh_e), int(mm_e))))
            if begintime:
                if begintime > endtime:  # if endtime before begintime
                    endtime = endtime + timedelta(
                        days=1)  # endtime is next day
                    if endtime.time() >= time(
                            6, 0):  # and after 6 am: validation error
                        raise ValidationError(
                            _("Eindtijd valt op volgende operationele dag"))
        else:
            endtime = None

        dataownercode = self.user.userprofile.company
        if 'Alle ritten' in self.data['journeys']:
            valid_journeys = self.clean_all_journeys(operatingday,
                                                     dataownercode, begintime,
                                                     endtime)
        elif 'Hele vervoerder' in self.data['lines']:
            valid_journeys = self.clean_all_lines(operatingday, dataownercode,
                                                  begintime, endtime)
        else:
            valid_journeys = self.clean_journeys(operatingday, dataownercode)

        if valid_journeys == 0:
            raise ValidationError(
                _("Er zijn geen ritten geselecteerd om op te heffen"))

        return cleaned_data

    def clean_journeys(self, operatingday, dataownercode):
        valid_journeys = 0
        if self.data['journeys'] != '':
            for journey in self.data['journeys'].split(',')[0:-1]:
                journey_qry = Kv1Journey.objects.filter(
                    dataownercode=dataownercode,
                    pk=journey,
                    dates__date=operatingday)
                if journey_qry.count() == 0:
                    raise ValidationError(
                        _("Een of meer geselecteerde ritten zijn ongeldig"))

                # delete recovered if query is the same.
                Kv17Change.objects.filter(dataownercode=dataownercode,
                                          journey__pk=journey,
                                          line=journey_qry[0].line,
                                          operatingday=operatingday,
                                          is_recovered=True).delete()

        else:
            raise ValidationError(_("Er werd geen rit geselecteerd."))

        valid_journeys += 1

        return valid_journeys

    def clean_all_journeys(self, operatingday, dataownercode, begintime,
                           endtime):
        valid_journeys = 0

        if 'lines' in self.data:
            if self.data['lines'] != '':
                for line in self.data['lines'].split(',')[0:-1]:
                    line_qry = Kv1Line.objects.filter(pk=line)

                    if line_qry.count() == 0:
                        raise ValidationError(_("Geen lijn gevonden."))

                    database_alljourneys = Kv17Change.objects.filter(
                        dataownercode=dataownercode,
                        is_alljourneysofline=True,
                        line=line_qry[0],
                        operatingday=operatingday,
                        is_recovered=False)

                    database_alllines = Kv17Change.objects.filter(
                        dataownercode=dataownercode,
                        is_alllines=True,
                        operatingday=operatingday,
                        is_recovered=False)

                    # delete recovered if query is the same.
                    Kv17Change.objects.filter(dataownercode=dataownercode,
                                              is_alljourneysofline=True,
                                              line=line_qry[0],
                                              operatingday=operatingday,
                                              begintime=begintime,
                                              endtime=endtime,
                                              is_recovered=True).delete()

                    if operatingday == datetime.today().date():
                        begintime = make_aware(
                            datetime.now()) if begintime is None else begintime
                    else:
                        begintime = make_aware(datetime.combine(operatingday, time((int(4))))) \
                            if begintime is None else begintime

                    if database_alllines:
                        if database_alllines.filter(
                                Q(endtime__gt=begintime) | Q(endtime=None),
                                Q(begintime__lte=begintime)
                                | Q(begintime=None)):
                            raise ValidationError(
                                _("De gehele vervoerder is al aangepast voor de aangegeven ingangstijd."
                                  ))

                    elif database_alljourneys:
                        if database_alljourneys.filter(
                                Q(endtime__gt=begintime) | Q(endtime=None),
                                Q(begintime__lte=begintime)
                                | Q(begintime=None)):
                            raise ValidationError(
                                _("Een of meer geselecteerde lijnen zijn al aangepast voor de aangegeven ingangstijd."
                                  ))
        else:
            raise ValidationError(_("Geen geldige lijn geselecteerd"))

        valid_journeys += 1

        return valid_journeys

    def clean_all_lines(self, operatingday, dataownercode, begintime, endtime):
        valid_journeys = 0

        database_alllines = Kv17Change.objects.filter(
            dataownercode=dataownercode,
            is_alllines=True,
            operatingday=operatingday,
            is_recovered=False)

        # delete recovered if query is the same.
        Kv17Change.objects.filter(dataownercode=dataownercode,
                                  is_alllines=True,
                                  is_recovered=True,
                                  operatingday=operatingday,
                                  begintime=begintime,
                                  endtime=endtime).delete()

        if database_alllines:
            if operatingday == datetime.today().date():
                begintime = make_aware(
                    datetime.now()) if begintime is None else begintime
            else:
                begintime = make_aware(datetime.combine(operatingday, time((int(4))))) \
                    if begintime is None else begintime

            if database_alllines.filter(
                    Q(endtime__gt=begintime) | Q(endtime=None),
                    Q(begintime__lte=begintime) | Q(begintime=None)):
                raise ValidationError(
                    _("De ingangstijd valt al binnen een geplande operatie."))

        valid_journeys += 1

        return valid_journeys

    def save(self, force_insert=False, force_update=False, commit=True):
        ''' Save each of the journeys in the model. This is a disaster, we return the XML
        TODO: Figure out a better solution fo this! '''
        operatingday = parse_date(self.data['operatingday'])
        if self.data['begintime_part'] != '':
            hh, mm = self.data['begintime_part'].split(':')
            begintime = make_aware(
                datetime.combine(operatingday, time(int(hh), int(mm))))
        else:
            begintime = None

        if self.data['endtime_part'] != '':
            hh_end, mm_end = self.data['endtime_part'].split(':')
            # if begintime is set and endtime is earlier than begintime add 1 day to operatingday of endtime
            if begintime and time(int(hh_end), int(mm_end)) < time(
                    int(hh), int(mm)):
                if time(0, 0) <= time(int(hh_end), int(mm_end)) < time(6, 0):
                    operatingday_endtime = operatingday + timedelta(days=1)
                endtime = make_aware(
                    datetime.combine(operatingday_endtime,
                                     time(int(hh_end), int(mm_end))))
            # else, operatingday is given day
            else:
                endtime = make_aware(
                    datetime.combine(operatingday,
                                     time(int(hh_end), int(mm_end))))
        else:
            endtime = None

        if 'Alle ritten' in self.data['journeys']:
            xml_output = self.save_all_journeys(operatingday, begintime,
                                                endtime)
        elif 'Hele vervoerder' in self.data['lines']:
            xml_output = self.save_all_lines(operatingday, begintime, endtime)
        else:
            xml_output = self.save_journeys(operatingday)

        return xml_output

    def save_all_journeys(self, operatingday, begintime, endtime):
        xml_output = []

        for line in self.data['lines'].split(',')[0:-1]:
            qry = Kv1Line.objects.filter(id=line)
            if qry.count() == 1:
                self.instance.pk = None
                self.instance.is_alljourneysofline = True
                self.instance.line = qry[0]
                self.instance.operatingday = operatingday
                self.instance.begintime = begintime
                self.instance.endtime = endtime
                self.instance.is_cancel = True

                # Unfortunately, we can't place this any earlier, because we don't have the dataownercode there
                if self.instance.line.dataownercode == self.instance.dataownercode:
                    self.instance.save()

                    # Add details
                    if self.data['reasontype'] != '0' or self.data[
                            'advicetype'] != '0':
                        Kv17JourneyChange(
                            change=self.instance,
                            reasontype=self.data['reasontype'],
                            subreasontype=self.data['subreasontype'],
                            reasoncontent=self.data['reasoncontent'],
                            advicetype=self.data['advicetype'],
                            subadvicetype=self.data['subadvicetype'],
                            advicecontent=self.data['advicecontent']).save()

                    xml_output.append(self.instance.to_xml())
                else:
                    log.error(
                        "Oops! mismatch between dataownercode of line (%s) and of user (%s) when saving journey cancel"
                        % (self.instance.line.dataownercode,
                           self.instance.dataownercode))

            else:
                log.error("Failed to find line %s" % line)

        return xml_output

    def save_journeys(self, operatingday):
        xml_output = []

        for journey in self.data['journeys'].split(',')[0:-1]:
            qry = Kv1Journey.objects.filter(id=journey,
                                            dates__date=operatingday)
            if qry.count() == 1:
                self.instance.pk = None
                self.instance.journey = qry[0]
                self.instance.line = qry[0].line
                self.instance.operatingday = operatingday
                self.instance.is_cancel = True

                # Shouldn't be necessary, but just in case:
                self.instance.begintime = None
                self.instance.endtime = None

                # Unfortunately, we can't place this any earlier, because we don't have the dataownercode there
                if self.instance.journey.dataownercode == self.instance.dataownercode:
                    self.instance.save()

                    # Add details
                    if self.data['reasontype'] != '0' or self.data[
                            'advicetype'] != '0':
                        Kv17JourneyChange(
                            change=self.instance,
                            reasontype=self.data['reasontype'],
                            subreasontype=self.data['subreasontype'],
                            reasoncontent=self.data['reasoncontent'],
                            advicetype=self.data['advicetype'],
                            subadvicetype=self.data['subadvicetype'],
                            advicecontent=self.data['advicecontent']).save()

                    xml_output.append(self.instance.to_xml())
                else:
                    log.error(
                        "Oops! mismatch between dataownercode of line (%s) and of user (%s) when saving journey cancel"
                        % (self.instance.journey.dataownercode,
                           self.instance.dataownercode))
            else:
                log.error("Failed to find journey %s" % journey)

        return xml_output

    def save_all_lines(self, operatingday, begintime, endtime):
        xml_output = []

        self.instance.pk = None
        self.instance.is_alllines = True
        self.instance.operatingday = operatingday
        self.instance.begintime = begintime
        self.instance.endtime = endtime
        self.instance.is_cancel = True

        # Unfortunately, we can't place this any earlier, because we don't have the dataownercode there
        if self.instance.dataownercode == self.user.userprofile.company:
            self.instance.save()

            # Add details
            if self.data['reasontype'] != '0' or self.data['advicetype'] != '0':
                Kv17JourneyChange(
                    change=self.instance,
                    reasontype=self.data['reasontype'],
                    subreasontype=self.data['subreasontype'],
                    reasoncontent=self.data['reasoncontent'],
                    advicetype=self.data['advicetype'],
                    subadvicetype=self.data['subadvicetype'],
                    advicecontent=self.data['advicecontent']).save()

            xml_output.append(self.instance.to_xml())
        else:
            log.error(
                "Oops! mismatch between dataownercode of line (%s) and of user (%s) when saving journey cancel"
                % (self.instance.line.dataownercode,
                   self.instance.dataownercode))

        return xml_output

    class Meta(object):
        model = Kv17Change
        exclude = [
            'dataownercode', 'line', 'journey', 'is_recovered', 'reinforcement'
        ]

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

        days = [[
            str(d['date'].strftime('%Y-%m-%d')),
            str(d['date'].strftime('%d-%m-%Y'))
        ] for d in Kv1JourneyDate.objects.all().filter(
            date__gte=datetime.today() -
            timedelta(days=1)).values('date').distinct('date').order_by('date')
                ]

        operating_day = days[((datetime.now().hour < 4) * -1) +
                             1] if len(days) > 1 else None
        self.fields['operatingday'].choices = days
        self.fields['operatingday'].initial = operating_day
        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.layout = Layout(
            Accordion(
                AccordionGroup(_('Datum en tijd'), 'operatingday',
                               'begintime_part', 'endtime_part'),
                AccordionGroup(_('Oorzaak'), 'reasontype', 'subreasontype',
                               'reasoncontent'),
                AccordionGroup(_('Advies'), 'advicetype', 'subadvicetype',
                               'advicecontent')))
예제 #23
0
class PeriodForm(forms.ModelForm):
    comment = forms.CharField(widget=forms.Textarea(attrs={'rows': 3}))

    class Meta:
        model = period_models.FlowEvent
        exclude = ['user']
예제 #24
0
class SubscribeForm(ModelFormWithCity, SubscriptionTypeFormMixin):
    """Subscribe to emailing"""

    city = forms.CharField(
        required=False,
        label=_('City'),
        widget=CityAutoComplete(attrs={
            'placeholder': _('Enter a city'),
            'size': '80'
        }))
    entity_type = forms.ChoiceField(required=False, widget=forms.Select())
    entity = forms.CharField(
        required=False,
        widget=forms.TextInput(attrs={'placeholder': _('Name of the entity')}))
    groups = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple(),
                                       label='',
                                       required=False)
    action_types = forms.MultipleChoiceField(
        widget=forms.CheckboxSelectMultiple(), label='', required=False)
    message = forms.CharField(required=False,
                              widget=forms.Textarea(attrs={
                                  'placeholder': _('Message'),
                                  'cols': '90'
                              }))
    captcha = get_captcha_field()
    favorite_language = forms.CharField(required=False,
                                        widget=forms.HiddenInput())

    class Meta:
        model = Contact
        fields = ('gender', 'firstname', 'lastname', 'phone', 'mobile',
                  'email', 'address', 'address2', 'address3', 'zip_code')
        widgets = {
            'lastname':
            forms.TextInput(attrs={
                'placeholder': _('Lastname'),
                'required': 'required'
            }),
            'firstname':
            forms.TextInput(attrs={'placeholder': _('Firstname')}),
            'phone':
            forms.TextInput(attrs={'placeholder': _('Phone')}),
            'email':
            forms.TextInput(attrs={
                'placeholder': _('Email'),
                'required': 'required'
            }),
            'zip_code':
            forms.TextInput(attrs={'placeholder': _('zip code')}),
        }

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

        self.fields['email'].required = True

        # Do not display (Mrs and M) gender on subscribe form
        self.fields['gender'].choices = [
            (models.Contact.GENDER_NOT_SET, _('')),
            (models.Contact.GENDER_MALE, ugettext('Mr')),
            (models.Contact.GENDER_FEMALE, ugettext('Mrs')),
        ]

        entity_types_choices = []

        if crm_settings.ALLOW_SINGLE_CONTACT:
            entity_types_choices.append((0, _('Individual')))
        else:
            entity_types_choices.append((0, ''))

        entity_types_choices.extend([
            (et.id, et.name)
            for et in EntityType.objects.filter(subscribe_form=True)
        ])

        self.fields['entity_type'].choices = entity_types_choices

        self.fields['groups'].choices = [
            (group.id, group.name)
            for group in Group.objects.filter(subscribe_form=True)
        ]

        self.fields['action_types'].choices = [
            (action_type.id, action_type.name)
            for action_type in ActionType.objects.filter(subscribe_form=True)
        ]

        self._add_subscription_types_field()

        if crm_settings.has_language_choices():
            self.fields['favorite_language'].initial = get_language()

    def clean_entity_type(self):
        """validation"""
        try:
            entity_type = int(self.cleaned_data['entity_type'])
            if entity_type:
                return EntityType.objects.get(id=entity_type)
            return None
        except (ValueError, EntityType.DoesNotExist):
            raise ValidationError(ugettext("Invalid entity type"))

    def get_entity(self):
        """get entity from form"""
        entity_type = self.cleaned_data.get('entity_type', None)
        entity = self.cleaned_data['entity']
        if entity_type:
            if entity:
                return Entity.objects.create(name=entity, type=entity_type)
        else:
            if crm_settings.ALLOW_SINGLE_CONTACT:
                return Entity.objects.create(name=entity,
                                             type=None,
                                             is_single_contact=True)
            else:
                et_id = getattr(settings, 'BALAFON_INDIVIDUAL_ENTITY_ID', 1)
                entity_type = EntityType.objects.get(id=et_id)
                entity_name = "{0} {1}".format(self.cleaned_data['lastname'],
                                               self.cleaned_data['firstname'])
                return Entity.objects.create(name=entity_name,
                                             type=entity_type)

    def clean_entity(self):
        """validation"""
        entity_type = self.cleaned_data.get('entity_type', None)
        entity = self._dehtmled_field("entity")
        if entity_type:
            if not entity:
                raise ValidationError("{0}: {1}".format(
                    entity_type.name, ugettext("Please enter a name")))
        else:
            data = [self.cleaned_data[x] for x in ('lastname', 'firstname')]
            entity = ' '.join([x for x in data if x]).strip().upper()

        return entity

    def _dehtmled_field(self, fieldname, **kwargs):
        """html to text for a field content"""
        value = self.cleaned_data[fieldname]
        return dehtml(value, **kwargs)

    def clean_lastname(self):
        """validate lastname"""
        return self._dehtmled_field("lastname")

    def clean_firstname(self):
        """validate firstname"""
        return self._dehtmled_field("firstname")

    def clean_phone(self):
        """validate phone"""
        return self._dehtmled_field("phone")

    def clean_mobile(self):
        """validate mobile phone"""
        return self._dehtmled_field("mobile")

    def clean_address(self):
        """validate address"""
        return self._dehtmled_field("address")

    def clean_address2(self):
        """valiadate address line 2"""
        return self._dehtmled_field("address2")

    def clean_address3(self):
        """validate address line 3"""
        return self._dehtmled_field("address3")

    def clean_message(self):
        """validate message"""
        message = self._dehtmled_field("message", allow_spaces=True)
        if len(message) > 10000:
            raise ValidationError(ugettext("Your message is too long"))
        return message

    def clean_groups(self):
        """validate groups"""
        try:
            groups = [
                Group.objects.get(id=group_id)
                for group_id in self.cleaned_data['groups']
            ]
        except Group.DoesNotExist:
            raise ValidationError(ugettext("Invalid group"))
        return groups

    def clean_action_types(self):
        """validate action types"""
        try:
            action_types = [
                ActionType.objects.get(id=at_id)
                for at_id in self.cleaned_data['action_types']
            ]
        except ActionType.DoesNotExist:
            raise ValidationError(ugettext("Invalid action type"))
        return action_types

    def save(self, request=None):
        """save"""
        contact = super(SubscribeForm, self).save(commit=False)
        contact.entity = self.get_entity()
        contact.city = self.cleaned_data['city']
        contact.favorite_language = self.cleaned_data.get(
            'favorite_language', '')
        contact.save()
        # delete unknown contacts for the current entity
        contact.entity.contact_set.filter(
            lastname='', firstname='').exclude(id=contact.id).delete()

        # force also the city on the entity
        contact.entity.city = contact.city

        groups = self.cleaned_data['groups']
        for group in groups:
            contact.entity.group_set.add(group)
        contact.entity.save()

        subscriptions = self._save_subscription_types(contact)

        message = self.cleaned_data["message"]

        if message:
            action_type = ActionType.objects.get_or_create(
                name=ugettext("Message"))[0]
            action = Action.objects.create(
                subject=ugettext("Message from web site"),
                type=action_type,
                planned_date=datetime.now(),
                detail=message,
                display_on_board=True)
            action.contacts.add(contact)
            action.save()

        if subscriptions:
            create_subscription_action(contact, subscriptions)

        action_types = self.cleaned_data['action_types']
        actions = []
        for action_type in action_types:
            action = Action.objects.create(subject=ugettext("Contact"),
                                           type=action_type,
                                           planned_date=datetime.now(),
                                           display_on_board=True)
            action.contacts.add(contact)
            action.save()
            actions.append(action)

        # send an email
        send_notification_email(request, contact, actions, message)

        return contact