feat(repairs): add repair documents
This commit is contained in:
parent
884a20e043
commit
6e7e75f864
21 changed files with 1222 additions and 6 deletions
|
|
@ -70,6 +70,7 @@ def get_dashboard_summary(
|
|||
MetricCard(label="Statusmails heute", value=RepairRepository.count_status_mails_sent_today(db)),
|
||||
MetricCard(label="Fehlgeschlagene Mails", value=RepairRepository.count_failed_status_mails(db)),
|
||||
MetricCard(label="Offen ohne Kundenmail", value=RepairRepository.count_open_repairs_without_customer_email(db)),
|
||||
MetricCard(label="Reparaturdokumente", value=RepairRepository.count_documents(db)),
|
||||
]
|
||||
|
||||
if "system_settings.manage" in permissions:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from fastapi import APIRouter, Depends, Header, HTTPException, Query, status
|
||||
from fastapi import APIRouter, Depends, File, Form, Header, HTTPException, Query, UploadFile, status
|
||||
from fastapi.responses import FileResponse
|
||||
from sqlalchemy.orm import Session
|
||||
from starlette.requests import Request
|
||||
from typing import cast
|
||||
|
|
@ -11,6 +12,10 @@ from app.models.user import User
|
|||
from app.repositories.repair_repository import RepairRepository
|
||||
from app.schemas.repair import (
|
||||
RepairCreate,
|
||||
RepairDocumentResponse,
|
||||
RepairDocumentType,
|
||||
RepairDocumentUpdate,
|
||||
RepairDocumentVisibility,
|
||||
RepairIntakePayload,
|
||||
RepairIntakeResponse,
|
||||
RepairNotificationEventResponse,
|
||||
|
|
@ -26,6 +31,7 @@ from app.schemas.repair import (
|
|||
RepairUpdate,
|
||||
)
|
||||
from app.services.repair_notification_service import RepairNotificationService
|
||||
from app.services.repair_document_service import RepairDocumentService
|
||||
from app.services.repair_public_link_service import RepairPublicLinkService
|
||||
from app.services.repair_service import RepairService
|
||||
|
||||
|
|
@ -130,6 +136,117 @@ def get_repair_history(
|
|||
return RepairRepository.get_history(db, repair_id)
|
||||
|
||||
|
||||
@router.get("/repairs/{repair_id}/documents", response_model=list[RepairDocumentResponse])
|
||||
def list_repair_documents(
|
||||
repair_id: int,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(require_permission("repairs.read")),
|
||||
):
|
||||
get_repair_or_404(db, repair_id)
|
||||
return RepairRepository.list_documents(db, repair_id)
|
||||
|
||||
|
||||
@router.post("/repairs/{repair_id}/documents/upload", response_model=RepairDocumentResponse, status_code=status.HTTP_201_CREATED)
|
||||
async def upload_repair_document(
|
||||
repair_id: int,
|
||||
request: Request,
|
||||
file: UploadFile = File(...),
|
||||
title: str = Form(..., min_length=1, max_length=255),
|
||||
document_type: RepairDocumentType = Form("other"),
|
||||
visibility: RepairDocumentVisibility = Form("internal"),
|
||||
note: str | None = Form(None),
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(require_permission("repairs.update")),
|
||||
):
|
||||
db_repair = get_repair_or_404(db, repair_id)
|
||||
normalized_title = title.strip()
|
||||
normalized_note = note.strip() if note else None
|
||||
if not normalized_title:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Titel ist erforderlich")
|
||||
return await RepairDocumentService.upload_document(
|
||||
db,
|
||||
db_repair,
|
||||
file=file,
|
||||
title=normalized_title,
|
||||
document_type=document_type,
|
||||
visibility=visibility,
|
||||
note=normalized_note,
|
||||
actor=current_user,
|
||||
request=request,
|
||||
)
|
||||
|
||||
|
||||
@router.get("/repairs/{repair_id}/documents/{document_id}", response_model=RepairDocumentResponse)
|
||||
def get_repair_document(
|
||||
repair_id: int,
|
||||
document_id: int,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(require_permission("repairs.read")),
|
||||
):
|
||||
get_repair_or_404(db, repair_id)
|
||||
document = RepairRepository.get_document(db, repair_id=repair_id, document_id=document_id)
|
||||
if document is None:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Dokument nicht gefunden")
|
||||
return document
|
||||
|
||||
|
||||
@router.put("/repairs/{repair_id}/documents/{document_id}", response_model=RepairDocumentResponse)
|
||||
def update_repair_document(
|
||||
repair_id: int,
|
||||
document_id: int,
|
||||
payload: RepairDocumentUpdate,
|
||||
request: Request,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(require_permission("repairs.update")),
|
||||
):
|
||||
db_repair = get_repair_or_404(db, repair_id)
|
||||
document = RepairRepository.get_document(db, repair_id=repair_id, document_id=document_id)
|
||||
if document is None:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Dokument nicht gefunden")
|
||||
return RepairDocumentService.update_document(db, db_repair, document, payload, actor=current_user, request=request)
|
||||
|
||||
|
||||
@router.get("/repairs/{repair_id}/documents/{document_id}/download")
|
||||
def download_repair_document(
|
||||
repair_id: int,
|
||||
document_id: int,
|
||||
disposition: str = Query(default="inline", pattern="^(inline|attachment)$"),
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(require_permission("repairs.read")),
|
||||
):
|
||||
get_repair_or_404(db, repair_id)
|
||||
document = RepairRepository.get_document(db, repair_id=repair_id, document_id=document_id)
|
||||
if document is None:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Dokument nicht gefunden")
|
||||
file_path = RepairDocumentService.open_document_file(document)
|
||||
return FileResponse(
|
||||
file_path,
|
||||
media_type=document.mime_type or "application/octet-stream",
|
||||
headers={
|
||||
"Content-Disposition": RepairDocumentService.content_disposition(
|
||||
document,
|
||||
mode="attachment" if disposition == "attachment" else "inline",
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@router.delete("/repairs/{repair_id}/documents/{document_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
def delete_repair_document(
|
||||
repair_id: int,
|
||||
document_id: int,
|
||||
request: Request,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(require_permission("repairs.update")),
|
||||
):
|
||||
db_repair = get_repair_or_404(db, repair_id)
|
||||
document = RepairRepository.get_document(db, repair_id=repair_id, document_id=document_id)
|
||||
if document is None:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Dokument nicht gefunden")
|
||||
RepairDocumentService.delete_document(db, db_repair, document, actor=current_user, request=request)
|
||||
return None
|
||||
|
||||
|
||||
@router.get("/repairs/{repair_id}/public-link", response_model=RepairPublicLinkResponse)
|
||||
def get_public_link(
|
||||
repair_id: int,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue