| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- import os
- import uuid
- from datetime import datetime
- from fastapi import FastAPI, UploadFile, File, Header, HTTPException, status, Form
- from fastapi.middleware.cors import CORSMiddleware
- from typing import Optional, List
- from backend.services.openai_service import extract_receipt_data
- from backend.schemas import ExtractionResponse, ClaimRecord, UserAccount, ClaimSubmission
- from dotenv import load_dotenv
- load_dotenv()
- app = FastAPI(title="AI-Assisted Data Entry API")
- # Configure CORS
- app.add_middleware(
- CORSMiddleware,
- allow_origins=["*"], # Adjust as needed for Angular frontend
- allow_credentials=True,
- allow_methods=["*"],
- allow_headers=["*"],
- )
- # In-memory database
- CLAIMS_DB: List[ClaimRecord] = []
- USERS_DB: List[UserAccount] = [
- UserAccount(
- id="demo-user-123",
- name="Demo User",
- department="Operations",
- medical_allowance=5000.0
- )
- ]
- @app.get("/health")
- async def health_check():
- return {"status": "healthy"}
- @app.get("/api/v1/users", response_model=List[UserAccount])
- async def get_users():
- return USERS_DB
- @app.post("/api/v1/users", response_model=UserAccount)
- async def create_user(user: UserAccount):
- USERS_DB.append(user)
- return user
- @app.post("/api/v1/extract", response_model=ExtractionResponse)
- async def extract_receipt(
- file: UploadFile = File(...),
- user_name: str = Form("Demo User"),
- department: str = Form("Operations")
- ):
- if not file.content_type.startswith("image/"):
- raise HTTPException(
- status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
- detail="File provided is not an image."
- )
-
- try:
- content = await file.read()
- extraction_result = await extract_receipt_data(content, user_name, department)
-
- if extraction_result is None:
- raise HTTPException(
- status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
- detail="Could not extract data from the provided image."
- )
-
- return extraction_result
- except Exception as e:
- raise HTTPException(
- status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
- detail=f"An error occurred during extraction: {str(e)}"
- )
- @app.post("/api/v1/claims", response_model=ClaimRecord)
- async def submit_claim(
- submission_data: ClaimSubmission,
- user_id: str = Header(...)
- ):
- # 1. Find User
- user = next((u for u in USERS_DB if u.id == user_id), None)
- if not user:
- raise HTTPException(status_code=404, detail="User not found")
- # 2. Financial Guard Logic
- spent_amount = submission_data.amount_spent
- remaining = user.medical_allowance
- amount_claimed = min(spent_amount, remaining)
- # 3. Update User Balance
- user.medical_allowance -= amount_claimed
- # 4. Save Claim
- claim = ClaimRecord(
- id=str(uuid.uuid4()),
- timestamp=datetime.now().isoformat(),
- submitted_by=user.name,
- department=user.department,
- amount_spent=spent_amount,
- amount_claimed=amount_claimed,
- provider_name=submission_data.provider_name,
- visit_date=submission_data.visit_date,
- treatment_type=submission_data.treatment_type,
- cost_center=submission_data.cost_center,
- declaration_signed=submission_data.declaration_signed,
- extraction_data=submission_data.extraction_data
- )
- CLAIMS_DB.append(claim)
- return claim
- @app.delete("/api/v1/claims/{claim_id}")
- async def delete_claim(claim_id: str):
- global CLAIMS_DB, USERS_DB
-
- # 1. Find the claim
- claim_index = next((i for i, c in enumerate(CLAIMS_DB) if c.id == claim_id), -1)
- if claim_index == -1:
- raise HTTPException(status_code=404, detail="Claim not found")
-
- deleted_claim = CLAIMS_DB[claim_index]
-
- # 2. Refund the user's allowance if user exists
- user = next((u for u in USERS_DB if u.name == deleted_claim.submitted_by), None)
- if user:
- user.medical_allowance += deleted_claim.amount_claimed
-
- # 3. Remove from list
- CLAIMS_DB.pop(claim_index)
-
- return {"status": "success", "message": "Claim deleted and allowance refunded"}
- @app.get("/api/v1/claims", response_model=List[ClaimRecord])
- async def get_claims():
- return CLAIMS_DB
- if __name__ == "__main__":
- import uvicorn
- uvicorn.run(app, host="0.0.0.0", port=8000)
|