package cost_component import ( "cargo-erp-backend/internal/domain" "cargo-erp-backend/pkg/helpers" "cargo-erp-backend/pkg/importer" "fmt" "strconv" "strings" "time" "gorm.io/gorm" ) type CostComponentImportHandler struct { UserData domain.User Helper helpers.HelperInterface lastGroupName string } func NewCostComponentImportHandler(userData domain.User, helper helpers.HelperInterface) importer.ImportHandler { return &CostComponentImportHandler{ UserData: userData, Helper: helper, } } func (h *CostComponentImportHandler) ValidateRow(row []string, rowNumber int) (importer.RowData, []error) { var errors []error if len(row) < 5 { errors = append(errors, fmt.Errorf("row must have 5 columns: name, code, inc, value, cost_component_group_name")) return nil, errors } name := strings.TrimSpace(row[0]) if name == "" { errors = append(errors, fmt.Errorf("name is required")) } else if len(name) < 2 { errors = append(errors, fmt.Errorf("name must be at least 2 characters")) } else if len(name) > 255 { errors = append(errors, fmt.Errorf("name must be at most 255 characters")) } code := strings.TrimSpace(row[1]) if code == "" { errors = append(errors, fmt.Errorf("code is required")) } incStr := strings.TrimSpace(row[2]) var inc int32 if incStr != "" { parsed, err := strconv.ParseInt(incStr, 10, 32) if err != nil { errors = append(errors, fmt.Errorf("inc must be a valid integer")) } else { inc = int32(parsed) } } value := strings.TrimSpace(row[3]) groupName := strings.TrimSpace(row[4]) if groupName == "" { errors = append(errors, fmt.Errorf("cost_component_group_name is required")) } if len(errors) > 0 { return nil, errors } var group domain.CostComponentGroup db := h.Helper.GetDB("slave") if err := db.Where("UPPER(name) = ?", strings.ToUpper(groupName)).First(&group).Error; err != nil { errors = append(errors, fmt.Errorf("cost_component_group '%s' not found", groupName)) return nil, errors } h.lastGroupName = groupName now := time.Now() component := &domain.CostComponent{ Name: &name, Code: &code, Inc: &inc, Value: &value, CostComponentGroupID: &group.ID, MerchantID: h.UserData.MerchantID, CreatedBy: &h.UserData.ID, CreatedOn: &now, UpdatedBy: &h.UserData.ID, UpdatedOn: &now, } return component, nil } func (h *CostComponentImportHandler) GetDataString(data importer.RowData) string { component := data.(*domain.CostComponent) name := "" if component.Name != nil { name = *component.Name } code := "" if component.Code != nil { code = *component.Code } return fmt.Sprintf("%s, %s, %s", name, code, h.lastGroupName) } func (h *CostComponentImportHandler) IsDuplicate(db *gorm.DB, data importer.RowData) bool { component := data.(*domain.CostComponent) var count int64 db.Model(&domain.CostComponent{}). Joins("JOIN cost_component_group ON cost_component.cost_component_group_id = cost_component_group.id"). Where("UPPER(cost_component.name) = ? AND UPPER(cost_component.code) = ? AND UPPER(cost_component_group.name) = ?", strings.ToUpper(*component.Name), strings.ToUpper(*component.Code), strings.ToUpper(h.lastGroupName)). Count(&count) return count > 0 } func (h *CostComponentImportHandler) GetTemplateHeaders() []string { return []string{"name", "code", "inc", "value", "cost_component_group_name"} } func (h *CostComponentImportHandler) GetTemplateRows() [][]string { return [][]string{ {"Component A", "CA", "1", "10000", "Group 1"}, {"Component B", "CB", "2", "20000", "Group 2"}, {"Component C", "CC", "3", "30000", "Group 1"}, } }