def __init__(self, *args, **kwargs): # initiate form, define method, and add Submit button super(ProjectForm, self).__init__(*args, **kwargs) self.helper = FormHelper() self.helper.form_method = "post" self.helper.add_input(Submit("submit", "Submit")) # validate form field self.fields['funding_goal'] = forms.DecimalField(min_value=5, decimal_places=2)
class TransactionRefundForm(forms.Form): items = forms.ModelMultipleChoiceField(queryset=BoughtItem.objects.none(), required=False, widget=forms.CheckboxSelectMultiple) amount = forms.DecimalField(required=False, max_digits=9, decimal_places=2, localize=False, min_value=0) def __init__(self, transaction, *args, **kwargs): super(TransactionRefundForm, self).__init__(*args, **kwargs) self.transaction = transaction self.fields[ 'amount'].max_value = self.transaction.get_refundable_amount() self.fields['amount'].initial = self.transaction.get_refundable_amount( ) self.fields['items'].queryset = self.transaction.bought_items.all() self.fields['items'].initial = self.fields['items'].queryset def clean_items(self): """ Check that items being refunded are not already refunded. If they are, ignore them. """ items = self.cleaned_data['items'] return [item for item in items if item.status != BoughtItem.REFUNDED] def clean_amount(self): amount = self.cleaned_data['amount'] refundable_amount = self.transaction.get_refundable_amount() if amount > refundable_amount: msg = 'Amount to refund is larger than amount refundable. Only {0} is left on this transaction.'.format( format_money(refundable_amount, self.transaction.event.currency)) raise ValidationError(msg) return amount def clean(self): cleaned_data = super(TransactionRefundForm, self).clean() amount = cleaned_data.get('amount') items = cleaned_data.get('items') if amount == 0 and len(items) == 0: msg = "Select items or specify a value to refund." raise ValidationError(msg)
def __init__(self, *args, **kwargs): # find maximum amount funder can give to project at current time max_amount = kwargs.pop('initial', None).pop('max_amount', None) super(FundForm, self).__init__(*args, **kwargs) self.helper = FormHelper() self.helper.form_method = "post" self.helper.add_input(Submit("submit", "Submit")) min_value = Decimal('0.01') self.fields['amount'] = forms.DecimalField(min_value=min_value, max_value=max_amount, decimal_places=2)
class AddExtraSaleForm(BetterBsForm): """A form for adding a new extra sale""" analysis_code = forms.ChoiceField(label=_('Analysis code'), required=True) amount = forms.DecimalField(max_digits=9, decimal_places=2, required=True, label=_('Amount')) vat_rate = forms.ChoiceField(label=_('VAT rate'), required=True) date = forms.DateField(label=_('Date'), required=True) def __init__(self, *args, **kwargs): super(AddExtraSaleForm, self).__init__(*args, **kwargs) self.valid_action_types = [ item.action_type for item in StoreManagementActionType.objects.all() ] self.fields['analysis_code'].choices = [ (analysis_code.id, analysis_code.name) for analysis_code in SaleAnalysisCode.objects.filter( action_type__in=self.valid_action_types) ] self.fields['vat_rate'].choices = [ (vat_rate.id, vat_rate.name) for vat_rate in VatRate.objects.all() ] self.fields['date'].initial = date.today() def clean_analysis_code(self): """validate the analysis code""" analysis_code_id = self.cleaned_data['analysis_code'] try: return SaleAnalysisCode.objects.get( id=analysis_code_id, action_type__in=self.valid_action_types) except SaleAnalysisCode.DoesNotExist: forms.ValidationError(ugettext('Invalid analysis code')) def clean_vat_rate(self): """validate the analysis code""" vat_rate_id = self.cleaned_data['vat_rate'] try: return VatRate.objects.get(id=vat_rate_id) except VatRate.DoesNotExist: forms.ValidationError(ugettext('Invalid analysis code'))
class RegistrationForm(forms.Form): honeypot = forms.CharField(required=False, widget=forms.HiddenInput) firstname = forms.CharField(label=_('Your first name?')) lastname = forms.CharField(label=_('Your last name:')) username = forms.CharField(max_length=30) password = forms.CharField( widget=forms.PasswordInput, help_text=_('Make sure to use a secure password.'), ) password2 = forms.CharField(label=_('Retype password'), widget=forms.PasswordInput) age = forms.IntegerField(required=False) height = forms.DecimalField(localize=True, required=False) agree_to_terms = forms.BooleanField() def clean_honeypot(self): if self.cleaned_data.get('honeypot'): raise ValidationError('Haha, you trapped into the honeypot.') return self.cleaned_data['honeypot'] def clean(self): if self.errors: raise ValidationError('Please correct the errors below.')
class ActionForm(FormWithFieldsetMixin, BetterBsModelForm): """form for creating or editing action""" date = forms.DateField(label=_(u"planned date"), required=False, widget=forms.TextInput()) time = forms.TimeField(label=_(u"planned time"), required=False) end_date = forms.DateField(label=_(u"end date"), required=False, widget=forms.TextInput()) end_time = forms.TimeField(label=_(u"end time"), required=False) amount = forms.DecimalField(label=_("Amount"), required=False) class Meta: """form from model""" model = models.Action fields = ( 'type', 'subject', 'date', 'time', 'status', 'status2', 'in_charge', 'detail', 'amount', 'number', 'planned_date', 'end_date', 'end_time', 'end_datetime', 'opportunity' ) fieldsets = [ ('summary', { 'fields': [ 'subject', 'in_charge', 'date', 'time', 'planned_date', 'end_date', 'end_time', 'end_datetime', 'opportunity' ], 'legend': _('Summary') }), ('type', {'fields': ['type', 'status', 'status2', 'amount', 'number'], 'legend': _('Type')}), ('details', {'fields': ['detail'], 'legend': _('Details')}), ] help_texts = { 'amount': _('Amount is disabled when value is calculated'), } 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") def _init_dt_field(self, dt_field, date_field, time_field): """init datetime fields""" self.fields[dt_field].widget = CalcHiddenInput() the_datetime = getattr(self.instance, dt_field) if self.instance else self.fields[dt_field].initial if the_datetime: self.fields[date_field].initial = the_datetime.date() if settings.USE_TZ: utc_dt = the_datetime.replace(tzinfo=timezone.utc) loc_dt = utc_dt.astimezone(timezone.get_current_timezone()) self.fields[time_field].initial = loc_dt.time() else: self.fields[time_field].initial = the_datetime.time() is_frozen = self.instance.frozen if self.instance else False if is_frozen: self.fields[date_field].widget.attrs['disabled'] = 'disabled' self.fields[time_field].widget.attrs['disabled'] = 'disabled' def clean_status(self): """status validation""" type_of = self.cleaned_data.get('type') or self.action_type status = self.cleaned_data['status'] if type_of: allowed_status = ([] if type_of.default_status else [None]) + list(type_of.allowed_status.all()) if len(allowed_status) > 0 and status not in allowed_status: raise ValidationError(ugettext(u"This status can't not be used for this action type")) else: if status: raise ValidationError(ugettext(u"Please select a type before defining the status")) return status def clean_status2(self): """status validation""" type_of = self.cleaned_data['type'] status = self.cleaned_data['status2'] if type_of: allowed_status = ([] if type_of.default_status2 else [None]) + list(type_of.allowed_status2.all()) if len(allowed_status) > 0 and status not in allowed_status: raise ValidationError(ugettext(u"This status can't not be used for this action type")) else: if status: raise ValidationError(ugettext(u"Please select a type before defining the status")) return status def clean_planned_date(self): """planned date validation""" the_date = self.cleaned_data.get("date", None) the_time = self.cleaned_data.get("time", None) if the_date: return datetime.combine(the_date, the_time or datetime.min.time()) return None def clean_time(self): """time validation""" the_date = self.cleaned_data.get("date", None) the_time = self.cleaned_data.get("time", None) if the_time and not the_date: raise ValidationError(_(u"You must set a date")) return the_time def clean_end_date(self): """end date validation""" date1 = self.cleaned_data.get("date", None) date2 = self.cleaned_data.get("end_date", None) if date2: start_dt = self.cleaned_data["planned_date"] if not start_dt: raise ValidationError(_(u"The planned date is not defined")) if date1 > date2: raise ValidationError(_(u"The end date must be after the planned date")) return date2 def clean_end_time(self): """end time validation""" date1 = self.cleaned_data.get("date", None) date2 = self.cleaned_data.get("end_date", None) time1 = self.cleaned_data.get("time", None) time2 = self.cleaned_data.get("end_time", None) if time2: if time2 and not date2: raise ValidationError(_(u"You must set a end date")) if date1 == date2 and (time1 or datetime.min.time()) >= time2: raise ValidationError(_(u"The end time must be after the planned time")) elif time1: if date1 == date2 and time1 >= datetime.min.time(): raise ValidationError(_(u"The end time must be set")) return time2 def clean_end_datetime(self): """clean end datetime""" end_date = self.cleaned_data.get("end_date", None) end_time = self.cleaned_data.get("end_time", None) if end_date: return datetime.combine(end_date, end_time or datetime.min.time()) return None def clean_amount(self): if self.is_amount_calculated: return self.calculated_amount else: return self.cleaned_data['amount'] def save(self, *args, **kwargs): return super(ActionForm, self).save(*args, **kwargs)
class DecimalForm(DjangoForm): num = forms.DecimalField(decimal_places=2, max_value=10.5) other = forms.DecimalField(decimal_places=1) third = forms.DecimalField(decimal_places=3, min_value=-10, max_value=15)
def test_parse_decimal(self): decimal_field = forms.DecimalField(decimal_places=2) result = decimal_field.clean('1.5') self.assertEqual(decimal.Decimal('1.5'), result) self.assertIsInstance(result, decimal.Decimal)
class BankTransactionListForm(forms.Form): label = forms.CharField( max_length=255, required=False, widget=forms.TextInput(attrs={ 'placeholder': ugettext_lazy('Label'), })) date_start = forms.DateField( required=False, widget=Datepicker(attrs={ 'placeholder': ugettext_lazy('Date start'), }), ) date_end = forms.DateField( required=False, widget=Datepicker(attrs={ 'placeholder': ugettext_lazy('Date end'), }), ) amount_min = forms.DecimalField( max_digits=10, decimal_places=2, localize=True, required=False, widget=forms.NumberInput( attrs={ 'placeholder': ugettext_lazy('Minimum amount'), }), ) amount_max = forms.DecimalField( max_digits=10, decimal_places=2, localize=True, required=False, widget=forms.NumberInput( attrs={ 'placeholder': ugettext_lazy('Maximum amount'), }), ) status = forms.ChoiceField( choices=(('', ugettext_lazy('Status?')), ) + BankTransaction.STATUSES, initial='', required=False, ) reconciled = forms.NullBooleanField(required=False) tags = forms.ModelMultipleChoiceField( queryset=BankTransactionTag.objects.none(), required=False) operation = forms.ChoiceField( choices=(), required=False, ) def __init__(self, user, bt_ids, submit, *args, **kwargs): super(BankTransactionListForm, self).__init__(*args, **kwargs) self.fields['tags'].queryset = ( BankTransactionTag.objects.get_user_tags_queryset(user)) self.fields['reconciled'].widget.choices[0] = ('1', _('Reconciled?')) for pk in bt_ids: self.fields['banktransaction_' + str(pk)] = forms.BooleanField( required=False, widget=forms.CheckboxInput(attrs={'data-id': pk})) choices = () if user.has_perm('banktransactions.change_banktransaction'): choices += ( ('reconcile', _('Reconcile')), ('unreconcile', _('Unreconcile')), ) if user.has_perm('banktransactions.delete_banktransaction'): choices += (('delete', _('Delete')), ) if choices: self.fields['operation'].choices = choices self._submit = submit def clean(self): cleaned_data = super(BankTransactionListForm, self).clean() if self._submit == 'filter': date_start = cleaned_data.get('date_start') date_end = cleaned_data.get('date_end') if date_start and date_end and date_start > date_end: raise forms.ValidationError( _("Date start could not be greater than date end."), code='date_start_greater', ) amount_min = cleaned_data.get('amount_min', None) amount_max = cleaned_data.get('amount_max', None) if (amount_min is not None and amount_max is not None and amount_min > amount_max): raise forms.ValidationError( _("Minimum amount could not be greater than maximum " "amount."), code='amount_min_greater', ) if self._submit == 'action' and cleaned_data['operation']: ids = set() for name, value in cleaned_data.items(): if name.startswith('banktransaction_') and value: ids.add(int(name[len('banktransaction_'):])) if not ids: raise forms.ValidationError( _('To apply operations, you need to select some bank ' 'transactions.'), code='no_id', ) cleaned_data['banktransactions'] = ids return cleaned_data