Add role-based filtering and imporve code
This commit is contained in:
@@ -19,6 +19,7 @@ from app.models.suppliers import PurchaseOrderStatus
|
||||
from shared.auth.decorators import get_current_user_dep
|
||||
from shared.routing import RouteBuilder
|
||||
from shared.auth.access_control import require_user_role
|
||||
from shared.security import create_audit_logger, AuditSeverity, AuditAction
|
||||
|
||||
# Create route builder for consistent URL structure
|
||||
route_builder = RouteBuilder('suppliers')
|
||||
@@ -26,6 +27,7 @@ route_builder = RouteBuilder('suppliers')
|
||||
|
||||
router = APIRouter(tags=["purchase-orders"])
|
||||
logger = structlog.get_logger()
|
||||
audit_logger = create_audit_logger("suppliers-service")
|
||||
|
||||
|
||||
@router.post(route_builder.build_base_route("purchase-orders"), response_model=PurchaseOrderResponse)
|
||||
@@ -158,26 +160,26 @@ async def update_purchase_order(
|
||||
):
|
||||
"""Update purchase order information"""
|
||||
# require_permissions(current_user, ["purchase_orders:update"])
|
||||
|
||||
|
||||
try:
|
||||
service = PurchaseOrderService(db)
|
||||
|
||||
|
||||
# Check order exists and belongs to tenant
|
||||
existing_order = await service.get_purchase_order(po_id)
|
||||
if not existing_order:
|
||||
raise HTTPException(status_code=404, detail="Purchase order not found")
|
||||
if existing_order.tenant_id != current_user.tenant_id:
|
||||
raise HTTPException(status_code=403, detail="Access denied")
|
||||
|
||||
|
||||
purchase_order = await service.update_purchase_order(
|
||||
po_id=po_id,
|
||||
po_data=po_data,
|
||||
updated_by=current_user.user_id
|
||||
)
|
||||
|
||||
|
||||
if not purchase_order:
|
||||
raise HTTPException(status_code=404, detail="Purchase order not found")
|
||||
|
||||
|
||||
return PurchaseOrderResponse.from_orm(purchase_order)
|
||||
except HTTPException:
|
||||
raise
|
||||
@@ -188,3 +190,65 @@ async def update_purchase_order(
|
||||
raise HTTPException(status_code=500, detail="Failed to update purchase order")
|
||||
|
||||
|
||||
@router.delete(route_builder.build_resource_detail_route("purchase-orders", "po_id"))
|
||||
@require_user_role(['admin', 'owner'])
|
||||
async def delete_purchase_order(
|
||||
po_id: UUID = Path(..., description="Purchase order ID"),
|
||||
tenant_id: str = Path(..., description="Tenant ID"),
|
||||
current_user: Dict[str, Any] = Depends(get_current_user_dep),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""Delete purchase order (soft delete, Admin+ only)"""
|
||||
try:
|
||||
service = PurchaseOrderService(db)
|
||||
|
||||
# Check order exists and belongs to tenant
|
||||
existing_order = await service.get_purchase_order(po_id)
|
||||
if not existing_order:
|
||||
raise HTTPException(status_code=404, detail="Purchase order not found")
|
||||
if existing_order.tenant_id != current_user.tenant_id:
|
||||
raise HTTPException(status_code=403, detail="Access denied")
|
||||
|
||||
# Capture PO data before deletion
|
||||
po_data = {
|
||||
"po_number": existing_order.order_number,
|
||||
"supplier_id": str(existing_order.supplier_id),
|
||||
"status": existing_order.status.value if existing_order.status else None,
|
||||
"total_amount": float(existing_order.total_amount) if existing_order.total_amount else 0.0,
|
||||
"expected_delivery_date": existing_order.expected_delivery_date.isoformat() if existing_order.expected_delivery_date else None
|
||||
}
|
||||
|
||||
# Delete purchase order (likely soft delete in service)
|
||||
success = await service.delete_purchase_order(po_id)
|
||||
if not success:
|
||||
raise HTTPException(status_code=404, detail="Purchase order not found")
|
||||
|
||||
# Log audit event for purchase order deletion
|
||||
try:
|
||||
await audit_logger.log_deletion(
|
||||
db_session=db,
|
||||
tenant_id=tenant_id,
|
||||
user_id=current_user["user_id"],
|
||||
resource_type="purchase_order",
|
||||
resource_id=str(po_id),
|
||||
resource_data=po_data,
|
||||
description=f"Admin {current_user.get('email', 'unknown')} deleted purchase order {po_data['po_number']}",
|
||||
endpoint=f"/purchase-orders/{po_id}",
|
||||
method="DELETE"
|
||||
)
|
||||
except Exception as audit_error:
|
||||
logger.warning("Failed to log audit event", error=str(audit_error))
|
||||
|
||||
logger.info("Deleted purchase order",
|
||||
po_id=str(po_id),
|
||||
tenant_id=tenant_id,
|
||||
user_id=current_user["user_id"])
|
||||
|
||||
return {"message": "Purchase order deleted successfully"}
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error("Error deleting purchase order", po_id=str(po_id), error=str(e))
|
||||
raise HTTPException(status_code=500, detail="Failed to delete purchase order")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user