wms-be/database/entities/m_product_entity.go

129 lines
5.7 KiB
Go

package entities
import (
"fmt"
"strings"
"time"
"github.com/google/uuid"
"gorm.io/gorm"
)
type MProductEntity struct {
ID uuid.UUID `gorm:"type:uuid;default:uuid_generate_v4()" json:"id"`
Name string `gorm:"type:varchar(255);not null" json:"name"`
RefNumber string `gorm:"type:varchar(100);not null;" json:"ref_number"`
SKU string `gorm:"type:varchar(100);not null;" json:"sku"`
Description string `gorm:"type:text" json:"description"`
Status string `gorm:"type:varchar(50);not null" json:"status"`
IsReturnable bool `gorm:"type:boolean;default:false" json:"is_returnable"`
DimLength float64 `gorm:"type:decimal(10,2);" json:"dim_length"`
DimWidth float64 `gorm:"type:decimal(10,2);" json:"dim_width"`
DimHeight float64 `gorm:"type:decimal(10,2);" json:"dim_height"`
Weight float64 `gorm:"type:decimal(10,2);" json:"weight"`
Volume float64 `gorm:"type:decimal(10,2);" json:"volume"`
MaxStackHeight int `gorm:"type:int;" json:"max_stack_height"`
Temperature string `gorm:"type:varchar(50)" json:"temperature"`
IsHazardous bool `gorm:"type:boolean;default:false" json:"is_hazardous"`
MinStock int `gorm:"type:int;default:0" json:"min_stock"`
MaxStock int `gorm:"type:int;default:0" json:"max_stock"`
ReplenishType string `gorm:"type:varchar(50)" json:"replenish_type"`
CycleCount string `gorm:"type:varchar(50);default:0" json:"cycle_count"`
LotRules string `gorm:"type:varchar(100)" json:"lot_rules"`
LeadTime int `gorm:"type:int;default:0" json:"lead_time"`
MultiplyRate string `gorm:"type:varchar(50)" json:"multiply_rate"`
DivideRate float64 `gorm:"type:decimal(10,2)" json:"divide_rate"`
ClientID uuid.UUID `gorm:"type:uuid;index;" json:"client_id"`
CategoryID *uuid.UUID `gorm:"type:uuid;index" json:"category_id"`
UomID *uuid.UUID `gorm:"type:uuid;index" json:"uom_id"`
DimUomID *uuid.UUID `gorm:"type:uuid;index" json:"dim_uom_id"`
WeightUomID *uuid.UUID `gorm:"type:uuid;index" json:"weight_uom_id"`
VolumeUomID *uuid.UUID `gorm:"type:uuid;index" json:"volume_uom_id"`
MinStockUomID *uuid.UUID `gorm:"type:uuid;index" json:"min_stock_uom_id"`
MaxStockUomID *uuid.UUID `gorm:"type:uuid;index" json:"max_stock_uom_id"`
LeadTimeUomID *uuid.UUID `gorm:"type:uuid;index" json:"lead_time_uom_id"`
UomToUomID *uuid.UUID `gorm:"type:uuid;index" json:"uom_to_uom_id"`
Client M_Client `gorm:"foreignKey:ClientID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"`
Category MCategoryEntity `gorm:"foreignKey:CategoryID;references:ID"`
Uom MUomEntity `gorm:"foreignKey:UomID;references:ID"`
DimUom MUomEntity `gorm:"foreignKey:DimUomID;references:ID"`
WeightUom MUomEntity `gorm:"foreignKey:WeightUomID;references:ID"`
VolumeUom MUomEntity `gorm:"foreignKey:VolumeUomID;references:ID"`
MinStockUom MUomEntity `gorm:"foreignKey:MinStockUomID;references:ID"`
MaxStockUom MUomEntity `gorm:"foreignKey:MaxStockUomID;references:ID"`
LeadTimeUom MUomEntity `gorm:"foreignKey:LeadTimeUomID;references:ID"`
UomToUom MUomEntity `gorm:"foreignKey:UomToUomID;references:ID"`
CrossReferences []MCrossReferenceEntity `gorm:"foreignKey:ProductID;references:ID"`
InventoryTransactions []InventoryTransactionEntity `gorm:"foreignKey:ProductID;references:ID"`
InventoryStorages []InventoryStorageEntity `gorm:"foreignKey:ProductID;references:ID"`
FullAuditTrail
}
func (MProductEntity) TableName() string {
return "m_products"
}
// GenerateRefNumberProduct generates a new reference number for a product
func GenerateRefNumberProduct(db *gorm.DB, clientId string, categoryId string) (string, error) {
prefix := "PRD"
// Ambil nama client berdasarkan clientId
var client struct {
Name string
}
if err := db.Table("m_clients").Select("name").Where("id = ?", clientId).First(&client).Error; err != nil {
return "", fmt.Errorf("client not found")
}
if client.Name == "" {
return "", fmt.Errorf("client name is empty")
}
// Ambil search key kategori berdasarkan categoryId
var category struct {
SearchKey string
}
if err := db.Table("m_categories").Select("search_key").Where("id = ?", categoryId).First(&category).Error; err != nil {
return "", fmt.Errorf("category not found")
}
if category.SearchKey == "" {
return "", fmt.Errorf("category search key is empty")
}
categoryInitial := ""
lettersOnly := ""
for _, r := range category.SearchKey {
if (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') {
lettersOnly += string(r)
}
}
if len(lettersOnly) > 0 {
categoryInitial = strings.ToUpper(lettersOnly)
}
// Ambil tahun dan bulan sekarang
now := time.Now()
period := now.Format("0601") // YYYYMM
// Cari sequence terakhir untuk client dan kategori di periode ini
var lastProduct MProductEntity
prefixQuery := fmt.Sprintf("%s-%s-%s", prefix, categoryInitial, period)
err := db.
Where("client_id = ? AND category_id = ? AND LEFT(ref_number, ?) = ?", clientId, categoryId, len(prefixQuery), prefixQuery).
Order("ref_number DESC").
First(&lastProduct).Error
seq := 1
if err == nil && lastProduct.RefNumber != "" {
parts := strings.Split(lastProduct.RefNumber, "-")
if len(parts) == 4 {
fmt.Sscanf(parts[3], "%d", &seq)
seq++
}
}
refNum := fmt.Sprintf("%s-%s-%s-%04d", prefix, categoryInitial, period, seq)
return refNum, nil
}