207 lines
10 KiB
Python
207 lines
10 KiB
Python
from flask import current_app, session
|
|
from flask_wtf import FlaskForm
|
|
from wtforms import (StringField, BooleanField, SubmitField, EmailField, IntegerField, DateField,
|
|
SelectField, SelectMultipleField, FieldList, FormField, TextAreaField)
|
|
from wtforms.validators import DataRequired, Length, Email, NumberRange, Optional, ValidationError
|
|
import pytz
|
|
from flask_security import current_user
|
|
from wtforms.widgets.core import HiddenInput
|
|
|
|
from common.models.user import TenantMake
|
|
from common.services.user import UserServices
|
|
from config.type_defs.service_types import SERVICE_TYPES
|
|
from eveai_app.views.dynamic_form_base import DynamicFormBase
|
|
|
|
|
|
class TenantForm(FlaskForm):
|
|
name = StringField('Name', validators=[DataRequired(), Length(max=80)])
|
|
code = StringField('Code', validators=[DataRequired()], render_kw={'readonly': True})
|
|
type = SelectField('Tenant Type', validators=[Optional()], default='Active')
|
|
website = StringField('Website', validators=[DataRequired(), Length(max=255)])
|
|
# language fields
|
|
default_language = SelectField('Default Language', choices=[], validators=[DataRequired()])
|
|
# invoicing fields
|
|
currency = SelectField('Currency', choices=[], validators=[DataRequired()])
|
|
# Timezone
|
|
timezone = SelectField('Timezone', choices=[], validators=[DataRequired()])
|
|
|
|
# For Super Users only - Allow to assign the tenant to the partner
|
|
assign_to_partner = BooleanField('Assign to Partner', default=False)
|
|
# Embedding variables
|
|
submit = SubmitField('Submit')
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(TenantForm, self).__init__(*args, **kwargs)
|
|
# initialise language fields
|
|
self.default_language.choices = [(lang, lang.lower()) for lang in current_app.config['SUPPORTED_LANGUAGES']]
|
|
# initialise currency field
|
|
self.currency.choices = [(curr, curr) for curr in current_app.config['SUPPORTED_CURRENCIES']]
|
|
# initialise timezone
|
|
self.timezone.choices = [(tz, tz) for tz in pytz.common_timezones]
|
|
# Initialize fallback algorithms
|
|
self.type.choices = [(t, t) for t in current_app.config['TENANT_TYPES']]
|
|
# Initialize default tenant make choices
|
|
tenant_id = session.get('tenant', {}).get('id') if 'tenant' in session else None
|
|
# Show field only for Super Users with partner in session
|
|
if not current_user.has_roles('Super User') or 'partner' not in session:
|
|
self._fields.pop('assign_to_partner', None)
|
|
|
|
|
|
class EditTenantForm(FlaskForm):
|
|
id = IntegerField('ID', widget=HiddenInput())
|
|
name = StringField('Name', validators=[DataRequired(), Length(max=80)])
|
|
code = StringField('Code', validators=[DataRequired()], render_kw={'readonly': True})
|
|
type = SelectField('Tenant Type', validators=[Optional()], default='Active')
|
|
website = StringField('Website', validators=[DataRequired(), Length(max=255)])
|
|
# language fields
|
|
default_language = SelectField('Default Language', choices=[], validators=[DataRequired()])
|
|
# invoicing fields
|
|
currency = SelectField('Currency', choices=[], validators=[DataRequired()])
|
|
# Timezone
|
|
timezone = SelectField('Timezone', choices=[], validators=[DataRequired()])
|
|
# Default tenant make
|
|
default_tenant_make_id = SelectField('Default Tenant Make', choices=[], validators=[Optional()])
|
|
|
|
# For Super Users only - Allow to assign the tenant to the partner
|
|
assign_to_partner = BooleanField('Assign to Partner', default=False)
|
|
# Embedding variables
|
|
submit = SubmitField('Submit')
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(EditTenantForm, self).__init__(*args, **kwargs)
|
|
# initialise language fields
|
|
self.default_language.choices = [(lang, lang.lower()) for lang in current_app.config['SUPPORTED_LANGUAGES']]
|
|
# initialise currency field
|
|
self.currency.choices = [(curr, curr) for curr in current_app.config['SUPPORTED_CURRENCIES']]
|
|
# initialise timezone
|
|
self.timezone.choices = [(tz, tz) for tz in pytz.common_timezones]
|
|
# Initialize fallback algorithms
|
|
self.type.choices = [(t, t) for t in current_app.config['TENANT_TYPES']]
|
|
# Initialize default tenant make choices
|
|
tenant_id = self.id.data
|
|
if tenant_id:
|
|
tenant_makes = TenantMake.query.filter_by(tenant_id=tenant_id, active=True).all()
|
|
self.default_tenant_make_id.choices = [(str(make.id), make.name) for make in tenant_makes]
|
|
# Add empty choice
|
|
self.default_tenant_make_id.choices.insert(0, ('', 'Geen'))
|
|
# Show field only for Super Users with partner in session
|
|
if not current_user.has_roles('Super User') or 'partner' not in session:
|
|
self._fields.pop('assign_to_partner', None)
|
|
|
|
|
|
class BaseUserForm(FlaskForm):
|
|
user_name = StringField('Name', validators=[DataRequired(), Length(max=80)])
|
|
email = EmailField('Email', validators=[DataRequired(), Email()])
|
|
first_name = StringField('First Name', validators=[DataRequired(), Length(max=80)])
|
|
last_name = StringField('Last Name', validators=[DataRequired(), Length(max=80)])
|
|
valid_to = DateField('Valid to', id='form-control datepicker', validators=[Optional()])
|
|
tenant_id = IntegerField('Tenant ID', validators=[NumberRange(min=0)])
|
|
roles = SelectMultipleField('Roles', coerce=int)
|
|
is_primary_contact = BooleanField('Primary Contact')
|
|
is_financial_contact = BooleanField('Financial Contact')
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(BaseUserForm, self).__init__(*args, **kwargs)
|
|
self.roles.choices = UserServices.get_assignable_roles()
|
|
|
|
|
|
class CreateUserForm(BaseUserForm):
|
|
submit = SubmitField('Create User')
|
|
|
|
|
|
class EditUserForm(BaseUserForm):
|
|
# Some R/O informational fields
|
|
confirmed_at = DateField('Confirmed At', id='form-control datepicker', validators=[Optional()],
|
|
render_kw={'readonly': True})
|
|
last_login_at = DateField('Last Login At', id='form-control datepicker', validators=[Optional()],
|
|
render_kw={'readonly': True})
|
|
login_count = IntegerField('Login Count', validators=[Optional()], render_kw={'readonly': True})
|
|
submit = SubmitField('Save User')
|
|
|
|
|
|
class RoleForm(FlaskForm):
|
|
# This subform will represent a single checkbox for each role
|
|
role_id = StringField('Role ID')
|
|
checked = BooleanField('Assigned')
|
|
|
|
|
|
class UserRoleForm(FlaskForm):
|
|
email = EmailField('Email', validators=[DataRequired(), Email()])
|
|
roles = FieldList(FormField(RoleForm), min_entries=1)
|
|
submit = SubmitField('Update Roles')
|
|
|
|
|
|
class TenantDomainForm(FlaskForm):
|
|
domain = StringField('Domain', validators=[DataRequired(), Length(max=80)])
|
|
valid_to = DateField('Valid to', id='form-control datepicker', validators=[Optional()])
|
|
submit = SubmitField('Add Domain')
|
|
|
|
|
|
class TenantSelectionForm(FlaskForm):
|
|
types = SelectMultipleField('Tenant Types', choices=[], validators=[Optional()])
|
|
search = StringField('Search', validators=[Optional()])
|
|
submit = SubmitField('Filter')
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(TenantSelectionForm, self).__init__(*args, **kwargs)
|
|
self.types.choices = [(t, t) for t in current_app.config['TENANT_TYPES']]
|
|
|
|
|
|
class TenantProjectForm(FlaskForm):
|
|
name = StringField('Name', validators=[DataRequired(), Length(max=50)])
|
|
description = TextAreaField('Description', validators=[Optional()])
|
|
services = SelectMultipleField('Allowed Services', choices=[], validators=[DataRequired()])
|
|
unencrypted_api_key = StringField('Unencrypted API Key', validators=[DataRequired()], render_kw={'readonly': True})
|
|
visual_api_key = StringField('Visual API Key', validators=[DataRequired()], render_kw={'readonly': True})
|
|
active = BooleanField('Active', validators=[Optional()], default=True)
|
|
responsible_email = EmailField('Responsible Email', validators=[Optional(), Email()])
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
# Initialize choices for the services field
|
|
self.services.choices = [(key, value['description']) for key, value in SERVICE_TYPES.items()]
|
|
|
|
|
|
class EditTenantProjectForm(FlaskForm):
|
|
name = StringField('Name', validators=[DataRequired(), Length(max=50)])
|
|
description = TextAreaField('Description', validators=[Optional()])
|
|
services = SelectMultipleField('Allowed Services', choices=[], validators=[DataRequired()])
|
|
visual_api_key = StringField('Visual API Key', validators=[DataRequired()], render_kw={'readonly': True})
|
|
active = BooleanField('Active', validators=[Optional()], default=True)
|
|
responsible_email = EmailField('Responsible Email', validators=[Optional(), Email()])
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
# Initialize choices for the services field
|
|
self.services.choices = [(key, value['description']) for key, value in SERVICE_TYPES.items()]
|
|
|
|
|
|
def validate_make_name(form, field):
|
|
# Controleer of een TenantMake met deze naam al bestaat
|
|
existing_make = TenantMake.query.filter_by(name=field.data).first()
|
|
|
|
# Als er een bestaande make is gevonden en we zijn niet in edit mode,
|
|
# of als we wel in edit mode zijn maar het is een ander record (andere id)
|
|
if existing_make and (not hasattr(form, 'id') or form.id.data != existing_make.id):
|
|
raise ValidationError(f'A Make with name "{field.data}" already exists. Choose another name.')
|
|
|
|
|
|
class TenantMakeForm(DynamicFormBase):
|
|
name = StringField('Name', validators=[DataRequired(), Length(max=50), validate_make_name])
|
|
description = TextAreaField('Description', validators=[Optional()])
|
|
active = BooleanField('Active', validators=[Optional()], default=True)
|
|
website = StringField('Website', validators=[DataRequired(), Length(max=255)])
|
|
logo_url = StringField('Logo URL', validators=[Optional(), Length(max=255)])
|
|
|
|
class EditTenantMakeForm(DynamicFormBase):
|
|
id = IntegerField('ID', widget=HiddenInput())
|
|
name = StringField('Name', validators=[DataRequired(), Length(max=50), validate_make_name])
|
|
description = TextAreaField('Description', validators=[Optional()])
|
|
active = BooleanField('Active', validators=[Optional()], default=True)
|
|
website = StringField('Website', validators=[DataRequired(), Length(max=255)])
|
|
logo_url = StringField('Logo URL', validators=[Optional(), Length(max=255)])
|
|
|
|
|
|
|
|
|