""" Project: PARTS Website Author: Edward Middleton-Smith Precision And Research Technology Systems Limited Technology: Backend Feature: Apply to Founding Partner Program Form Description: Defines Flask-WTF form for handling user input on Apply to Founding Partner Program page. """ # IMPORTS # internal from business_objects.base import Base from business_objects.project_hub.apply_founding_partner_form import Apply_Founding_Partner_Form from business_objects.project_hub.contact_form import Contact_Form from forms.project_hub.contact import AltchaValidator, AltchaField # from models.model_view_store import Model_View_Store # circular from models.model_view_base import Model_View_Base from forms.base import Form_Base # external from flask import Flask, render_template, request, flash, redirect, url_for, current_app from flask_wtf import FlaskForm from wtforms import StringField, TextAreaField, SubmitField, HiddenField, BooleanField, Field, EmailField, IntegerField, SelectField, SelectMultipleField from wtforms.validators import DataRequired, Email, ValidationError, Optional from wtforms.widgets import CheckboxInput, ListWidget import markupsafe from flask_wtf.recaptcha import RecaptchaField from abc import ABCMeta, abstractmethod import json from altcha import verify_solution import base64 def at_least_one_required(form, field): """Validator that requires at least one checkbox to be selected""" if not field.data or len(field.data) == 0: raise ValidationError('Please select at least one option.') class MultiCheckboxField(SelectMultipleField): widget = ListWidget(prefix_label=False) option_widget = CheckboxInput() class Form_Apply_Founding_Partner(FlaskForm): contact_name = StringField( 'Name' , validators = [DataRequired()] ) email = EmailField( 'Email' , validators = [DataRequired()] ) phone_number = StringField( 'Phone number' , validators = [Optional()] ) company_name = StringField( 'Company' , validators = [DataRequired()] ) website = StringField( 'Website / social media' , validators = [Optional()] ) dog_count = IntegerField( 'How many dogs do you currently train regularly?' , validators = [DataRequired()] ) id_years_of_experience = SelectField( 'How long have you been training professionally?' , choices = [ ( '1', 'Less than 1 year' ) , ( '2', 'Less than 3 years' ) , ( '3', 'Less than 5 years' ) , ( '4', 'More than 5 years' ) ] , validators = [DataRequired()] ) ids_speciality = MultiCheckboxField( # SelectMultipleField( 'What type(s) of training do you specialise in?' , choices = [ ( '1', 'Basic obedience' ) , ( '2', 'Puppy training' ) , ( '3', 'Behaviour modification' ) , ( '4', 'Advanced / competition training' ) , ( '5', 'Service / therapy dog training' ) , ( '6', 'Group classes' ) , ( '7', 'One-on-one sessions' ) , ( '8', 'Other (specify below)' ) ] , validators = [at_least_one_required] ) ids_existing_system = MultiCheckboxField( # SelectMultipleField( 'How do you currently manage client information and training records?' , choices = [ ( '1', 'Spreadsheets (Excel/Google Sheets)' ) , ( '2', 'Paper notes/binders' ) , ( '3', 'Generic CRM software' ) , ( '4', 'Mix of different apps' ) , ( '5', 'Mostly in my head/memory' ) , ( '6', 'Other (specify below)' ) ] , validators = [at_least_one_required] ) existing_challenges = TextAreaField( "What's your biggest frustration with your current system?" , validators = [DataRequired()] ) id_existing_time_sink_weekly = SelectField( 'How much time do you spend on training-related admin work per week?' , choices = [ ( '1', 'Less than 1 hour' ) , ( '2', 'Less than 3 hours' ) , ( '3', 'Less than 6 hours' ) , ( '3', 'Less than 10 hours' ) , ( '4', 'More than 10 hours' ) ] , validators = [DataRequired()] ) id_commitment_frequency = SelectField( 'Are you willing to provide regular feedback during the beta phase?' , choices = [ ( '1', 'Yes, weekly feedback' ) , ( '2', 'Yes, monthly feedback' ) , ( '3', 'Occasional feedback only' ) , ( '4', 'Just want to use the software' ) ] , validators = [DataRequired()] ) """ implementation_timeline = SelectField( "What's your timeline for implementing new business management software?" , choices = [ , ( '1', 'Immediately' ) , ( '2', 'Within 1 month' ) , ( '3', 'Within 3 months' ) , ( '4', 'When the right solution comes along' ) , ( '5', 'No timeline yet' ) ] , validators = [DataRequired()] ) most_valuable_feature = TextAreaField( 'What feature would be most valuable to your business?' , validators = [DataRequired()] ) """ notes = TextAreaField( "Anything else you'd like us to know about your business or training approach?" , validators = [Optional()] ) altcha = AltchaField('Verify you are human') submit = SubmitField('Send Message') def to_json(self): return { Contact_Form.FLAG_NAME_CONTACT: self.contact_name.data , Base.FLAG_EMAIL: self.email.data , Base.FLAG_PHONE_NUMBER: self.phone_number.data , Contact_Form.FLAG_NAME_COMPANY: self.company_name.data , Base.FLAG_WEBSITE: self.website.data , Apply_Founding_Partner_Form.FLAG_DOG_COUNT: self.dog_count.data , Apply_Founding_Partner_Form.FLAG_YEARS_OF_EXPERIENCE: self.id_years_of_experience.data , Apply_Founding_Partner_Form.FLAG_SPECIALITY: ','.join(self.ids_speciality.data) , Apply_Founding_Partner_Form.FLAG_EXISTING_SYSTEM: ','.join(self.ids_existing_system.data) , Apply_Founding_Partner_Form.FLAG_EXISTING_CHALLENGES: self.existing_challenges.data , Apply_Founding_Partner_Form.FLAG_EXISTING_TIME_SINK_WEEKLY: self.id_existing_time_sink_weekly.data , Apply_Founding_Partner_Form.FLAG_COMMITMENT_FREQUENCY: self.id_commitment_frequency.data # , Apply_Founding_Partner_Form.FLAG_IMPLEMENTATION_TIMELINE: self.implementation_timeline.data # , Apply_Founding_Partner_Form.FLAG_MOST_VALUABLE_FEATURE: self.most_valuable_feature.data , Apply_Founding_Partner_Form.FLAG_NOTES: self.notes.data , Contact_Form.FLAG_ALTCHA: self.altcha.data , Base.FLAG_ACTIVE: True , Base.FLAG_CREATED_ON: None }