feat: update status field validation in inventory DTOs and add completed constant
Deploy Application / deploy (push) Successful in 37s
Details
Deploy Application / deploy (push) Successful in 37s
Details
This commit is contained in:
parent
2676a20026
commit
14eccfb336
|
|
@ -26,7 +26,7 @@ type InventoryIssueCreateRequest struct {
|
|||
IssuerBy string `json:"issuer_by"`
|
||||
InvRequestID string `json:"inv_request_id"`
|
||||
ClientID string `json:"client_id" binding:"required"`
|
||||
Status string `json:"status" binding:"required"`
|
||||
Status string `json:"status"`
|
||||
IssueLines []InventoryIssueLineCreateRequest `json:"issue_lines,omitempty" binding:"dive"`
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ type InventoryMovementCreateRequest struct {
|
|||
MovementDate string `json:"movement_date"`
|
||||
MovementType string `json:"movement_type"`
|
||||
ClientID string `json:"client_id" binding:"required"`
|
||||
Status string `json:"status" binding:"required"`
|
||||
Status string `json:"status"`
|
||||
SourceLocationID string `json:"source_location_id"`
|
||||
DestinationLocationID string `json:"destination_location_id"`
|
||||
MovementLines []InventoryMovementLineCreateRequest `json:"movement_lines,omitempty" binding:"dive"`
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ type InventoryReceiptCreateRequest struct {
|
|||
Source string `json:"source"`
|
||||
QrCodeFile string `json:"qr_code_file"`
|
||||
ClientID string `json:"client_id" binding:"required"`
|
||||
Status string `json:"status" binding:"required"`
|
||||
ReceiptLines []InventoryReceiptLineCreateRequest `json:"inventory_lines,omitempty" binding:"dive"`
|
||||
Status string `json:"status"`
|
||||
ReceiptLines []InventoryReceiptLineCreateRequest `json:"receipt_lines,omitempty" binding:"dive"`
|
||||
}
|
||||
|
||||
type InventoryReceiptLineCreateRequest struct {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ type InventoryRequestCreateRequest struct {
|
|||
RequestType string `json:"request_type"`
|
||||
Note string `json:"note"`
|
||||
ClientID string `json:"client_id" binding:"required"`
|
||||
Status string `json:"status" binding:"required"`
|
||||
Status string `json:"status"`
|
||||
RequestLines []InventoryRequestLineCreateRequest `json:"request_lines,omitempty" binding:"dive"`
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,11 @@ package dto
|
|||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
|
||||
"github.com/Caknoooo/go-gin-clean-starter/pkg/constants"
|
||||
pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
|
||||
"github.com/Caknoooo/go-gin-clean-starter/pkg/utils"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -164,3 +168,146 @@ type (
|
|||
InvMoveRef string `json:"inv_move_ref,omitempty"`
|
||||
}
|
||||
)
|
||||
|
||||
func MapProductToResponse(product entities.MProductEntity) ProductResponse {
|
||||
crossRefs := make([]ProductVendorResponse, 0, len(product.CrossReferences))
|
||||
for _, v := range product.CrossReferences {
|
||||
crossRefs = append(crossRefs, ProductVendorResponse{
|
||||
ID: v.Vendor.ID.String(),
|
||||
Name: v.Vendor.Name,
|
||||
Address: v.Vendor.Address,
|
||||
ContactPerson: v.Vendor.ContactPerson,
|
||||
SearchKey: v.Vendor.SearchKey,
|
||||
})
|
||||
}
|
||||
|
||||
invTransactions := make([]ProductInventoryTransactionResponse, 0, len(product.InventoryTransactions))
|
||||
for _, it := range product.InventoryTransactions {
|
||||
var transactionQuantity float64
|
||||
var lot, locater, invReceiptRef, invIssueRef, invMoveRef string
|
||||
var transactionDate string
|
||||
valid := false
|
||||
|
||||
// Receipt
|
||||
if it.InvReceipt.ID != uuid.Nil && it.InvReceipt.Status == constants.COMPLETED {
|
||||
invReceiptRef = it.InvReceipt.ReferenceNumber
|
||||
transactionDate = utils.DateTimeToString(it.TransactionDate)
|
||||
for _, line := range it.InvReceipt.ReceiptLines {
|
||||
if line.ProductID == it.ProductID {
|
||||
transactionQuantity = line.Quantity
|
||||
lot = line.BatchNumber
|
||||
valid = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Issue
|
||||
if it.InvIssue.ID != uuid.Nil && it.InvIssue.Status == constants.COMPLETED {
|
||||
invIssueRef = it.InvIssue.DocumentNumber
|
||||
transactionDate = utils.DateTimeToString(it.TransactionDate)
|
||||
for _, line := range it.InvIssue.IssueLines {
|
||||
if line.ProductID == it.ProductID {
|
||||
transactionQuantity = line.IssuedQuantity
|
||||
valid = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Move
|
||||
if it.InvMove.ID != uuid.Nil && it.InvMove.Status == constants.COMPLETED {
|
||||
invMoveRef = it.InvMove.MovementNumber
|
||||
transactionDate = utils.DateTimeToString(it.TransactionDate)
|
||||
for _, line := range it.InvMove.MovementLines {
|
||||
if line.ProductID == it.ProductID {
|
||||
transactionQuantity = line.MovedQuantity
|
||||
valid = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if valid {
|
||||
invTransactions = append(invTransactions, ProductInventoryTransactionResponse{
|
||||
ID: it.ID.String(),
|
||||
TransactionDate: transactionDate,
|
||||
TransactionType: it.TransactionType,
|
||||
TransactionQuantity: transactionQuantity,
|
||||
Lot: lot,
|
||||
Locater: locater,
|
||||
InvReceiptRef: invReceiptRef,
|
||||
InvIssueRef: invIssueRef,
|
||||
InvMoveRef: invMoveRef,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return ProductResponse{
|
||||
ID: product.ID.String(),
|
||||
Name: product.Name,
|
||||
RefNumber: product.RefNumber,
|
||||
SKU: product.SKU,
|
||||
Description: product.Description,
|
||||
Status: product.Status,
|
||||
IsReturnable: product.IsReturnable,
|
||||
DimLength: product.DimLength,
|
||||
DimWidth: product.DimWidth,
|
||||
DimHeight: product.DimHeight,
|
||||
Weight: product.Weight,
|
||||
Volume: product.Volume,
|
||||
MaxStackHeight: product.MaxStackHeight,
|
||||
Temperature: product.Temperature,
|
||||
IsHazardous: product.IsHazardous,
|
||||
MinStock: product.MinStock,
|
||||
MaxStock: product.MaxStock,
|
||||
ReplenishType: product.ReplenishType,
|
||||
CycleCount: product.CycleCount,
|
||||
LotRules: product.LotRules,
|
||||
LeadTime: product.LeadTime,
|
||||
MultiplyRate: product.MultiplyRate,
|
||||
DivideRate: product.DivideRate,
|
||||
Client: pkgdto.IdNameResponse{
|
||||
ID: product.Client.ID.String(),
|
||||
Name: product.Client.Name,
|
||||
},
|
||||
Category: pkgdto.IdNameResponse{
|
||||
ID: product.Category.ID.String(),
|
||||
Name: product.Category.Name,
|
||||
},
|
||||
Uom: pkgdto.IdNameResponse{
|
||||
ID: product.Uom.ID.String(),
|
||||
Name: product.Uom.Name,
|
||||
},
|
||||
DimUom: pkgdto.IdNameResponse{
|
||||
ID: product.DimUom.ID.String(),
|
||||
Name: product.DimUom.Name,
|
||||
},
|
||||
WeightUom: pkgdto.IdNameResponse{
|
||||
ID: product.WeightUom.ID.String(),
|
||||
Name: product.WeightUom.Name,
|
||||
},
|
||||
VolumeUom: pkgdto.IdNameResponse{
|
||||
ID: product.VolumeUom.ID.String(),
|
||||
Name: product.VolumeUom.Name,
|
||||
},
|
||||
MinStockUom: pkgdto.IdNameResponse{
|
||||
ID: product.MinStockUom.ID.String(),
|
||||
Name: product.MinStockUom.Name,
|
||||
},
|
||||
MaxStockUom: pkgdto.IdNameResponse{
|
||||
ID: product.MaxStockUom.ID.String(),
|
||||
Name: product.MaxStockUom.Name,
|
||||
},
|
||||
LeadTimeUom: pkgdto.IdNameResponse{
|
||||
ID: product.LeadTimeUom.ID.String(),
|
||||
Name: product.LeadTimeUom.Name,
|
||||
},
|
||||
UomToUom: pkgdto.IdNameResponse{
|
||||
ID: product.UomToUom.ID.String(),
|
||||
Name: product.UomToUom.Name,
|
||||
},
|
||||
CrossReferences: crossRefs,
|
||||
InvTransactions: invTransactions,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,7 @@ import (
|
|||
"github.com/Caknoooo/go-gin-clean-starter/modules/product/dto"
|
||||
"github.com/Caknoooo/go-gin-clean-starter/modules/product/query"
|
||||
"github.com/Caknoooo/go-gin-clean-starter/modules/product/repository"
|
||||
pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
|
||||
"github.com/Caknoooo/go-gin-clean-starter/pkg/utils"
|
||||
"github.com/google/uuid"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
|
|
@ -148,7 +145,7 @@ func (s *productService) GetById(ctx context.Context, productId string) (dto.Pro
|
|||
if err != nil {
|
||||
return dto.ProductResponse{}, err
|
||||
}
|
||||
return mapProductToResponse(product), nil
|
||||
return dto.MapProductToResponse(product), nil
|
||||
}
|
||||
|
||||
func (s *productService) GetAll(ctx context.Context, filter query.ProductFilter) ([]dto.ProductResponse, int64, error) {
|
||||
|
|
@ -158,7 +155,7 @@ func (s *productService) GetAll(ctx context.Context, filter query.ProductFilter)
|
|||
}
|
||||
var responses []dto.ProductResponse
|
||||
for _, p := range products {
|
||||
responses = append(responses, mapProductToResponse(p))
|
||||
responses = append(responses, dto.MapProductToResponse(p))
|
||||
}
|
||||
if len(responses) == 0 {
|
||||
responses = []dto.ProductResponse{} // <-- pastikan slice kosong, bukan nil
|
||||
|
|
@ -322,148 +319,3 @@ func parseUUID(id string) uuid.UUID {
|
|||
}
|
||||
return u
|
||||
}
|
||||
|
||||
func mapProductToResponse(product entities.MProductEntity) dto.ProductResponse {
|
||||
crossRefs := make([]dto.ProductVendorResponse, 0, len(product.CrossReferences))
|
||||
for _, v := range product.CrossReferences {
|
||||
crossRefs = append(crossRefs, dto.ProductVendorResponse{
|
||||
ID: v.Vendor.ID.String(),
|
||||
Name: v.Vendor.Name,
|
||||
Address: v.Vendor.Address,
|
||||
ContactPerson: v.Vendor.ContactPerson,
|
||||
SearchKey: v.Vendor.SearchKey,
|
||||
})
|
||||
}
|
||||
|
||||
logrus.Infof("Inventory Transactions Count: %d", len(product.InventoryTransactions))
|
||||
invTransactions := make([]dto.ProductInventoryTransactionResponse, 0, len(product.InventoryTransactions))
|
||||
for _, it := range product.InventoryTransactions {
|
||||
var transactionQuantity float64
|
||||
var lot, locater, invReceiptRef, invIssueRef, invMoveRef string
|
||||
var transactionDate string
|
||||
|
||||
// Receipt
|
||||
if it.InvReceipt.ID != uuid.Nil {
|
||||
invReceiptRef = it.InvReceipt.ReferenceNumber
|
||||
transactionDate = utils.DateTimeToString(it.TransactionDate)
|
||||
// Cari line yang sesuai product
|
||||
for _, line := range it.InvReceipt.ReceiptLines {
|
||||
if line.ProductID == it.ProductID {
|
||||
transactionQuantity = line.Quantity
|
||||
lot = line.BatchNumber
|
||||
// Jika ada field lokasi, isi di sini
|
||||
// locater = line.Locater
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Issue
|
||||
if it.InvIssue.ID != uuid.Nil {
|
||||
invIssueRef = it.InvIssue.DocumentNumber
|
||||
transactionDate = utils.DateTimeToString(it.TransactionDate)
|
||||
for _, line := range it.InvIssue.IssueLines {
|
||||
if line.ProductID == it.ProductID {
|
||||
transactionQuantity = line.IssuedQuantity
|
||||
// lot = line.BatchNumber
|
||||
// locater = line.Locater
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Move
|
||||
if it.InvMove.ID != uuid.Nil {
|
||||
invMoveRef = it.InvMove.MovementNumber
|
||||
transactionDate = utils.DateTimeToString(it.TransactionDate)
|
||||
for _, line := range it.InvMove.MovementLines {
|
||||
if line.ProductID == it.ProductID {
|
||||
transactionQuantity = line.MovedQuantity
|
||||
// lot = line.BatchNumber
|
||||
// locater = line.Locater
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
invTransactions = append(invTransactions, dto.ProductInventoryTransactionResponse{
|
||||
ID: it.ID.String(),
|
||||
TransactionDate: transactionDate,
|
||||
TransactionType: it.TransactionType,
|
||||
TransactionQuantity: transactionQuantity,
|
||||
Lot: lot,
|
||||
Locater: locater,
|
||||
InvReceiptRef: invReceiptRef,
|
||||
InvIssueRef: invIssueRef,
|
||||
InvMoveRef: invMoveRef,
|
||||
})
|
||||
}
|
||||
|
||||
return dto.ProductResponse{
|
||||
ID: product.ID.String(),
|
||||
Name: product.Name,
|
||||
RefNumber: product.RefNumber,
|
||||
SKU: product.SKU,
|
||||
Description: product.Description,
|
||||
Status: product.Status,
|
||||
IsReturnable: product.IsReturnable,
|
||||
DimLength: product.DimLength,
|
||||
DimWidth: product.DimWidth,
|
||||
DimHeight: product.DimHeight,
|
||||
Weight: product.Weight,
|
||||
Volume: product.Volume,
|
||||
MaxStackHeight: product.MaxStackHeight,
|
||||
Temperature: product.Temperature,
|
||||
IsHazardous: product.IsHazardous,
|
||||
MinStock: product.MinStock,
|
||||
MaxStock: product.MaxStock,
|
||||
ReplenishType: product.ReplenishType,
|
||||
CycleCount: product.CycleCount,
|
||||
LotRules: product.LotRules,
|
||||
LeadTime: product.LeadTime,
|
||||
MultiplyRate: product.MultiplyRate,
|
||||
DivideRate: product.DivideRate,
|
||||
Client: pkgdto.IdNameResponse{
|
||||
ID: product.Client.ID.String(),
|
||||
Name: product.Client.Name,
|
||||
},
|
||||
Category: pkgdto.IdNameResponse{
|
||||
ID: product.Category.ID.String(),
|
||||
Name: product.Category.Name,
|
||||
},
|
||||
Uom: pkgdto.IdNameResponse{
|
||||
ID: product.Uom.ID.String(),
|
||||
Name: product.Uom.Name,
|
||||
},
|
||||
DimUom: pkgdto.IdNameResponse{
|
||||
ID: product.DimUom.ID.String(),
|
||||
Name: product.DimUom.Name,
|
||||
},
|
||||
WeightUom: pkgdto.IdNameResponse{
|
||||
ID: product.WeightUom.ID.String(),
|
||||
Name: product.WeightUom.Name,
|
||||
},
|
||||
VolumeUom: pkgdto.IdNameResponse{
|
||||
ID: product.VolumeUom.ID.String(),
|
||||
Name: product.VolumeUom.Name,
|
||||
},
|
||||
MinStockUom: pkgdto.IdNameResponse{
|
||||
ID: product.MinStockUom.ID.String(),
|
||||
Name: product.MinStockUom.Name,
|
||||
},
|
||||
MaxStockUom: pkgdto.IdNameResponse{
|
||||
ID: product.MaxStockUom.ID.String(),
|
||||
Name: product.MaxStockUom.Name,
|
||||
},
|
||||
LeadTimeUom: pkgdto.IdNameResponse{
|
||||
ID: product.LeadTimeUom.ID.String(),
|
||||
Name: product.LeadTimeUom.Name,
|
||||
},
|
||||
UomToUom: pkgdto.IdNameResponse{
|
||||
ID: product.UomToUom.ID.String(),
|
||||
Name: product.UomToUom.Name,
|
||||
},
|
||||
CrossReferences: crossRefs,
|
||||
InvTransactions: invTransactions,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,4 +14,5 @@ const (
|
|||
JWTService = "JWTService"
|
||||
LOGGER = "logger"
|
||||
SUPERADMIN = "superadmin"
|
||||
COMPLETED = "completed"
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue