""" Formulaires WTForms pour la GMAO """ from flask_wtf import FlaskForm from wtforms import (StringField, TextAreaField, SelectField, IntegerField, FloatField, DateField, BooleanField, PasswordField, FieldList, FormField) from wtforms.validators import (DataRequired, Optional, Email, Length, NumberRange, ValidationError) def coerce_int_or_none(value): """Convertit en int ou retourne None pour les chaînes vides.""" if value is None or value == '' or value == 'None': return None try: return int(value) except (ValueError, TypeError): return None # ─── Authentification ────────────────────────────────────────── class LoginForm(FlaskForm): username = StringField("Nom d'utilisateur", validators=[DataRequired()]) password = PasswordField("Mot de passe", validators=[DataRequired()]) class UserForm(FlaskForm): username = StringField("Nom d'utilisateur", validators=[DataRequired(), Length(3, 80)]) email = StringField("Email", validators=[DataRequired(), Email()]) full_name = StringField("Nom complet", validators=[DataRequired()]) password = PasswordField("Mot de passe", validators=[Optional(), Length(min=12)]) role = SelectField("Rôle", choices=[ ("admin", "Administrateur"), ("responsable_gmao", "Responsable GMAO"), ("technicien", "Technicien"), ("assistant_prevention", "Assistant de prévention"), ("demandeur", "Demandeur"), ("lecture", "Lecture seule"), ]) is_active = BooleanField("Actif") class PasswordForm(FlaskForm): current_password = PasswordField("Mot de passe actuel", validators=[DataRequired()]) new_password = PasswordField("Nouveau mot de passe", validators=[ DataRequired(), Length(min=12, message="Le mot de passe doit contenir au moins 12 caractères") ]) confirm_password = PasswordField("Confirmer le nouveau mot de passe", validators=[ DataRequired() ]) def validate_confirm_password(form, field): if field.data != form.new_password.data: raise ValidationError("Les mots de passe ne correspondent pas") # ─── Bâtiments & Salles ──────────────────────────────────────── class BuildingForm(FlaskForm): name = StringField("Nom du bâtiment", validators=[DataRequired()]) description = TextAreaField("Description") class RoomForm(FlaskForm): name = StringField("Nom de la salle", validators=[DataRequired()]) code = StringField("Code", validators=[Optional()]) floor = IntegerField("Étage", validators=[Optional()], default=0) building_id = SelectField("Bâtiment", coerce=int, validators=[DataRequired()]) room_type_id = SelectField("Type de salle", coerce=coerce_int_or_none, validators=[Optional()]) class RoomTypeForm(FlaskForm): name = StringField("Nom du type", validators=[DataRequired()]) description = TextAreaField("Description") is_teaching = BooleanField("Type enseignement (avec planning)", default=False) color = SelectField("Couleur", choices=[ ("primary", "Bleu"), ("secondary", "Gris"), ("success", "Vert"), ("danger", "Rouge"), ("warning", "Orange"), ("info", "Cyan"), ("dark", "Noir"), ], default="primary") # ─── Équipements ──────────────────────────────────────────────── class EquipmentCategoryForm(FlaskForm): name = StringField("Nom de la catégorie", validators=[DataRequired()]) description = TextAreaField("Description") class EquipmentForm(FlaskForm): name = StringField("Nom de l'équipement", validators=[DataRequired()]) code = StringField("Code interne", validators=[Optional()]) description = TextAreaField("Description") status = SelectField("Statut", choices=[ ("en_service", "En service"), ("hors_service", "Hors service"), ("en_reparation", "En réparation"), ("remplace", "Remplacé"), ]) location = StringField("Emplacement", validators=[Optional()]) room_id = SelectField("Salle", coerce=coerce_int_or_none, validators=[Optional()]) category_id = SelectField("Catégorie", coerce=coerce_int_or_none, validators=[Optional()]) # ─── Interventions ──────────────────────────────────────────────── class InterventionForm(FlaskForm): title = StringField("Titre", validators=[DataRequired()]) description = TextAreaField("Description") intervention_type = SelectField("Type", choices=[ ("curatif", "Curatif"), ("preventif", "Préventif"), ("amelioratif", "Amélioratif"), ("administratif", "Administratif"), ("formation", "Formation"), ]) priority = SelectField("Priorité", choices=[ ("basse", "Basse"), ("normale", "Normale"), ("haute", "Haute"), ("urgente", "Urgente"), ]) status = SelectField("Statut", choices=[ ("en_attente", "En attente"), ("en_cours", "En cours"), ("terminee", "Terminée"), ("annulee", "Annulée"), ]) lot_id = SelectField("Lot", coerce=coerce_int_or_none, validators=[Optional()]) equipment_id = SelectField("Équipement", coerce=coerce_int_or_none, validators=[Optional()]) room_id = SelectField("Salle", coerce=coerce_int_or_none, validators=[Optional()]) assigned_to = SelectField("Technicien assigné", coerce=coerce_int_or_none, validators=[Optional()]) scheduled_date = DateField("Date prévue", validators=[Optional()]) estimated_duration = FloatField("Durée estimée (heures)", validators=[Optional()]) requester_name = StringField("Demandeur", validators=[Optional()]) # ─── Lots ──────────────────────────────────────────────────────── class LotForm(FlaskForm): name = StringField("Nom du lot", validators=[DataRequired()]) description = TextAreaField("Description") category = StringField("Catégorie", validators=[Optional()]) company_id = SelectField("Entreprise", coerce=coerce_int_or_none, validators=[Optional()]) service_id = SelectField("Service", coerce=coerce_int_or_none, validators=[Optional()]) is_active = BooleanField("Actif", default=True) # ─── Entreprises ──────────────────────────────────────────────── class CompanyForm(FlaskForm): name = StringField("Nom de l'entreprise", validators=[DataRequired()]) contact_name = StringField("Nom du contact", validators=[Optional()]) contact_email = StringField("Email du contact", validators=[Optional(), Email()]) contact_phone = StringField("Téléphone du contact", validators=[Optional()]) address = TextAreaField("Adresse") is_active = BooleanField("Active", default=True) # ─── Collège ──────────────────────────────────────────────── class CollegeForm(FlaskForm): name = StringField("Nom du collège", validators=[DataRequired()]) code = StringField("Code UAI", validators=[Optional()]) address = StringField("Adresse", validators=[Optional()]) city = StringField("Ville", validators=[Optional()]) postal_code = StringField("Code postal", validators=[Optional()]) phone = StringField("Téléphone", validators=[Optional()]) email = StringField("Email", validators=[Optional(), Email()]) principal_name = StringField("Nom du principal", validators=[Optional()])