mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
Feat[BE]: refactor document handling in transfer service and introduce document type constants
This commit is contained in:
@@ -20,4 +20,5 @@ type StockTransferDelivery struct {
|
|||||||
StockTransfer *StockTransfer `gorm:"foreignKey:StockTransferId"`
|
StockTransfer *StockTransfer `gorm:"foreignKey:StockTransferId"`
|
||||||
Supplier *Supplier `gorm:"foreignKey:SupplierId"`
|
Supplier *Supplier `gorm:"foreignKey:SupplierId"`
|
||||||
Items []StockTransferDeliveryItem `gorm:"foreignKey:StockTransferDeliveryId"`
|
Items []StockTransferDeliveryItem `gorm:"foreignKey:StockTransferDeliveryId"`
|
||||||
|
Documents []Document `gorm:"foreignKey:DocumentableId;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ func (u *TransferController) GetOne(c *fiber.Ctx) error {
|
|||||||
Code: fiber.StatusOK,
|
Code: fiber.StatusOK,
|
||||||
Status: "success",
|
Status: "success",
|
||||||
Message: "Get transfer successfully",
|
Message: "Get transfer successfully",
|
||||||
Data: dto.ToTransferListDTO(*result),
|
Data: dto.ToTransferDetailDTO(*result),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,6 +87,11 @@ func (u *TransferController) CreateOne(c *fiber.Ctx) error {
|
|||||||
|
|
||||||
files := form.File["documents"]
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
result, err := u.TransferService.CreateOne(c, &req, files)
|
result, err := u.TransferService.CreateOne(c, &req, files)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -97,6 +102,6 @@ func (u *TransferController) CreateOne(c *fiber.Ctx) error {
|
|||||||
Code: fiber.StatusCreated,
|
Code: fiber.StatusCreated,
|
||||||
Status: "success",
|
Status: "success",
|
||||||
Message: "Create transfer successfully",
|
Message: "Create transfer successfully",
|
||||||
Data: dto.ToTransferListDTO(*result),
|
Data: dto.ToTransferDetailDTO(*result),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ import (
|
|||||||
userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto"
|
userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto"
|
||||||
)
|
)
|
||||||
|
|
||||||
// === DTO Structs ===
|
|
||||||
|
|
||||||
type TransferRelationDTO struct {
|
type TransferRelationDTO struct {
|
||||||
Id uint64 `json:"id"`
|
Id uint64 `json:"id"`
|
||||||
TransferReason string `json:"transfer_reason"`
|
TransferReason string `json:"transfer_reason"`
|
||||||
@@ -17,7 +15,6 @@ type TransferRelationDTO struct {
|
|||||||
DestinationWarehouse *WarehouseDetailDTO `json:"destination_warehouse,omitempty"`
|
DestinationWarehouse *WarehouseDetailDTO `json:"destination_warehouse,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only id and name for warehouse simple view
|
|
||||||
type WarehouseSimpleDTO struct {
|
type WarehouseSimpleDTO struct {
|
||||||
Id uint `json:"id"`
|
Id uint `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
@@ -65,7 +62,6 @@ type TransferListDTO struct {
|
|||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
Details []TransferDetailItemDTO `json:"details"`
|
Details []TransferDetailItemDTO `json:"details"`
|
||||||
Deliveries []TransferDeliveryDTO `json:"deliveries"`
|
Deliveries []TransferDeliveryDTO `json:"deliveries"`
|
||||||
Documents []DocumentDTO `json:"documents"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type TransferDetailDTO struct {
|
type TransferDetailDTO struct {
|
||||||
@@ -74,14 +70,12 @@ type TransferDetailDTO struct {
|
|||||||
Deliveries []TransferDeliveryDTO `json:"deliveries"`
|
Deliveries []TransferDeliveryDTO `json:"deliveries"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detail produk
|
|
||||||
type TransferDetailItemDTO struct {
|
type TransferDetailItemDTO struct {
|
||||||
Id uint64 `json:"id"`
|
Id uint64 `json:"id"`
|
||||||
Proudct ProductSimpleDTO `json:"product"`
|
Product ProductSimpleDTO `json:"product"`
|
||||||
Quantity float64 `json:"quantity"`
|
Quantity float64 `json:"quantity"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delivery ekspedisi
|
|
||||||
type TransferDeliveryDTO struct {
|
type TransferDeliveryDTO struct {
|
||||||
Id uint64 `json:"id"`
|
Id uint64 `json:"id"`
|
||||||
Supplier SupplierSimpleDTO `json:"supplier"`
|
Supplier SupplierSimpleDTO `json:"supplier"`
|
||||||
@@ -91,6 +85,7 @@ type TransferDeliveryDTO struct {
|
|||||||
ShippingCostItem float64 `json:"shipping_cost_item"`
|
ShippingCostItem float64 `json:"shipping_cost_item"`
|
||||||
ShippingCostTotal float64 `json:"shipping_cost_total"`
|
ShippingCostTotal float64 `json:"shipping_cost_total"`
|
||||||
Items []TransferDeliveryItemDTO `json:"items"`
|
Items []TransferDeliveryItemDTO `json:"items"`
|
||||||
|
Documents []DocumentDTO `json:"documents"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TransferDeliveryItemDTO struct {
|
type TransferDeliveryItemDTO struct {
|
||||||
@@ -99,10 +94,7 @@ type TransferDeliveryItemDTO struct {
|
|||||||
Quantity float64 `json:"quantity"`
|
Quantity float64 `json:"quantity"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// === Mapper Functions ===
|
|
||||||
|
|
||||||
func ToTransferRelationDTO(e entity.StockTransfer) TransferRelationDTO {
|
func ToTransferRelationDTO(e entity.StockTransfer) TransferRelationDTO {
|
||||||
|
|
||||||
var sourceWarehouse *WarehouseDetailDTO
|
var sourceWarehouse *WarehouseDetailDTO
|
||||||
if e.FromWarehouse != nil && e.FromWarehouse.Id != 0 {
|
if e.FromWarehouse != nil && e.FromWarehouse.Id != 0 {
|
||||||
sourceWarehouse = toWarehouseDetailDTO(e.FromWarehouse)
|
sourceWarehouse = toWarehouseDetailDTO(e.FromWarehouse)
|
||||||
@@ -148,7 +140,7 @@ func toWarehouseDetailDTO(w *entity.Warehouse) *WarehouseDetailDTO {
|
|||||||
Id: w.Id,
|
Id: w.Id,
|
||||||
Name: w.Name,
|
Name: w.Name,
|
||||||
Location: toLocationDTO(w.Location),
|
Location: toLocationDTO(w.Location),
|
||||||
Area: toAreaDTO(&w.Area), // Ambil area langsung dari warehouse (area_id)
|
Area: toAreaDTO(&w.Area),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,22 +150,21 @@ func ToTransferListDTO(e entity.StockTransfer) TransferListDTO {
|
|||||||
mapped := userDTO.ToUserRelationDTO(*e.CreatedUser)
|
mapped := userDTO.ToUserRelationDTO(*e.CreatedUser)
|
||||||
createdUser = &mapped
|
createdUser = &mapped
|
||||||
}
|
}
|
||||||
// Map details
|
|
||||||
var details []TransferDetailItemDTO
|
var details []TransferDetailItemDTO
|
||||||
for _, d := range e.Details {
|
for _, d := range e.Details {
|
||||||
details = append(details, TransferDetailItemDTO{
|
details = append(details, TransferDetailItemDTO{
|
||||||
Id: d.Id,
|
Id: d.Id,
|
||||||
Proudct: ProductSimpleDTO{
|
Product: ProductSimpleDTO{
|
||||||
Id: d.Product.Id,
|
Id: d.Product.Id,
|
||||||
Name: d.Product.Name,
|
Name: d.Product.Name,
|
||||||
},
|
},
|
||||||
Quantity: d.Quantity,
|
Quantity: d.Quantity,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// Map deliveries
|
|
||||||
var deliveries []TransferDeliveryDTO
|
var deliveries []TransferDeliveryDTO
|
||||||
for _, del := range e.Deliveries {
|
for _, del := range e.Deliveries {
|
||||||
// Map delivery items
|
|
||||||
var items []TransferDeliveryItemDTO
|
var items []TransferDeliveryItemDTO
|
||||||
for _, item := range del.Items {
|
for _, item := range del.Items {
|
||||||
items = append(items, TransferDeliveryItemDTO{
|
items = append(items, TransferDeliveryItemDTO{
|
||||||
@@ -183,6 +174,17 @@ func ToTransferListDTO(e entity.StockTransfer) TransferListDTO {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var documents []DocumentDTO
|
||||||
|
for _, doc := range del.Documents {
|
||||||
|
documents = append(documents, DocumentDTO{
|
||||||
|
Id: doc.Id,
|
||||||
|
Path: doc.Path,
|
||||||
|
Name: doc.Name,
|
||||||
|
Ext: doc.Ext,
|
||||||
|
Size: doc.Size,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
deliveries = append(deliveries, TransferDeliveryDTO{
|
deliveries = append(deliveries, TransferDeliveryDTO{
|
||||||
Id: del.Id,
|
Id: del.Id,
|
||||||
Supplier: SupplierSimpleDTO{
|
Supplier: SupplierSimpleDTO{
|
||||||
@@ -195,16 +197,7 @@ func ToTransferListDTO(e entity.StockTransfer) TransferListDTO {
|
|||||||
ShippingCostItem: del.ShippingCostItem,
|
ShippingCostItem: del.ShippingCostItem,
|
||||||
ShippingCostTotal: del.ShippingCostTotal,
|
ShippingCostTotal: del.ShippingCostTotal,
|
||||||
Items: items,
|
Items: items,
|
||||||
})
|
Documents: documents,
|
||||||
}
|
|
||||||
var documents []DocumentDTO
|
|
||||||
for _, doc := range e.Documents {
|
|
||||||
documents = append(documents, DocumentDTO{
|
|
||||||
Id: doc.Id,
|
|
||||||
Path: doc.Path,
|
|
||||||
Name: doc.Name,
|
|
||||||
Ext: doc.Ext,
|
|
||||||
Size: doc.Size,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,7 +208,6 @@ func ToTransferListDTO(e entity.StockTransfer) TransferListDTO {
|
|||||||
UpdatedAt: e.UpdatedAt,
|
UpdatedAt: e.UpdatedAt,
|
||||||
Details: details,
|
Details: details,
|
||||||
Deliveries: deliveries,
|
Deliveries: deliveries,
|
||||||
Documents: documents,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,21 +220,31 @@ func ToTransferListDTOs(e []entity.StockTransfer) []TransferListDTO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ToTransferDetailDTO(e entity.StockTransfer) TransferDetailDTO {
|
func ToTransferDetailDTO(e entity.StockTransfer) TransferDetailDTO {
|
||||||
// Map details
|
|
||||||
var details []TransferDetailItemDTO
|
var details []TransferDetailItemDTO
|
||||||
for _, d := range e.Details {
|
for _, d := range e.Details {
|
||||||
details = append(details, TransferDetailItemDTO{
|
details = append(details, TransferDetailItemDTO{
|
||||||
Id: d.Id,
|
Id: d.Id,
|
||||||
Proudct: ProductSimpleDTO{
|
Product: ProductSimpleDTO{
|
||||||
Id: d.Product.Id,
|
Id: d.Product.Id,
|
||||||
Name: d.Product.Name,
|
Name: d.Product.Name,
|
||||||
},
|
},
|
||||||
Quantity: d.Quantity,
|
Quantity: d.Quantity,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// Map deliveries
|
|
||||||
var deliveries []TransferDeliveryDTO
|
var deliveries []TransferDeliveryDTO
|
||||||
for _, del := range e.Deliveries {
|
for _, del := range e.Deliveries {
|
||||||
|
var documents []DocumentDTO
|
||||||
|
for _, doc := range del.Documents {
|
||||||
|
documents = append(documents, DocumentDTO{
|
||||||
|
Id: doc.Id,
|
||||||
|
Path: doc.Path,
|
||||||
|
Name: doc.Name,
|
||||||
|
Ext: doc.Ext,
|
||||||
|
Size: doc.Size,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
deliveries = append(deliveries, TransferDeliveryDTO{
|
deliveries = append(deliveries, TransferDeliveryDTO{
|
||||||
Id: del.Id,
|
Id: del.Id,
|
||||||
Supplier: SupplierSimpleDTO{
|
Supplier: SupplierSimpleDTO{
|
||||||
@@ -254,8 +256,10 @@ func ToTransferDetailDTO(e entity.StockTransfer) TransferDetailDTO {
|
|||||||
DocumentNumber: del.DocumentNumber,
|
DocumentNumber: del.DocumentNumber,
|
||||||
ShippingCostItem: del.ShippingCostItem,
|
ShippingCostItem: del.ShippingCostItem,
|
||||||
ShippingCostTotal: del.ShippingCostTotal,
|
ShippingCostTotal: del.ShippingCostTotal,
|
||||||
|
Documents: documents,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return TransferDetailDTO{
|
return TransferDetailDTO{
|
||||||
TransferListDTO: ToTransferListDTO(e),
|
TransferListDTO: ToTransferListDTO(e),
|
||||||
Details: details,
|
Details: details,
|
||||||
|
|||||||
@@ -76,8 +76,8 @@ func (s transferService) withRelations(db *gorm.DB) *gorm.DB {
|
|||||||
Preload("Details.Product").
|
Preload("Details.Product").
|
||||||
Preload("Deliveries.Items").
|
Preload("Deliveries.Items").
|
||||||
Preload("Deliveries.Supplier").
|
Preload("Deliveries.Supplier").
|
||||||
Preload("Documents", func(db *gorm.DB) *gorm.DB {
|
Preload("Deliveries.Documents", func(db *gorm.DB) *gorm.DB {
|
||||||
return db.Where("documentable_type = ?", "STOCK_TRANSFER")
|
return db.Where("documentable_type = ?", string(utils.DocumentableTypeTransfer))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,29 +258,26 @@ func (s *transferService) CreateOne(c *fiber.Ctx, req *validation.TransferReques
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
actorIDCopy := actorID
|
|
||||||
if s.DocumentSvc != nil && len(files) > 0 {
|
if s.DocumentSvc != nil && len(files) > 0 {
|
||||||
s.Log.Infof("Starting document upload for %d files", len(files))
|
// Upload documents for each delivery
|
||||||
documentFiles := make([]commonSvc.DocumentFile, 0, len(files))
|
|
||||||
for idx, file := range files {
|
for idx, file := range files {
|
||||||
docIndex := idx
|
documentFiles := []commonSvc.DocumentFile{
|
||||||
documentFiles = append(documentFiles, commonSvc.DocumentFile{
|
{
|
||||||
File: file,
|
File: file,
|
||||||
Type: "STOCK_TRANSFER_DOCUMENT",
|
Type: string(utils.DocumentTypeTransfer),
|
||||||
Index: &docIndex,
|
Index: &idx,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_, err := s.DocumentSvc.UploadDocuments(c.Context(), commonSvc.DocumentUploadRequest{
|
||||||
|
DocumentableType: string(utils.DocumentableTypeTransfer),
|
||||||
|
DocumentableID: deliveries[idx].Id,
|
||||||
|
CreatedBy: &actorID,
|
||||||
|
Files: documentFiles,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to upload document for delivery %d", idx+1))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_, err := s.DocumentSvc.UploadDocuments(c.Context(), commonSvc.DocumentUploadRequest{
|
|
||||||
DocumentableType: "STOCK_TRANSFER",
|
|
||||||
DocumentableID: entityTransfer.Id,
|
|
||||||
CreatedBy: &actorIDCopy,
|
|
||||||
Files: documentFiles,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
s.Log.Errorf("Failed to upload documents for transfer %d: %+v", entityTransfer.Id, err)
|
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to upload transfer documents")
|
|
||||||
}
|
|
||||||
s.Log.Infof("Successfully uploaded documents for transfer ID %d", entityTransfer.Id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, product := range req.Products {
|
for _, product := range req.Products {
|
||||||
|
|||||||
@@ -314,6 +314,19 @@ var ExpenseApprovalSteps = map[approvalutils.ApprovalStep]string{
|
|||||||
ExpenseStepSelesai: "Selesai",
|
ExpenseStepSelesai: "Selesai",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Document
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
|
type DocumentType string
|
||||||
|
type DocumentableType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
DocumentTypeTransfer DocumentType = "STOCK_TRANSFER_DOCUMENT"
|
||||||
|
|
||||||
|
DocumentableTypeTransfer DocumentableType = "STOCK_TRANSFER"
|
||||||
|
)
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Validators
|
// Validators
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
@@ -448,7 +461,7 @@ func IsValidExpenseCategory(v string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// example use
|
// e xample use
|
||||||
|
|
||||||
// Recording helper
|
// Recording helper
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user