Files
lti-api/internal/database/seed/seeder.go
T
2025-12-30 23:52:37 +07:00

453 lines
11 KiB
Go

package seed
import (
"errors"
"fmt"
"strings"
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
"gitlab.com/mbugroup/lti-api.git/internal/utils"
"gorm.io/gorm"
)
func Run(db *gorm.DB) error {
return db.Transaction(func(tx *gorm.DB) error {
users, err := seedUsers(tx)
if err != nil {
return err
}
adminID := users["admin"]
uoms, err := seedUoms(tx, adminID)
if err != nil {
return err
}
productCategories, err := seedProductCategories(tx, adminID)
if err != nil {
return err
}
suppliers, err := seedSuppliers(tx, adminID)
if err != nil {
return err
}
if err := seedProducts(tx, adminID, uoms, productCategories, suppliers); err != nil {
return err
}
fmt.Println("✅ Master data seeding completed")
return nil
})
}
func seedUsers(tx *gorm.DB) (map[string]uint, error) {
seeds := []struct {
Key string
Data entity.User
}{
{
Key: "admin",
Data: entity.User{Email: "admin@mbugroup.id", IdUser: 1, Name: "Super Admin"},
},
}
result := make(map[string]uint, len(seeds))
for _, seed := range seeds {
var user entity.User
err := tx.Where("email = ?", seed.Data.Email).First(&user).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
user = seed.Data
if err := tx.Create(&user).Error; err != nil {
return nil, err
}
} else if err != nil {
return nil, err
}
result[seed.Key] = user.Id
}
return result, nil
}
func seedUoms(tx *gorm.DB, createdBy uint) (map[string]uint, error) {
names := []string{"Kilogram", "Gram", "Liter", "Unit", "Ekor"}
result := make(map[string]uint, len(names))
for _, name := range names {
var uom entity.Uom
err := tx.Where("name = ?", name).First(&uom).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
uom = entity.Uom{Name: name, CreatedBy: createdBy}
if err := tx.Create(&uom).Error; err != nil {
return nil, err
}
} else if err != nil {
return nil, err
}
result[name] = uom.Id
}
return result, nil
}
func seedProductCategories(tx *gorm.DB, createdBy uint) (map[string]uint, error) {
seeds := []struct {
Name string
Code string
}{
{"Pullet", "PLT"},
{"Bahan Baku", "RAW"},
{"Day Old Chick", "DOC"},
{"Telur", "EGG"},
}
result := make(map[string]uint, len(seeds))
for _, seed := range seeds {
var category entity.ProductCategory
err := tx.Where("name = ?", seed.Name).First(&category).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
category = entity.ProductCategory{Name: seed.Name, Code: seed.Code, CreatedBy: createdBy}
if err := tx.Create(&category).Error; err != nil {
return nil, err
}
} else if err != nil {
return nil, err
} else {
if err := tx.Model(&entity.ProductCategory{}).Where("id = ?", category.Id).Updates(map[string]any{
"code": seed.Code,
}).Error; err != nil {
return nil, err
}
}
result[seed.Name] = category.Id
}
return result, nil
}
func seedSuppliers(tx *gorm.DB, createdBy uint) (map[string]uint, error) {
seeds := []struct {
Name string
Alias string
Category string
Email string
Phone string
Address string
}{
{"PT CHAROEN POKPHAND INDONESIA Tbk", "CPI", string(utils.SupplierCategorySapronak), "cpi@gmail.com", "081200000001", "Jl. Pakan 1, Bekasi"},
{"BOP Vendor", "BOP", string(utils.SupplierCategoryBOP), "bop@gmail.com", "081200000002", "Jl. Veteriner 3, Bogor"},
{"Ekspedisi", "EKS", string(utils.SupplierCategoryBOP), "bop@gmail.com", "081200000002", "Jl. Veteriner 3, Bogor"},
}
result := make(map[string]uint, len(seeds))
for idx, seed := range seeds {
var supplier entity.Supplier
err := tx.Where("name = ?", seed.Name).First(&supplier).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
supplier = entity.Supplier{
Name: seed.Name,
Alias: seed.Alias,
Pic: "John Doe",
Type: string(utils.CustomerSupplierTypeBisnis),
Category: seed.Category,
Phone: seed.Phone,
Email: seed.Email,
Address: seed.Address,
DueDate: 30,
CreatedBy: createdBy,
AccountNumber: strPtr(fmt.Sprintf("%03d", idx+1)),
}
if err := tx.Create(&supplier).Error; err != nil {
return nil, err
}
} else if err != nil {
return nil, err
}
result[seed.Name] = supplier.Id
}
return result, nil
}
func seedProducts(tx *gorm.DB, createdBy uint, uoms map[string]uint, categories map[string]uint, suppliers map[string]uint) error {
seeds := []struct {
Name string
Brand string
Sku string
Uom string
Category string
Price float64
Selling *float64
Tax *float64
Expiry *int
Suppliers []string
Flags []utils.FlagType
IsVisible bool
}{
{
Name: "ISA Brown",
Brand: "ISA Brown",
Sku: "ISA0001",
Uom: "Ekor",
Category: "Day Old Chick",
Price: 7500,
Suppliers: []string{"PT CHAROEN POKPHAND INDONESIA Tbk"},
Flags: []utils.FlagType{utils.FlagDOC, utils.FlagPullet, utils.FlagLayer},
IsVisible: true,
},
{
Name: "Ayam Afkir",
Brand: "-",
Sku: "1",
Uom: "Ekor",
Category: "Day Old Chick",
Price: 1,
Flags: []utils.FlagType{utils.FlagAyamAfkir},
IsVisible: false,
},
{
Name: "Ayam Mati",
Brand: "-",
Sku: "2",
Uom: "Ekor",
Category: "Day Old Chick",
Price: 1,
Flags: []utils.FlagType{utils.FlagAyamMati},
IsVisible: false,
},
{
Name: "Ayam Culling",
Brand: "-",
Sku: "3",
Uom: "Ekor",
Category: "Day Old Chick",
Price: 1,
Flags: []utils.FlagType{utils.FlagAyamCulling},
IsVisible: false,
},
{
Name: "Telur Utuh",
Brand: "-",
Sku: "4",
Uom: "Gram",
Category: "Telur",
Price: 1,
Flags: []utils.FlagType{utils.FlagTelurUtuh},
IsVisible: false,
},
{
Name: "Telur Pecah",
Brand: "-",
Sku: "5",
Uom: "Gram",
Category: "Telur",
Price: 1,
Flags: []utils.FlagType{utils.FlagTelurPecah},
IsVisible: false,
},
{
Name: "Telur Putih",
Brand: "-",
Sku: "6",
Uom: "Gram",
Category: "Telur",
Price: 1,
Flags: []utils.FlagType{utils.FlagTelurPutih},
IsVisible: false,
},
{
Name: "Telur Retak",
Brand: "-",
Sku: "7",
Uom: "Gram",
Category: "Telur",
Price: 1,
Flags: []utils.FlagType{utils.FlagTelurRetak},
IsVisible: false,
},
}
for _, seed := range seeds {
uomID, ok := uoms[seed.Uom]
if !ok {
return fmt.Errorf("uom %s not seeded", seed.Uom)
}
categoryID, ok := categories[seed.Category]
if !ok {
return fmt.Errorf("product category %s not seeded", seed.Category)
}
var product entity.Product
err := tx.Where("name = ?", seed.Name).First(&product).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
selling := seed.Selling
tax := seed.Tax
product = entity.Product{
Name: seed.Name,
Brand: seed.Brand,
Sku: &seed.Sku,
UomId: uomID,
ProductCategoryId: categoryID,
ProductPrice: seed.Price,
SellingPrice: selling,
Tax: tax,
ExpiryPeriod: seed.Expiry,
CreatedBy: createdBy,
}
if err := tx.Create(&product).Error; err != nil {
return err
}
} else if err != nil {
return err
} else {
updates := map[string]any{
"brand": seed.Brand,
"uom_id": uomID,
"product_category_id": categoryID,
"product_price": seed.Price,
"selling_price": seed.Selling,
"tax": seed.Tax,
"expiry_period": seed.Expiry,
}
if seed.Sku != "" {
updates["sku"] = seed.Sku
}
if err := tx.Model(&entity.Product{}).Where("id = ?", product.Id).Updates(updates).Error; err != nil {
return err
}
}
for _, supplierName := range seed.Suppliers {
supplierID, ok := suppliers[supplierName]
if !ok {
return fmt.Errorf("supplier %s not seeded", supplierName)
}
var existing entity.ProductSupplier
err := tx.Where("product_id = ? AND supplier_id = ?", product.Id, supplierID).First(&existing).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
link := entity.ProductSupplier{ProductId: product.Id, SupplierId: supplierID}
if err := tx.Create(&link).Error; err != nil {
return err
}
} else if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return err
}
}
if err := seedFlags(tx, product.Id, entity.FlagableTypeProduct, seed.Flags); err != nil {
return err
}
}
return nil
}
// func seedNonstocks(tx *gorm.DB, createdBy uint, uoms map[string]uint, suppliers map[string]uint) error {
// seeds := []struct {
// Name string
// Uom string
// Suppliers []string
// Flags []utils.FlagType
// }{
// {
// Name: "LAJ",
// Uom: "Unit",
// Suppliers: []string{"Ekspedisi"},
// Flags: []utils.FlagType{utils.FlagEkspedisi},
// },
// {
// Name: "Solar",
// Uom: "Liter",
// Suppliers: []string{"BOP Vendor"},
// Flags: []utils.FlagType{},
// },
// }
// for _, seed := range seeds {
// uomID, ok := uoms[seed.Uom]
// if !ok {
// return fmt.Errorf("uom %s not seeded", seed.Uom)
// }
// var nonstock entity.Nonstock
// err := tx.Where("name = ?", seed.Name).First(&nonstock).Error
// if errors.Is(err, gorm.ErrRecordNotFound) {
// nonstock = entity.Nonstock{
// Name: seed.Name,
// UomId: uomID,
// CreatedBy: createdBy,
// }
// if err := tx.Create(&nonstock).Error; err != nil {
// return err
// }
// } else if err != nil {
// return err
// } else {
// if err := tx.Model(&entity.Nonstock{}).Where("id = ?", nonstock.Id).Updates(map[string]any{
// "uom_id": uomID,
// }).Error; err != nil {
// return err
// }
// }
// for _, supplierName := range seed.Suppliers {
// supplierID, ok := suppliers[supplierName]
// if !ok {
// return fmt.Errorf("supplier %s not seeded", supplierName)
// }
// var existing entity.NonstockSupplier
// err := tx.Where("nonstock_id = ? AND supplier_id = ?", nonstock.Id, supplierID).First(&existing).Error
// if errors.Is(err, gorm.ErrRecordNotFound) {
// link := entity.NonstockSupplier{NonstockId: nonstock.Id, SupplierId: supplierID}
// if err := tx.Create(&link).Error; err != nil {
// return err
// }
// } else if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
// return err
// }
// }
// if err := seedFlags(tx, nonstock.Id, entity.FlagableTypeNonstock, seed.Flags); err != nil {
// return err
// }
// }
// return nil
// }
// nanti saya isi
func seedFlags(tx *gorm.DB, flagableID uint, flagableType string, flags []utils.FlagType) error {
if len(flags) == 0 {
return nil
}
for _, flag := range flags {
name := strings.ToUpper(string(flag))
var existing entity.Flag
err := tx.Where("name = ? AND flagable_id = ? AND flagable_type = ?", name, flagableID, flagableType).First(&existing).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
record := entity.Flag{
Name: name,
FlagableID: flagableID,
FlagableType: flagableType,
}
if err := tx.Create(&record).Error; err != nil {
return err
}
} else if err != nil {
return err
}
}
return nil
}
func strPtr(s string) *string {
return &s
}