129 lines
5.7 KiB
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
|
|
}
|