from flask_wtf import Form from wtforms import DateField, IntegerField, DecimalField, StringField, SelectField, SubmitField, SelectMultipleField, BooleanField from wtforms.validators import ValidationError, Length from datetime import date def date_check(form, field): """ Checks that the date of the pitstop is not before the date of the latest pitstop and not after today. :param form: the form where the field is in :param field: the field to check :return: Nothing or a ValidationError if the limits are not kept """ if field.data < form.last_pitstop.date: raise ValidationError('The new date must not be before %s' % form.last_pitstop.date) if field.data > date.today(): raise ValidationError('The new date must not be after %s' % date.today()) def odometer_check(form, field): """ :param form: :param field: :return: """ if not form.same_odometer_allowed and field.data <= form.last_pitstop.odometer: raise ValidationError('The new odometer value must be higher than %i km' % form.last_pitstop.odometer) if form.same_odometer_allowed and field.data < form.last_pitstop.odometer: raise ValidationError('The new odometer value must be higher than %i km' % form.last_pitstop.odometer) def litres_check(form, field): if field.data is not None and field.data <= 0: raise ValidationError('You must fuel at least 0.1 l') def costs_check(form, field): if field.data is not None and field.data <= 0: raise ValidationError('Costs must be above 0.01 €.') def edit_costs_check(form, field): """ Costs must be given, if a default value was given to the form field. :param form: :param field: :return: """ costs_check_required = (form.costs.default is not None and form.costs.default > 0) if costs_check_required and field.data is not None and field.data <= 0: raise ValidationError('Costs must be above 0.01 €.') class SelectVehicleForm(Form): vehicle = SelectField('Vehicle', coerce=int) submit = SubmitField(label='Do it!') class SelectConsumableForm(Form): consumable = SelectField('Consumable', coerce=int) submit = SubmitField(label='Do it!') class CreatePitstopForm(Form): date = DateField('Date of Pitstop', validators=[date_check]) odometer = IntegerField('Odometer (km)', validators=[odometer_check]) litres = DecimalField('Litres (l)', places=2, validators=[litres_check]) costs = DecimalField('Costs (€, overall)', places=2, validators=[costs_check]) submit = SubmitField(label='Do it!') last_pitstop = None same_odometer_allowed = True def set_pitstop(self, last_pitstop): self.last_pitstop = last_pitstop def set_consumable(self, consumable): self.litres.label = '%s (%s)' % (consumable.name, consumable.unit) def preinit_with_data(self): if self.date.data: self.date.default = self.date.data else: self.date.default = self.last_pitstop.date if self.odometer.data: self.odometer.default = self.odometer.data else: self.odometer.default = self.last_pitstop.odometer if self.litres.data: self.litres.default = self.litres.data else: self.litres.default = self.last_pitstop.amount if self.costs.data: self.costs.default = self.costs.data else: self.costs.default = self.last_pitstop.costs def get_hint_messages(self): if self.same_odometer_allowed: or_equal = ' or equal to' else: or_equal = '' messages = { 'date': 'Date must be between %s and %s (including).' % (str(self.last_pitstop.date), str(date.today())), 'odometer': 'Odometer must be greater than%s %s km.' % (or_equal, str(self.last_pitstop.odometer)), 'costs': 'Costs must be higher than 0.01 €.' } return messages class EditVehicleForm(Form): name = StringField('Name', validators=[Length(1, 255)]) consumables = SelectMultipleField('Consumables', coerce=int,validators=[]) submit = SubmitField(label='Do it!') class DeleteVehicleForm(Form): submit = SubmitField(label='Do it!') class DeleteAccountForm(Form): submit = SubmitField(label='Really delete my account!') class DeletePitStopForm(Form): submit = SubmitField(label='Really delete this pitstop!') class EditPitstopForm(Form): date = DateField('Date of Pitstop', validators=[date_check]) odometer = IntegerField('Odometer (km)', validators=[odometer_check]) litres = DecimalField('Litres (l)', places=2, validators=[litres_check]) costs = DecimalField('Costs (€, overall)', places=2, validators=[edit_costs_check]) submit = SubmitField(label='Update it!') last_pitstop = None same_odometer_allowed = True def set_pitstop(self, last_pitstop): self.last_pitstop = last_pitstop def set_consumable(self, consumable): self.litres.label = '%s (%s)' % (consumable.name, consumable.unit) def preinit_with_data(self): if self.date.data: self.date.default = self.date.data if self.odometer.data: self.odometer.default = self.odometer.data if self.litres.data: self.litres.default = self.litres.data if self.costs.data: self.costs.default = self.costs.data class CreateConsumableForm(Form): name = StringField('Name', validators=[Length(1, 255)]) unit = StringField('Unit', validators=[Length(1, 255)]) submit = SubmitField(label='Do it!') class EditConsumableForm(Form): name = StringField('Name', validators=[Length(1, 255)]) unit = StringField('Unit', validators=[Length(1, 255)]) submit = SubmitField(label='Do it!') class DeletConsumableForm(Form): submit = SubmitField(label='Do it!')