Enhancements
This commit is contained in:
+116
-15
@@ -1,12 +1,16 @@
|
||||
from fastapi import FastAPI, HTTPException, Depends, WebSocket
|
||||
from fastapi.security import OAuth2PasswordBearer
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from pydantic import BaseModel
|
||||
from typing import List, Annotated, Optional
|
||||
from pydantic import BaseModel, ConfigDict, Field, model_validator
|
||||
from typing import List, Annotated, Optional, Union
|
||||
from sustApp.models.models import Base, Members, Payments
|
||||
from sustApp.models.database import engine, SessionLocal
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy import func
|
||||
from datetime import datetime
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
# from create_payment_report import create_payment_report
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
@@ -31,6 +35,7 @@ origins = [
|
||||
"http://localhost:8080",
|
||||
"http://localhost:3000",
|
||||
"http://localhost:5173",
|
||||
"http://localhost:5174",
|
||||
]
|
||||
|
||||
app.add_middleware(
|
||||
@@ -91,10 +96,12 @@ class User(BaseModel):
|
||||
|
||||
class DeliveryBase(BaseModel):
|
||||
delivery_date: datetime
|
||||
delivered_by: int
|
||||
delivered_by_id: int | None = None
|
||||
|
||||
|
||||
class PaymentBase(BaseModel):
|
||||
payment_date: datetime
|
||||
payment_date: datetime | None = None
|
||||
payment_year: datetime | None = None
|
||||
|
||||
class MemberBase(BaseModel):
|
||||
member_count: int
|
||||
@@ -105,19 +112,31 @@ class MemberBase(BaseModel):
|
||||
member_street: str
|
||||
member_streetnumber: str | None = None
|
||||
member_email: str | None = None
|
||||
member_zip: int
|
||||
member_zip: int | None = Field(default=None, description="Member ZIP code")
|
||||
#member_zip: Optional[int] = Field(default=None, description="Member ZIP code")
|
||||
member_printed: bool | None = None
|
||||
member_city: str
|
||||
member_active: bool
|
||||
member_active: bool | None = None
|
||||
member_gender: str | None = None
|
||||
member_connected: int | None = None
|
||||
member_printed: bool
|
||||
#member_coordinates:
|
||||
#payments: Optional[List[PaymentBase]]
|
||||
member_deliveries: Optional[List[DeliveryBase]]
|
||||
#deliveries: Mapped[List["DeliveryBase"]] = relationship()
|
||||
member_deliveries: Optional[List[DeliveryBase]] = []
|
||||
member_payments: Optional[List[PaymentBase]] = []
|
||||
current_state_code: str | None = None
|
||||
current_state_name: str | None = None
|
||||
|
||||
@model_validator(mode='before')
|
||||
@classmethod
|
||||
def handle_empty_strings(cls, data):
|
||||
"""Convert empty strings to None for int fields"""
|
||||
if isinstance(data, dict):
|
||||
if data.get('member_zip') == '':
|
||||
data['member_zip'] = None
|
||||
return data
|
||||
|
||||
model_config = ConfigDict(from_attributes=True) # Enables SQLAlchemy object conversion
|
||||
|
||||
def get_db():
|
||||
db = SessionLocal()
|
||||
try:
|
||||
@@ -128,17 +147,84 @@ def get_db():
|
||||
db_dependency = Annotated[Session, Depends(get_db)]
|
||||
|
||||
@app.get("/members/", response_model=List[MemberBase])
|
||||
async def read_members(db: db_dependency, skip: int = 0, limit: int = 100):
|
||||
members = db.query(Members).offset(skip).limit(limit).all()
|
||||
if not members:
|
||||
raise HTTPException(status_code=404, detail='No members found')
|
||||
|
||||
return [
|
||||
{
|
||||
"id": m.id,
|
||||
"member_firstname": m.member_firstname,
|
||||
"member_surname": m.member_surname,
|
||||
"member_count": m.member_count,
|
||||
"member_street": m.member_street,
|
||||
"member_zip": m.member_zip,
|
||||
"member_city": m.member_city,
|
||||
"member_active": m.member_active,
|
||||
"member_printed": m.member_printed,
|
||||
"member_deliveries": [
|
||||
{
|
||||
"id": d.id,
|
||||
"delivery_date": d.delivery_date, # Correct field
|
||||
"delivered_by_id": d.delivered_by_id,
|
||||
# Add any other required delivery fields here
|
||||
}
|
||||
for d in m.member_deliveries
|
||||
] if m.member_deliveries else [],
|
||||
"member_payments": [
|
||||
{
|
||||
"id": p.id,
|
||||
"payment_date": p.payment_date,
|
||||
"payment_year": p.payment_year,
|
||||
# Add any other required delivery fields here
|
||||
}
|
||||
for p in m.member_payments
|
||||
] if m.member_payments else []
|
||||
}
|
||||
for m in members
|
||||
]
|
||||
|
||||
""" @app.get("/members/", response_model=List[MemberBase])
|
||||
async def read_members(db: db_dependency, skip: int = 0, limit: int = 100):
|
||||
members = db.query(Members).offset(skip).limit(limit).all()
|
||||
if not members:
|
||||
raise HTTPException(status_code=404, detail='No members found') # Use 404 for not found
|
||||
|
||||
# DEBUG: Print first member attributes
|
||||
if members:
|
||||
print("First member:", vars(members[0]))
|
||||
print("First member type:", type(members[0]))
|
||||
|
||||
# TEMP: Return dicts to bypass Pydantic entirely
|
||||
#return [{"id": m.id, "name": getattr(m, 'name', None)} for m in members] #
|
||||
|
||||
# Safe conversion - handles any SQLAlchemy objects
|
||||
return jsonable_encoder(members)
|
||||
|
||||
# return members # Now works with ORM mode enabled """
|
||||
|
||||
""" @app.get("/members/", response_model=List[MemberBase])
|
||||
async def read_members(db: db_dependency, skip: int = 0, limit: int = 100 ):
|
||||
members = db.query(Members).offset(skip).limit(limit).all()
|
||||
if not members:
|
||||
raise HTTPException(status_code=400, detail='No members')
|
||||
return members
|
||||
return members """
|
||||
|
||||
@app.get("/activememberscount/", response_model=int)
|
||||
async def read_activememberscount(db: db_dependency):
|
||||
count = db.query(Members).filter(Members.member_active == True).count()
|
||||
logger.info("This is a test log message from backend!")
|
||||
return count
|
||||
count = db.query(func.sum(Members.member_count)).filter(Members.current_state_code == 'A', Members.member_primary == True).scalar()
|
||||
return count or 0
|
||||
|
||||
@app.get("/inactivememberscount/", response_model=int)
|
||||
async def read_inactivememberscount(db: db_dependency):
|
||||
count = db.query(func.sum(Members.member_count)).filter(Members.current_state_code == 'I', Members.member_primary == True).scalar()
|
||||
return count or 0
|
||||
|
||||
@app.get("/deactivatedmemberscount/", response_model=int)
|
||||
async def read_deactivatedmemberscount(db: db_dependency):
|
||||
count = db.query(func.sum(Members.member_count)).filter(Members.current_state_code == 'D', Members.member_primary == True).scalar()
|
||||
return count or 0
|
||||
|
||||
@app.get("/member/{member_id}")
|
||||
async def read_member(member_id: int, db: db_dependency): #, token: Annotated[str, Depends(oauth2_scheme)]):
|
||||
@@ -151,9 +237,16 @@ async def read_member(member_id: int, db: db_dependency): #, token: Annotated[st
|
||||
|
||||
return result
|
||||
|
||||
@app.get("/payments/")
|
||||
async def read_all_payments(db: db_dependency):
|
||||
result = db.query(Payments).all()
|
||||
if not result:
|
||||
raise HTTPException(status_code=400, detail=f'No payments found')
|
||||
return result
|
||||
|
||||
@app.get("/payments/{member_id}")
|
||||
async def read_payments(member_id: int, db: db_dependency):
|
||||
result = db.query(Members).filter(Members.id == member_id).all()
|
||||
result = db.query(Payments).filter(Payments.member_id == member_id).all()
|
||||
if not result:
|
||||
raise HTTPException(status_code=400, detail=f'No payments found for member {member_id}')
|
||||
return result
|
||||
@@ -191,4 +284,12 @@ async def create_members(members: List[MemberBase], db: db_dependency):
|
||||
db_payment = Payments(payment_date=payment.payment_date,
|
||||
member_id=db_member.id)
|
||||
db.add(db_payment)
|
||||
db.commit()
|
||||
db.commit()
|
||||
|
||||
# @app.get("/api/reports/payments")
|
||||
# async def get_payment_report():
|
||||
# try:
|
||||
# report_path = create_payment_report()
|
||||
# return {"message": "Report generated", "path": report_path}
|
||||
# except Exception as e:
|
||||
# raise HTTPException(status_code=500, detail=str(e))
|
||||
Reference in New Issue
Block a user