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, "purchase_task_id": request.PurchaseTaskID, "source_changed": request.SourceChanged, "created_at": formatTime(request.CreatedAt), "updated_at": formatTime(request.UpdatedAt), } }