working on backend
This commit is contained in:
@@ -90,14 +90,14 @@ class UserResponse(BaseModel):
|
||||
id: int
|
||||
username: str
|
||||
email: str
|
||||
first_name: Optional[str]
|
||||
last_name: Optional[str]
|
||||
is_admin: bool
|
||||
is_active: bool
|
||||
is_approver: bool
|
||||
last_login: Optional[datetime]
|
||||
created_at: Optional[datetime]
|
||||
updated_at: Optional[datetime]
|
||||
first_name: Optional[str] = None
|
||||
last_name: Optional[str] = None
|
||||
is_admin: bool = False
|
||||
is_active: bool = True
|
||||
is_approver: bool = False
|
||||
last_login: Optional[datetime] = None
|
||||
created_at: Optional[datetime] = None
|
||||
updated_at: Optional[datetime] = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
1607
app/api/billing.py
Normal file
1607
app/api/billing.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -18,6 +18,32 @@ def ensure_schema_updates(engine: Engine) -> None:
|
||||
"""Ensure missing columns are added for backward-compatible updates."""
|
||||
# Map of table -> {column: SQL type}
|
||||
updates: Dict[str, Dict[str, str]] = {
|
||||
# Billing batch history (lightweight persistence)
|
||||
"billing_batches": {
|
||||
"id": "INTEGER",
|
||||
"batch_id": "TEXT",
|
||||
"status": "TEXT",
|
||||
"total_files": "INTEGER",
|
||||
"successful_files": "INTEGER",
|
||||
"failed_files": "INTEGER",
|
||||
"started_at": "DATETIME",
|
||||
"updated_at": "DATETIME",
|
||||
"completed_at": "DATETIME",
|
||||
"processing_time_seconds": "FLOAT",
|
||||
"success_rate": "FLOAT",
|
||||
"error_message": "TEXT",
|
||||
},
|
||||
"billing_batch_files": {
|
||||
"id": "INTEGER",
|
||||
"batch_id": "TEXT",
|
||||
"file_no": "TEXT",
|
||||
"status": "TEXT",
|
||||
"error_message": "TEXT",
|
||||
"filename": "TEXT",
|
||||
"size": "INTEGER",
|
||||
"started_at": "DATETIME",
|
||||
"completed_at": "DATETIME",
|
||||
},
|
||||
# Forms
|
||||
"form_index": {
|
||||
"keyword": "TEXT",
|
||||
|
||||
@@ -83,6 +83,7 @@ from app.api.customers import router as customers_router
|
||||
from app.api.files import router as files_router
|
||||
from app.api.financial import router as financial_router
|
||||
from app.api.documents import router as documents_router
|
||||
from app.api.billing import router as billing_router
|
||||
from app.api.search import router as search_router
|
||||
from app.api.admin import router as admin_router
|
||||
from app.api.import_data import router as import_router
|
||||
@@ -99,6 +100,7 @@ app.include_router(auth_router, prefix="/api/auth", tags=["authentication"])
|
||||
app.include_router(customers_router, prefix="/api/customers", tags=["customers"])
|
||||
app.include_router(files_router, prefix="/api/files", tags=["files"])
|
||||
app.include_router(financial_router, prefix="/api/financial", tags=["financial"])
|
||||
app.include_router(billing_router, prefix="/api/billing", tags=["billing"])
|
||||
app.include_router(documents_router, prefix="/api/documents", tags=["documents"])
|
||||
app.include_router(search_router, prefix="/api/search", tags=["search"])
|
||||
app.include_router(admin_router, prefix="/api/admin", tags=["admin"])
|
||||
@@ -157,6 +159,13 @@ async def financial_page(request: Request):
|
||||
"financial.html",
|
||||
{"request": request, "title": "Financial/Ledger - " + settings.app_name}
|
||||
)
|
||||
@app.get("/billing", response_class=HTMLResponse)
|
||||
async def billing_page(request: Request):
|
||||
"""Billing Statements page"""
|
||||
return templates.TemplateResponse(
|
||||
"billing.html",
|
||||
{"request": request, "title": "Billing Statements - " + settings.app_name}
|
||||
)
|
||||
|
||||
|
||||
@app.get("/documents", response_class=HTMLResponse)
|
||||
|
||||
@@ -17,6 +17,7 @@ from .pensions import (
|
||||
SeparationAgreement, LifeTable, NumberTable, PensionResult
|
||||
)
|
||||
from .templates import DocumentTemplate, DocumentTemplateVersion, TemplateKeyword
|
||||
from .billing import BillingBatch, BillingBatchFile
|
||||
from .lookups import (
|
||||
Employee, FileType, FileStatus, TransactionType, TransactionCode,
|
||||
State, GroupLookup, Footer, PlanInfo, FormIndex, FormList,
|
||||
@@ -32,5 +33,6 @@ __all__ = [
|
||||
"SeparationAgreement", "LifeTable", "NumberTable", "PensionResult",
|
||||
"Employee", "FileType", "FileStatus", "TransactionType", "TransactionCode",
|
||||
"State", "GroupLookup", "Footer", "PlanInfo", "FormIndex", "FormList",
|
||||
"PrinterSetup", "SystemSetup", "FormKeyword", "TemplateKeyword"
|
||||
"PrinterSetup", "SystemSetup", "FormKeyword", "TemplateKeyword",
|
||||
"BillingBatch", "BillingBatchFile"
|
||||
]
|
||||
47
app/models/billing.py
Normal file
47
app/models/billing.py
Normal file
@@ -0,0 +1,47 @@
|
||||
from sqlalchemy import Column, Integer, String, DateTime, Float, Text, Index
|
||||
from app.models.base import BaseModel
|
||||
|
||||
|
||||
class BillingBatch(BaseModel):
|
||||
__tablename__ = "billing_batches"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
batch_id = Column(String(100), unique=True, nullable=False, index=True)
|
||||
status = Column(String(32), nullable=False)
|
||||
total_files = Column(Integer, nullable=False, default=0)
|
||||
successful_files = Column(Integer, nullable=False, default=0)
|
||||
failed_files = Column(Integer, nullable=False, default=0)
|
||||
started_at = Column(DateTime(timezone=True), nullable=False)
|
||||
updated_at = Column(DateTime(timezone=True))
|
||||
completed_at = Column(DateTime(timezone=True))
|
||||
processing_time_seconds = Column(Float)
|
||||
success_rate = Column(Float)
|
||||
error_message = Column(Text)
|
||||
|
||||
__table_args__ = (
|
||||
Index("ix_billing_batches_started_at", "started_at"),
|
||||
Index("ix_billing_batches_updated_at", "updated_at"),
|
||||
Index("ix_billing_batches_completed_at", "completed_at"),
|
||||
{},
|
||||
)
|
||||
|
||||
|
||||
class BillingBatchFile(BaseModel):
|
||||
__tablename__ = "billing_batch_files"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
batch_id = Column(String(100), nullable=False, index=True)
|
||||
file_no = Column(String(50), nullable=False, index=True)
|
||||
status = Column(String(32), nullable=False)
|
||||
error_message = Column(Text)
|
||||
filename = Column(String(255))
|
||||
size = Column(Integer)
|
||||
started_at = Column(DateTime(timezone=True))
|
||||
completed_at = Column(DateTime(timezone=True))
|
||||
|
||||
__table_args__ = (
|
||||
Index("ix_billing_batch_files_batch_file", "batch_id", "file_no"),
|
||||
{},
|
||||
)
|
||||
|
||||
|
||||
@@ -22,9 +22,9 @@ class User(BaseModel):
|
||||
full_name = Column(String(100)) # Keep for backward compatibility
|
||||
|
||||
# Authorization
|
||||
is_active = Column(Boolean, default=True)
|
||||
is_admin = Column(Boolean, default=False)
|
||||
is_approver = Column(Boolean, default=False)
|
||||
is_active = Column(Boolean, default=True, nullable=False)
|
||||
is_admin = Column(Boolean, default=False, nullable=False)
|
||||
is_approver = Column(Boolean, default=False, nullable=False)
|
||||
|
||||
# User Preferences
|
||||
theme_preference = Column(String(10), default='light') # 'light', 'dark'
|
||||
|
||||
Reference in New Issue
Block a user