Files
cmroubao/backend-api/internal/transport/httpapi/procurement_handlers.go
T

170 lines
4.2 KiB
Go

package httpapi
import (
"net/http"
"cmroubao/backend-api/internal/domain"
"cmroubao/backend-api/internal/usecase"
"github.com/gin-gonic/gin"
)
func (h *adminHandlers) createProcurementRequest(ctx *gin.Context) {
if !hasMediaType(ctx, "application/json") {
writePublicError(
ctx,
http.StatusUnsupportedMediaType,
"UNSUPPORTED_MEDIA_TYPE",
"application/json is required",
false,
gin.H{},
)
return
}
var request struct {
ConfirmProcurementNeeded bool `json:"confirm_procurement_needed"`
}
if err := decodeJSON(ctx, &request); err != nil {
writePublicError(
ctx,
http.StatusBadRequest,
"INVALID_JSON",
"request body must be valid JSON",
false,
gin.H{},
)
return
}
result, err := h.services.Procurement.CreateRequest(
ctx.Request.Context(),
usecase.CreateProcurementRequestCommand{
CreatorSubject: localAdminSubject,
ActorUserID: adminActorUserID(ctx),
FreightOrderItemID: ctx.Param("id"),
ConfirmProcurementNeeded: request.ConfirmProcurementNeeded,
},
)
if err != nil {
writeUsecaseError(ctx, err)
return
}
ctx.Header("Cache-Control", "no-store")
ctx.JSON(http.StatusCreated, gin.H{
"procurement_request": procurementRequestResponse(result.Request),
"replayed": result.Replayed,
})
}
func (h *adminHandlers) bindProcurementReference(ctx *gin.Context) {
if !hasMediaType(ctx, "application/json") {
writePublicError(
ctx,
http.StatusUnsupportedMediaType,
"UNSUPPORTED_MEDIA_TYPE",
"application/json is required",
false,
gin.H{},
)
return
}
var request struct {
ImageAssetID string `json:"image_asset_id"`
}
if err := decodeJSON(ctx, &request); err != nil {
writePublicError(
ctx,
http.StatusBadRequest,
"INVALID_JSON",
"request body must be valid JSON",
false,
gin.H{},
)
return
}
result, err := h.services.Procurement.BindReference(
ctx.Request.Context(),
usecase.BindProcurementReferenceCommand{
CreatorSubject: localAdminSubject,
ActorUserID: adminActorUserID(ctx),
RequestID: ctx.Param("id"),
ImageAssetID: request.ImageAssetID,
},
)
if err != nil {
writeUsecaseError(ctx, err)
return
}
ctx.Header("Cache-Control", "no-store")
ctx.JSON(http.StatusOK, gin.H{
"procurement_request": procurementRequestResponse(result),
})
}
func (h *adminHandlers) createProcurementTask(ctx *gin.Context) {
if !hasMediaType(ctx, "application/json") {
writePublicError(
ctx,
http.StatusUnsupportedMediaType,
"UNSUPPORTED_MEDIA_TYPE",
"application/json is required",
false,
gin.H{},
)
return
}
var request struct{}
if err := decodeJSON(ctx, &request); err != nil {
writePublicError(
ctx,
http.StatusBadRequest,
"INVALID_JSON",
"request body must be an empty JSON object",
false,
gin.H{},
)
return
}
result, err := h.services.Procurement.CreateTask(
ctx.Request.Context(),
usecase.CreateProcurementTaskCommand{
CreatorSubject: localAdminSubject,
ActorUserID: adminActorUserID(ctx),
RequestID: ctx.Param("id"),
IdempotencyKey: ctx.GetHeader("Idempotency-Key"),
},
)
if err != nil {
writeUsecaseError(ctx, err)
return
}
ctx.Header("Cache-Control", "no-store")
ctx.JSON(http.StatusCreated, gin.H{
"task": taskSummaryResponse(result.Task),
"replayed": result.Replayed,
})
}
func procurementRequestResponse(
request domain.ProcurementRequest,
) gin.H {
return gin.H{
"id": request.ID,
"freight_order_item_id": request.FreightOrderItemID,
"source_revision": request.SourceRevision,
"source_sha256": request.SourceSHA256,
"title": request.Title,
"product_spec": request.ProductSpec,
"sku": request.SKU,
"quantity": request.Quantity,
"source_purchase_status": request.SourcePurchaseStatus,
"status": request.Status,
"blocking_code": request.BlockingCode,
"reference_asset_id": request.ReferenceAssetID,
"reference_origin": request.ReferenceOrigin,
"purchase_task_id": request.PurchaseTaskID,
"source_changed": request.SourceChanged,
"created_at": formatTime(request.CreatedAt),
"updated_at": formatTime(request.UpdatedAt),
}
}