bmc_hub/app/modules/also/backend/router.py
Christian a604a3cc44 Add comprehensive test suite for vTiger integration and ticket module
- Implemented test scripts for vTiger account retrieval, contact data, and modules.
- Created a detailed test suite for the ticket module, covering database schema validation, ticket number generation, prepaid card constraints, and service logic.
- Added tests for vTiger field inspection and various queries related to accounts and sales orders.
- Introduced SQL migration scripts for the ALSO Cloud Billing foundation, including import jobs, lines, and mapping tables with necessary constraints and indices.
- Enhanced workflow columns in the import lines table to support matching and validation timestamps.
2026-06-20 03:29:51 +02:00

115 lines
3.6 KiB
Python

from typing import Optional
from fastapi import APIRouter, Query, Request
from app.modules.also.backend.service import also_service
from app.modules.also.models.schemas import (
AlsoApproveResult,
AlsoCompanyMappingUpsert,
AlsoDifferenceItem,
AlsoDashboardSummaryResponse,
AlsoImportJobCreate,
AlsoImportJobResponse,
AlsoImportLinesRequest,
AlsoProductMappingUpsert,
AlsoQueueApproveRequest,
AlsoQueueLineResponse,
AlsoQueueProcessRequest,
AlsoQueueProcessResult,
)
router = APIRouter()
def _user_id_from_request(request: Request) -> Optional[int]:
raw_user_id = getattr(request.state, "user_id", None)
if raw_user_id is None:
return None
try:
return int(raw_user_id)
except (TypeError, ValueError):
return None
@router.get("/also/config")
async def also_config() -> dict:
return also_service.get_config()
@router.post("/also/import-jobs", response_model=AlsoImportJobResponse)
async def create_import_job(payload: AlsoImportJobCreate, request: Request):
return also_service.create_import_job(payload, _user_id_from_request(request))
@router.get("/also/import-jobs", response_model=list[AlsoImportJobResponse])
async def list_import_jobs(
status: Optional[str] = Query(default=None),
limit: int = Query(default=100, ge=1, le=500),
):
return also_service.list_import_jobs(status=status, limit=limit)
@router.get("/also/import-jobs/{job_id}", response_model=AlsoImportJobResponse)
async def get_import_job(job_id: int):
return also_service.get_import_job(job_id)
@router.post("/also/import-jobs/{job_id}/lines")
async def import_lines(job_id: int, payload: AlsoImportLinesRequest):
return also_service.import_lines(job_id=job_id, payload=payload)
@router.get("/also/queue", response_model=list[AlsoQueueLineResponse])
async def get_queue(
status: Optional[str] = Query(default=None),
limit: int = Query(default=200, ge=1, le=1000),
):
return also_service.get_queue(status=status, limit=limit)
@router.get("/also/dashboard/summary", response_model=AlsoDashboardSummaryResponse)
async def get_dashboard_summary():
return also_service.get_dashboard_summary()
@router.get("/also/dashboard/differences", response_model=list[AlsoDifferenceItem])
async def get_dashboard_differences(limit: int = Query(default=50, ge=1, le=200)):
return also_service.get_monthly_differences(limit=limit)
@router.post("/also/queue/run-matching", response_model=AlsoQueueProcessResult)
async def run_matching(payload: AlsoQueueProcessRequest):
return also_service.run_matching(
import_job_id=payload.import_job_id,
line_ids=payload.line_ids,
limit=payload.limit,
)
@router.post("/also/queue/run-validation", response_model=AlsoQueueProcessResult)
async def run_validation(payload: AlsoQueueProcessRequest):
return also_service.run_validation(
import_job_id=payload.import_job_id,
line_ids=payload.line_ids,
limit=payload.limit,
)
@router.post("/also/queue/approve", response_model=AlsoApproveResult)
async def approve_queue(payload: AlsoQueueApproveRequest, request: Request):
return also_service.approve_lines_to_drafts(
import_job_id=payload.import_job_id,
line_ids=payload.line_ids,
approved_by_user_id=_user_id_from_request(request),
)
@router.put("/also/mappings/company")
async def upsert_company_mapping(payload: AlsoCompanyMappingUpsert):
return also_service.upsert_company_mapping(payload)
@router.put("/also/mappings/product")
async def upsert_product_mapping(payload: AlsoProductMappingUpsert):
return also_service.upsert_product_mapping(payload)