system for validating answers to signup forms
This commit is contained in:
parent
6d8b06dfc7
commit
f8c576263c
@ -1,5 +1,5 @@
|
||||
from typing import Literal, Self
|
||||
from pydantic import model_validator
|
||||
from typing import Literal, Self, Annotated
|
||||
from pydantic import model_validator, Field
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
@ -8,8 +8,17 @@ from .submodels import ActivityPaymentInfo
|
||||
from .enums import CommunicationCategory
|
||||
|
||||
from fiber_package.refs import SignupRefList
|
||||
from fiber_package.signup.signup import SignupModel
|
||||
from fiber_package.signup.util import validate_answer
|
||||
|
||||
from fiber_package.signup.elements.form_element import FormElement
|
||||
from fiber_package.signup.element.form_base_text import FormBaseText
|
||||
from fiber_package.signup.element.form_base_question import FormBaseQuestion
|
||||
|
||||
# Special type which uses enum category to decide type!
|
||||
FieldUnionType = Annotated[
|
||||
FormBaseText | FormBaseQuestion,
|
||||
Field(discriminator="category")
|
||||
]
|
||||
|
||||
class ActivityModel(CommunicationModel):
|
||||
category: Literal[CommunicationCategory.activity]
|
||||
@ -22,7 +31,7 @@ class ActivityModel(CommunicationModel):
|
||||
|
||||
payment_info: ActivityPaymentInfo | None = None
|
||||
|
||||
form: list[FormElement]
|
||||
form: list[FieldUnionType]
|
||||
|
||||
signups: SignupRefList = SignupRefList([], "signup")
|
||||
|
||||
@ -34,3 +43,37 @@ class ActivityModel(CommunicationModel):
|
||||
if self.end_time < self.start_time:
|
||||
raise ValueError("End time cannot be earlier than start time")
|
||||
return self
|
||||
|
||||
def validate_signup_form(self, signup: SignupModel) -> None:
|
||||
required = set()
|
||||
answerable = set()
|
||||
|
||||
question_dict: dict[str, FormBaseQuestion] = {}
|
||||
|
||||
for element in self.form:
|
||||
if isinstance(element, FormBaseText):
|
||||
continue
|
||||
# so we know it is istance of FormBaseQuestion
|
||||
answerable.add(element.name)
|
||||
if element.required:
|
||||
required.add(element.name)
|
||||
question_dict[element.name] = element
|
||||
|
||||
answers = signup.answers
|
||||
for answer in answers:
|
||||
q_name = answer.question_name
|
||||
if q_name not in answerable:
|
||||
raise ValueError(
|
||||
f"Form contains answer to "
|
||||
f"non-existing question {q_name}."
|
||||
)
|
||||
answerable.remove(q_name)
|
||||
if answer.question_name in required:
|
||||
required.remove(q_name)
|
||||
|
||||
question = question_dict[q_name]
|
||||
validate_answer(question, answer)
|
||||
|
||||
|
||||
if len(required) > 0:
|
||||
raise ValueError("Form does not answer all required questions.")
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
from .form_element import FormElement
|
||||
from fiber_package.signup.enums import FormQuestionCategory
|
||||
|
||||
class FormBaseQuestion(FormElement):
|
||||
category: FormQuestionCategory
|
||||
|
||||
required: bool
|
||||
|
||||
title: str | None = None
|
||||
|
||||
5
src/fiber_package/signup/element/form_base_text.py
Normal file
5
src/fiber_package/signup/element/form_base_text.py
Normal file
@ -0,0 +1,5 @@
|
||||
from .form_element import FormElement
|
||||
from fiber_package.signup.enums import FormTextCategory
|
||||
|
||||
class FormBaseText(FormElement):
|
||||
category: FormTextCategory
|
||||
@ -12,3 +12,8 @@ class FormElementCategory(StrEnum):
|
||||
FormQuestionCategory = Literal[
|
||||
FormElementCategory.open_questions
|
||||
]
|
||||
|
||||
FormTextCategory = Literal[
|
||||
FormElementCategory.text_piece,
|
||||
FormElementCategory.title_text
|
||||
]
|
||||
|
||||
18
src/fiber_package/signup/util.py
Normal file
18
src/fiber_package/signup/util.py
Normal file
@ -0,0 +1,18 @@
|
||||
from fiber_package.signup.element.form_base_question import FormBaseQuestion
|
||||
from fiber_package.signup.element.form_open_questions import FormOpenQuestions
|
||||
|
||||
from fiber_package.signup.answer.answer_base import AnswerBase
|
||||
from fiber_package.signup.enums import FormElementCategory
|
||||
|
||||
from fiber_package.signup.answer.answer_open_questions import AnswerOpenQuestions
|
||||
|
||||
def validate_answer(question: FormBaseQuestion, answer: AnswerBase) -> None:
|
||||
if question.category != answer.category:
|
||||
raise ValueError("Question and answer category do not match!")
|
||||
|
||||
if question.category == FormElementCategory.open_questions:
|
||||
question_val = FormOpenQuestions.model_validate(question.model_dump())
|
||||
answer_val = AnswerOpenQuestions.model_validate(answer.model_dump())
|
||||
question_val.validate_answer(answer_val)
|
||||
|
||||
# TODO: implement
|
||||
Loading…
x
Reference in New Issue
Block a user