added form submission

This commit is contained in:
Alexander Karpov 2022-12-09 12:09:22 +03:00
parent 145c322fb5
commit d9f084d48f
5 changed files with 175 additions and 11 deletions

View File

@ -145,3 +145,12 @@ class UserFormFieldSubmission(Base):
"UserFormSubmission",
foreign_keys="UserFormFieldSubmission.submission_id",
)
# question
question_id: int = Column(Integer, ForeignKey(FormQuestion.id), primary_key=True)
question: FormQuestion = relationship(
"FormQuestion",
foreign_keys="UserFormFieldSubmission.question_id",
)
answer: str = Column(String)

View File

@ -3,14 +3,22 @@ from typing import List
from fastapi import HTTPException
from sqlalchemy import select, update
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from med_backend.db.models.forms import (
FormAssignment,
FormQuestion,
FormScheme,
UserFormFieldSubmission,
UserFormSubmission,
UserRevQuestion,
)
from med_backend.forms.schemas import BaseForm, CreateFormField
from med_backend.forms.schemas import (
BaseForm,
CreateFormField,
FullAnswer,
FullSubmission,
)
from med_backend.users.crud import get_user
@ -166,3 +174,84 @@ async def create_user_form_rev_question(
await session.commit()
await session.refresh(rev)
return rev
async def create_submission(session: AsyncSession, form_id: int, user_id: int):
user = await get_user(session, user_id)
if not user:
raise HTTPException(status_code=422, detail="User can't be used")
form = await get_form(session, form_id)
if not form:
raise HTTPException(status_code=422, detail="Form can't be used")
obj = UserFormSubmission(form_id=form_id, user_id=user_id)
session.add(obj)
await session.commit()
await session.refresh(obj)
return obj
async def create_submission_answer(
session: AsyncSession,
sumb_id: int,
field_id: int,
data: str,
):
r = await session.execute(select(FormQuestion).where(FormQuestion.id == field_id))
field = r.scalars().first()
if not field:
raise HTTPException(status_code=422, detail="Such field doesn't exist")
obj = UserFormFieldSubmission(
submission_id=sumb_id,
question_id=field_id,
answer=data,
)
session.add(obj)
await session.commit()
await session.refresh(obj)
return obj
async def get_submissions(session: AsyncSession, form_id: int) -> List[FullSubmission]:
r = await session.execute(
select(UserFormSubmission)
.options(selectinload(UserFormSubmission.answers))
.options(selectinload(UserFormSubmission.user))
.where(UserFormSubmission.form_id == form_id),
)
submissions = r.scalars().all()
res: List[FullSubmission] = []
for submission in submissions:
answers: List[FullAnswer] = []
for answer in submission.answers:
r = await session.execute(
select(UserRevQuestion)
.where(UserRevQuestion.user_id == submission.user.id)
.where(UserRevQuestion.question_id == answer.question_id),
)
obj = r.scalars().first()
ref_min = None
ref_max = None
if obj:
ref_min = obj.ref_min
ref_max = obj.ref_max
r = await session.execute(
select(FormQuestion).where(FormQuestion.id == answer.question_id),
)
obj = r.scalars().first()
answers.append(
FullAnswer(
field_id=obj.id,
question=obj.question,
type=obj.type,
answer=answer.answer,
ref_min=ref_min if ref_min else obj.ref_min,
ref_max=ref_max if ref_max else obj.ref_max,
),
)
res.append(FullSubmission(fio=submission.user.fullname, answers=answers))
return res

View File

@ -2,8 +2,6 @@ from typing import List
from pydantic import BaseModel
from med_backend.auth.schemas import UserPublicInfo
class Question(BaseModel):
id: int
@ -40,6 +38,25 @@ class FormAssigment(BaseModel):
question_refs: List[QuestionRef]
class FormAnswer(BaseModel):
field_id: int
answer: str
class FullAnswer(BaseModel):
field_id: int
question: str
type: str
answer: str
ref_min: int | None
ref_max: int | None
class FullSubmission(BaseModel):
fio: str
answers: List[FullAnswer]
class BaseForm(BaseModel):
name: str
@ -57,7 +74,6 @@ class ListForm(BaseForm):
class Form(BaseForm):
id: int
user: UserPublicInfo
questions: List[Question]
class Config:

View File

@ -1,15 +1,18 @@
from typing import List
from fastapi import HTTPException
from pydantic import parse_obj_as
from sqlalchemy.ext.asyncio import AsyncSession
from med_backend.auth.schemas import UserPublicInfo
from med_backend.forms.crud import (
create_form_assigment,
create_submission,
create_submission_answer,
create_user_form_rev_question,
get_form,
get_questions,
get_submissions,
)
from med_backend.forms.schemas import Form, FormAssigment, Question
from med_backend.forms.schemas import Form, FormAnswer, FormAssigment, Question
async def get_full_form(session: AsyncSession, form_id: int) -> Form:
@ -21,7 +24,6 @@ async def get_full_form(session: AsyncSession, form_id: int) -> Form:
return Form(
id=form_id,
name=form.name,
user=parse_obj_as(UserPublicInfo, form.user),
questions=[
Question(id=q.id, type=q.type, question=q.question) for q in questions
],
@ -41,3 +43,22 @@ async def assign_form(session: AsyncSession, data: FormAssigment, form_id: int):
field.ref_min,
field.ref_max,
)
async def submit_form(
session: AsyncSession,
data: List[FormAnswer],
form_id: int,
user_id: int,
):
subm = await create_submission(session, form_id, user_id)
for answer in data:
await create_submission_answer(session, subm.id, answer.field_id, answer.answer)
async def get_form_submissions(session: AsyncSession, form_id: int):
form = await get_form(session, form_id)
if not form:
raise HTTPException(status_code=404, detail="Form doesn't exist")
submissions = await get_submissions(session, form_id)
return submissions

View File

@ -12,11 +12,13 @@ from med_backend.forms.schemas import (
BaseForm,
CreateFormField,
Form,
FormAnswer,
FormAssigment,
FormField,
FullSubmission,
ListForm,
)
from med_backend.forms.services import assign_form
from med_backend.forms.services import assign_form, submit_form
from med_backend.users.services import get_current_active_manager
router = APIRouter()
@ -34,7 +36,7 @@ async def get_all_forms(
@router.get("/list", response_model=list[ListForm])
async def get_all_forms(
async def get_all_user_forms(
skip: int = 0,
limit: int = 100,
current_user: User = Depends(get_current_active_user),
@ -65,13 +67,29 @@ async def get_form(
return form
@router.get("/{form_id}/answers", response_model=List[FullSubmission])
async def get_form(
form_id: int,
current_user: User = Depends(get_current_active_manager),
session: AsyncSession = Depends(get_db_session),
):
form = await crud.get_form(session, form_id)
if form.user.id != current_user.id:
raise HTTPException(
status_code=401,
detail="You are not allowed to access this form",
)
submissions = await services.get_form_submissions(session, form_id)
return submissions
@router.get("/{form_id}/fields", response_model=List[FormField])
async def create_form_field_view(
form_id: int,
current_user: User = Depends(get_current_active_manager),
session: AsyncSession = Depends(get_db_session),
):
form = await services.get_form(session, form_id)
form = await crud.get_form(session, form_id)
if form.user.id != current_user.id:
raise HTTPException(
status_code=401,
@ -107,3 +125,14 @@ async def create_assigment_view(
)
await assign_form(session, data, form_id)
return {"message": "created"}
@router.post("/{form_id}/submit")
async def submit_form_view(
form_id: int,
data: List[FormAnswer],
current_user: User = Depends(get_current_active_user),
session: AsyncSession = Depends(get_db_session),
):
await submit_form(session, data, form_id, current_user.id)
return {"message": "created"}