form integrated

pull/29/head
ahmed.mujtaba 2026-08-27 17:32:03 +05:00
parent fe80fa9fdc
commit ecd9b3597a
5 changed files with 19 additions and 17 deletions

View File

@ -173,20 +173,21 @@ async def fetch_form_data_sheets(
async def fetch_form_data(
sheet: str | None = Query(None),
search: str | None = Query(None),
top: int | None = Query(None),
skip: int = Query(0,ge=0),
offset: int = Query(0,ge=0),
limit: int | None = Query(None,ge=1),
current_user: dict = Depends(require_permission(PermissionTag.SETTINGS_VIEW)),
session: AsyncSession = Depends(get_session),
):
try:
service=SheetFormData(session=session)
items,total=await service.get_form_data(sheet=sheet,search=search,top=top,skip=skip)
items,total=await service.get_form_data(sheet=sheet,search=search,offset=offset,limit=limit)
return JSONResponse(content={"data":items,"total":total,"status_code":200})
except HTTPException:
raise
except Exception as e:
raise HTTPException(status_code=500,detail=str(e))
# @router.get
@router.get("/sheet/form-data/{record_id}")
async def fetch_form_data_by_id(

View File

@ -36,7 +36,7 @@ class FormDataField(str, Enum):
RESUME_LINK = "resume_link"
AREA_OF_EXPERTISE = "area_of_expertise"
REQUISITION_NUMBER = "requisition_number"
POSITION_SUITABLE_FOR = "position_suitable_for"
POSITION_APPLIED_FOR = "position_applied_for"
SOURCE_OF_APPLICATION = "source_of_application"
AGE = "age"
MARITAL_STATUS = "marital_status"
@ -99,7 +99,7 @@ HEADER_ALIASES: dict[FormDataField, tuple[str, ...]] = {
"area of expertise", "area of interest", "expertise",
),
FormDataField.REQUISITION_NUMBER: ("requisition number", "requisition", "req no"),
FormDataField.POSITION_SUITABLE_FOR: (
FormDataField.POSITION_APPLIED_FOR: (
"position suitable for", "position applied for", "position",
"designation", "job title", "role", "title",
),
@ -190,7 +190,7 @@ class FormDataColumn(str, Enum):
RESUME_LINK = "resume_link"
AREA_OF_EXPERTISE = "area_of_expertise"
REQUISITION_NUMBER = "requisition_number"
POSITION_SUITABLE_FOR = "position_suitable_for"
POSITION_APPLIED_FOR = "position_applied_for"
SOURCE_OF_APPLICATION = "source_of_application"
AGE = "age"
AGE_RAW = "age_raw"

View File

@ -50,7 +50,7 @@ class FormData(SQLModel, table=True):
resume_link: str | None = Field(default=None)
area_of_expertise: str | None = Field(default=None)
requisition_number: str | None = Field(default=None, index=True)
position_suitable_for: str | None = Field(default=None)
position_applied_for: str | None = Field(default=None)
source_of_application: str | None = Field(default=None)
age: int | None = Field(default=None)
age_raw: str | None = Field(default=None)
@ -102,7 +102,7 @@ class FormData(SQLModel, table=True):
cls.experience.ilike(pattern),
cls.experience_details.ilike(pattern),
cls.current_company.ilike(pattern),
cls.position_suitable_for.ilike(pattern),
cls.position_applied_for.ilike(pattern),
cls.area_of_expertise.ilike(pattern),
cls.source_of_application.ilike(pattern),
cls.cnic.ilike(pattern),
@ -120,14 +120,15 @@ class FormData(SQLModel, table=True):
return result.scalars().first()
@classmethod
async def fetch_form_data(cls, session: AsyncSession, *, sheet=None, search=None, top=None, skip=None):
async def fetch_form_data(cls, session: AsyncSession, *, sheet=None, search=None, offset=0, limit=None):
statement = select(cls).order_by(cls.sheet, cls.row_number)
for clause in cls._filters(sheet=sheet, search=search):
statement = statement.where(clause)
if skip:
statement = statement.offset(skip)
if top is not None:
statement = statement.limit(top)
if offset:
statement = statement.offset(offset)
if limit is not None:
statement = statement.limit(limit)
statement=statement.order_by(cls.row_number)
result = await session.execute(statement)
return result.scalars().all()
@ -236,7 +237,7 @@ class FormData(SQLModel, table=True):
"date_of_birth": parse_date(data.get("Date of Birth")),
"cnic": cls._cell(data, "National Identification No. (42000-XXXXXXX-X)"),
"marital_status": cls._cell(data, "Marital Status"),
"position_suitable_for": cls._cell(data, "Position Applied For"),
"position_applied_for": cls._cell(data, "Position Applied For"),
"profile_link": cls._cell(data, "LinkedIn Profile Link"),
"residing_country": cls._cell(data, "Residing Country"),
"residing_city": cls._cell(data, "Residing City"),

View File

@ -332,10 +332,10 @@ class SheetImport(SheetRead):
class SheetFormData(Sheet):
"""FormData DB mirror — query / delete only (no Google client)."""
async def get_form_data(self,sheet=None,search=None,top=None,skip=None):
async def get_form_data(self,sheet=None,search=None,offset=0,limit=None):
session=self._require_session()
rows=await FormData.fetch_form_data(
session,sheet=sheet,search=search,top=top,skip=skip,
session,sheet=sheet,search=search,offset=offset,limit=limit,
)
total=await FormData.count_form_data(session,sheet=sheet,search=search)
return [serialize_form_data(row) for row in rows],total

View File

@ -60,7 +60,7 @@ def test_from_sheet_row_maps_form_response_keys():
assert mapped["cgpa"] == "3.5"
assert mapped["degree"] == "Masters"
assert mapped["university"] == "Karachi University"
assert mapped["position_suitable_for"] == "Executive Secretary"
assert mapped["position_applied_for"] == "Executive Secretary"
assert mapped["notice_period"] == "1 - 2 weeks"
assert mapped["source_of_application"] == "Indeed"
assert mapped["ho_availability"] == "Yes"