feat(BE): add file size validation and improve document indexing for transfer creation

This commit is contained in:
aguhh18
2026-01-08 18:52:12 +07:00
parent 2650e919e7
commit 7af78d04dd
3 changed files with 28 additions and 14 deletions
@@ -75,6 +75,8 @@ func (u *TransferController) GetOne(c *fiber.Ctx) error {
func (u *TransferController) CreateOne(c *fiber.Ctx) error {
data := c.FormValue("data")
const maxFileSize = 5 * 1024 * 1024
var req validation.TransferRequest
if err := json.Unmarshal([]byte(data), &req); err != nil {
return fiber.NewError(fiber.StatusBadRequest, "Invalid request body")
@@ -87,9 +89,11 @@ func (u *TransferController) CreateOne(c *fiber.Ctx) error {
files := form.File["documents"]
if len(files) != len(req.Deliveries) {
return fiber.NewError(fiber.StatusBadRequest,
fiber.NewError(fiber.StatusBadRequest, "Jumlah dokumen harus sama dengan jumlah deliveries").Message)
for i, file := range files {
if file.Size > maxFileSize {
return fiber.NewError(fiber.StatusBadRequest,
"Dokumen ke-"+strconv.Itoa(i+1)+" melebihi ukuran maksimal 5MB")
}
}
result, err := u.TransferService.CreateOne(c, &req, files)
@@ -128,7 +128,6 @@ func (s transferService) GetOne(c *fiber.Ctx, id uint) (*entity.StockTransfer, e
func (s *transferService) CreateOne(c *fiber.Ctx, req *validation.TransferRequest, files []*multipart.FileHeader) (*entity.StockTransfer, error) {
// === VALIDASI SOURCE WAREHOUSE ===
pwIDs := make([]uint, 0, len(req.Products))
for _, product := range req.Products {
@@ -201,7 +200,6 @@ func (s *transferService) CreateOne(c *fiber.Ctx, req *validation.TransferReques
return nil, fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Supplier dengan ID %d bukan kategori BOP", delivery.SupplierID))
}
}
seqNum, err := s.StockTransferRepo.GetNextMovementNumber(c.Context())
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to generate movement number")
@@ -226,12 +224,11 @@ func (s *transferService) CreateOne(c *fiber.Ctx, req *validation.TransferReques
return err
}
// Prepare details and fetch product warehouses
details := make([]*entity.StockTransferDetail, 0, len(req.Products))
detailMap := make(map[uint64]*entity.StockTransferDetail)
for _, product := range req.Products {
// Get source product warehouse
sourcePW, err := s.ProductWarehouseRepo.GetProductWarehouseByProductAndWarehouseID(
c.Context(), uint(product.ProductID), uint(req.SourceWarehouseID),
)
@@ -242,7 +239,6 @@ func (s *transferService) CreateOne(c *fiber.Ctx, req *validation.TransferReques
return fiber.NewError(fiber.StatusInternalServerError, "Gagal mengambil data product warehouse source")
}
// Get or create destination product warehouse
destPW, err := s.ProductWarehouseRepo.GetProductWarehouseByProductAndWarehouseID(
c.Context(), uint(product.ProductID), uint(req.DestinationWarehouseID),
)
@@ -323,24 +319,38 @@ func (s *transferService) CreateOne(c *fiber.Ctx, req *validation.TransferReques
if s.DocumentSvc != nil && len(files) > 0 {
for idx, file := range files {
for deliveryIdx, delivery := range deliveries {
reqDelivery := req.Deliveries[deliveryIdx]
if reqDelivery.DocumentIndex < 0 {
continue
}
if reqDelivery.DocumentIndex >= len(files) {
return fiber.NewError(fiber.StatusBadRequest,
fmt.Sprintf("DocumentIndex %d untuk delivery %d melebihi jumlah file yang diupload (%d)",
reqDelivery.DocumentIndex, deliveryIdx+1, len(files)))
}
file := files[reqDelivery.DocumentIndex]
documentFiles := []commonSvc.DocumentFile{
{
File: file,
Type: string(utils.DocumentTypeTransfer),
Index: &idx,
Index: &reqDelivery.DocumentIndex,
},
}
_, err := s.DocumentSvc.UploadDocuments(c.Context(), commonSvc.DocumentUploadRequest{
DocumentableType: string(utils.DocumentableTypeTransfer),
DocumentableID: deliveries[idx].Id,
DocumentableID: delivery.Id,
CreatedBy: &actorID,
Files: documentFiles,
})
if err != nil {
s.Log.WithError(err).Errorf("Failed to upload document for delivery %d (delivery_id: %d, filename: %s)",
idx+1, deliveries[idx].Id, file.Filename)
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to upload document for delivery %d: %v", idx+1, err))
deliveryIdx+1, delivery.Id, file.Filename)
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to upload document for delivery %d: %v", deliveryIdx+1, err))
}
}
}
@@ -23,7 +23,7 @@ type TransferDeliveryProduct struct {
type TransferDelivery struct {
DeliveryCost float64 `json:"delivery_cost" validate:"required"`
DeliveryCostPerItem float64 `json:"delivery_cost_per_item" validate:"required"`
DocumentIndex int `json:"document_index" validate:"min=0"`
DocumentIndex int `json:"document_index" validate:"omitempty,min=-1" default:"-1"`
DriverName string `json:"driver_name" validate:"required"`
VehiclePlate string `json:"vehicle_plate" validate:"required"`
SupplierID uint `json:"supplier_id" validate:"required"`