wms-be/modules/product/dto/product_dto.go

314 lines
12 KiB
Go

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 (
MESSAGE_FAILED_CREATE_PRODUCT = "failed create product"
MESSAGE_SUCCESS_CREATE_PRODUCT = "success create product"
MESSAGE_FAILED_GET_PRODUCT = "failed get product"
MESSAGE_SUCCESS_GET_PRODUCT = "success get product"
MESSAGE_FAILED_UPDATE_PRODUCT = "failed update product"
MESSAGE_SUCCESS_UPDATE_PRODUCT = "success update product"
MESSAGE_FAILED_DELETE_PRODUCT = "failed delete product"
MESSAGE_SUCCESS_DELETE_PRODUCT = "success delete product"
MESSAGE_FAILED_GET_DATA_FROM_BODY = "failed get data from body"
MESSAGE_FAILED_ASSIGN_CROSS_REF = "failed assign cross reference"
MESSAGE_SUCCESS_ASSIGN_CROSS_REF = "success assign cross reference"
MESSAGE_FAILED_REMOVE_CROSS_REF = "failed remove cross reference"
MESSAGE_SUCCESS_REMOVE_CROSS_REF = "success remove cross reference"
)
var (
ErrCreateProduct = errors.New("failed to create product")
ErrGetProductById = errors.New("failed to get product by id")
ErrUpdateProduct = errors.New("failed to update product")
ErrDeleteProduct = errors.New("failed to delete product")
ErrAssignCrossRef = errors.New("failed to assign cross reference")
ErrRemoveCrossRef = errors.New("failed to remove cross reference")
)
type (
ProductCreateRequest struct {
Name string `json:"name" binding:"required"`
// RefNumber string `json:"ref_number" binding:"required"`
SKU string `json:"sku" binding:"required"`
Description string `json:"description"`
Status string `json:"status" binding:"required"`
IsReturnable bool `json:"is_returnable"`
// DimLength float64 `json:"dim_length"`
// DimWidth float64 `json:"dim_width"`
// DimHeight float64 `json:"dim_height"`
// Weight float64 `json:"weight"`
// Volume float64 `json:"volume"`
// MaxStackHeight int `json:"max_stack_height"`
// Temperature string `json:"temperature"`
// IsHazardous bool `json:"is_hazardous"`
// MinStock int `json:"min_stock"`
// MaxStock int `json:"max_stock"`
// ReplenishType string `json:"replenish_type"`
// CycleCount string `json:"cycle_count"`
// LotRules string `json:"lot_rules"`
// LeadTime int `json:"lead_time"`
// MultiplyRate string `json:"multiply_rate"`
// DivideRate float64 `json:"divide_rate"`
ClientID string `json:"client_id" binding:"required"`
CategoryID *string `json:"category_id"`
UomID *string `json:"uom_id"`
// DimUomID string `json:"dim_uom_id"`
// WeightUomID string `json:"weight_uom_id"`
// VolumeUomID string `json:"volume_uom_id"`
// MinStockUomID string `json:"min_stock_uom_id"`
// MaxStockUomID string `json:"max_stock_uom_id"`
// LeadTimeUomID string `json:"lead_time_uom_id"`
// UomToUomID string `json:"uom_to_uom_id"`
}
ProductUpdateRequest struct {
Name *string `json:"name"`
// RefNumber *string `json:"ref_number"`
SKU *string `json:"sku"`
Description *string `json:"description"`
Status *string `json:"status"`
IsReturnable *bool `json:"is_returnable"`
DimLength *float64 `json:"dim_length"`
DimWidth *float64 `json:"dim_width"`
DimHeight *float64 `json:"dim_height"`
Weight *float64 `json:"weight"`
Volume *float64 `json:"volume"`
MaxStackHeight *int `json:"max_stack_height"`
Temperature *string `json:"temperature"`
IsHazardous *bool `json:"is_hazardous"`
MinStock *int `json:"min_stock"`
MaxStock *int `json:"max_stock"`
ReplenishType *string `json:"replenish_type"`
CycleCount *string `json:"cycle_count"`
LotRules *string `json:"lot_rules"`
LeadTime *int `json:"lead_time"`
MultiplyRate *string `json:"multiply_rate"`
DivideRate *float64 `json:"divide_rate"`
ClientID *string `json:"client_id"`
CategoryID *string `json:"category_id"`
UomID *string `json:"uom_id"`
DimUomID *string `json:"dim_uom_id"`
WeightUomID *string `json:"weight_uom_id"`
VolumeUomID *string `json:"volume_uom_id"`
MinStockUomID *string `json:"min_stock_uom_id"`
MaxStockUomID *string `json:"max_stock_uom_id"`
LeadTimeUomID *string `json:"lead_time_uom_id"`
UomToUomID *string `json:"uom_to_uom_id"`
}
ProductResponse struct {
ID string `json:"id"`
Name string `json:"name"`
RefNumber string `json:"ref_number"`
SKU string `json:"sku"`
Description string `json:"description"`
Status string `json:"status"`
IsReturnable bool `json:"is_returnable"`
DimLength float64 `json:"dim_length"`
DimWidth float64 `json:"dim_width"`
DimHeight float64 `json:"dim_height"`
Weight float64 `json:"weight"`
Volume float64 `json:"volume"`
MaxStackHeight int `json:"max_stack_height"`
Temperature string `json:"temperature"`
IsHazardous bool `json:"is_hazardous"`
MinStock int `json:"min_stock"`
MaxStock int `json:"max_stock"`
ReplenishType string `json:"replenish_type"`
CycleCount string `json:"cycle_count"`
LotRules string `json:"lot_rules"`
LeadTime int `json:"lead_time"`
MultiplyRate string `json:"multiply_rate"`
DivideRate float64 `json:"divide_rate"`
Client pkgdto.IdNameResponse `json:"client"`
Category pkgdto.IdNameResponse `json:"category"`
Uom pkgdto.IdNameResponse `json:"uom"`
DimUom pkgdto.IdNameResponse `json:"dim_uom"`
WeightUom pkgdto.IdNameResponse `json:"weight_uom"`
VolumeUom pkgdto.IdNameResponse `json:"volume_uom"`
MinStockUom pkgdto.IdNameResponse `json:"min_stock_uom"`
MaxStockUom pkgdto.IdNameResponse `json:"max_stock_uom"`
LeadTimeUom pkgdto.IdNameResponse `json:"lead_time_uom"`
UomToUom pkgdto.IdNameResponse `json:"uom_to_uom"`
CrossReferences []ProductVendorResponse `json:"cross_references"`
InvTransactions []ProductInventoryTransactionResponse `json:"inv_transactions"`
}
CrossReferenceRequest struct {
VendorIDs []string `json:"vendor_ids" binding:"required"`
}
ProductVendorResponse struct {
ID string `json:"id"`
Name string `json:"name"`
SearchKey string `json:"search_key"`
Address string `json:"address"`
ContactPerson string `json:"contact_person"`
}
ProductInventoryTransactionResponse struct {
ID string `json:"id"`
TransactionDate string `json:"transaction_date"`
TransactionType string `json:"transaction_type"`
TransactionQuantity float64 `json:"transaction_quantity"`
Lot string `json:"lot"`
Locater string `json:"locater"`
InvReceiptRef string `json:"inv_receipt_ref,omitempty"`
InvIssueRef string `json:"inv_issue_ref,omitempty"`
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,
}
}