package usecases import ( "cargo-erp-backend/internal/domain" "cargo-erp-backend/internal/handlers/dto" "cargo-erp-backend/pkg/datatable" "cargo-erp-backend/pkg/helpers" "fmt" "reflect" "time" "gorm.io/gorm" ) type CostComponentUsecaseInterface interface { GetAll(filter dto.CostComponentFilterAllRequest) ([]domain.CostComponent, int64, error) GetList(dto.DataTableRequest) (dto.DataTableResponse, error) GetByID(id string) (domain.CostComponent, error) Create(name string, code string, value string, componentType int32, createdBy string, merchantid *string) (domain.CostComponent, error) Update(id string, name string, code string, value string, componentType int32, updatedBy string) (domain.CostComponent, error) Delete(id string) error SortDown(id string) error SortUp(id string) error } type CostComponentUsecase struct { Helper helpers.HelperInterface AuthUser domain.User } func NewCostComponentUsecase(helper helpers.HelperInterface, authUser domain.User) CostComponentUsecaseInterface { return &CostComponentUsecase{Helper: helper, AuthUser: authUser} } func (u *CostComponentUsecase) GetAll(filter dto.CostComponentFilterAllRequest) ([]domain.CostComponent, int64, error) { var components []domain.CostComponent var total int64 db := u.Helper.GetDB("slave") tx := db.Model(&components) if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { tx.Where(db.Where("merchant_id IS NULL").Or("merchant_id=?", u.AuthUser.MerchantID)) } v := reflect.ValueOf(filter) t := reflect.TypeOf(filter) for i := 0; i < v.NumField(); i++ { if v.Field(i).String() != "" { tagKey := t.Field(i).Tag.Get("form") tx.Where(fmt.Sprintf("%v=?", tagKey), v.Field(i)) } } tx.Model(&domain.CostComponent{}).Count(&total) tx.Order("inc ASC, name ASC") if err := tx.Find(&components).Error; err != nil { return nil, 0, err } return components, total, nil } func (u *CostComponentUsecase) GetList(req dto.DataTableRequest) (dto.DataTableResponse, error) { var response dto.DataTableResponse db := u.Helper.GetDB("slave") tx := db.Table("cost_component"). Joins("LEFT JOIN merchant ON cost_component.merchant_id=merchant.id") dt := datatable.NewDatatable(tx, req) coldef := make([]dto.DataTableColDef, 0) coldef = append(coldef, dto.DataTableColDef{ Field: "cost_component.name", Alias: "name", }) coldef = append(coldef, dto.DataTableColDef{ Field: "cost_component.code", Alias: "code", }) coldef = append(coldef, dto.DataTableColDef{ Field: "cost_component.inc", Alias: "inc", }) coldef = append(coldef, dto.DataTableColDef{ Field: "cost_component.value", Alias: "value", }) coldef = append(coldef, dto.DataTableColDef{ Field: "cost_component.component_type", Alias: "component_type", }) coldef = append(coldef, dto.DataTableColDef{ Field: "merchant.id", Alias: "merchant_id", }) coldef = append(coldef, dto.DataTableColDef{ Field: "cost_component.id", Alias: "id", }) response = dt.Render(coldef) return response, nil } func (u *CostComponentUsecase) GetByID(id string) (domain.CostComponent, error) { var component domain.CostComponent db := u.Helper.GetDB("slave") if err := db.Where("id = ?", id).First(&component).Error; err != nil { return domain.CostComponent{}, err } return component, nil } func (u *CostComponentUsecase) Create(name string, code string, value string, componentType int32, createdBy string, merchantid *string) (domain.CostComponent, error) { now := time.Now() db := u.Helper.GetDB("master") var component domain.CostComponent err := db.Transaction(func(tx *gorm.DB) error { var maxInc int64 q := tx.Model(&domain.CostComponent{}) if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { q = q.Where("merchant_id=?", u.AuthUser.MerchantID) } q.Select("COALESCE(MAX(inc),0)").Row().Scan(&maxInc) inc := int32(maxInc + 1) component = domain.CostComponent{ Name: &name, Code: &code, Inc: &inc, Value: &value, ComponentType: &componentType, MerchantID: merchantid, CreatedBy: &createdBy, CreatedOn: &now, UpdatedBy: &createdBy, UpdatedOn: &now, } return tx.Create(&component).Error }) if err != nil { return domain.CostComponent{}, err } return component, nil } func (u *CostComponentUsecase) Update(id string, name string, code string, value string, componentType int32, updatedBy string) (domain.CostComponent, error) { var component domain.CostComponent db := u.Helper.GetDB("master") err := db.Transaction(func(tx *gorm.DB) error { q := tx if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { q = tx.Where("merchant_id=?", u.AuthUser.MerchantID) } if err := q.Where("id = ?", id).First(&component).Error; err != nil { return err } now := time.Now() component.Name = &name component.Code = &code component.Value = &value component.ComponentType = &componentType component.UpdatedBy = &updatedBy component.UpdatedOn = &now return tx.Save(&component).Error }) if err != nil { return domain.CostComponent{}, err } return component, nil } func (u *CostComponentUsecase) Delete(id string) error { db := u.Helper.GetDB("master") if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { db.Where("merchant_id=?", u.AuthUser.MerchantID) } if err := db.Delete(&domain.CostComponent{}, "id = ?", id).Error; err != nil { return err } return nil } func (u *CostComponentUsecase) SortDown(id string) error { db := u.Helper.GetDB("master") if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { var olData domain.CostComponent err := db.Model(&olData).Where("id=?", id).Where("merchant_id=?", u.AuthUser.MerchantID).First(&olData).Error if err != nil { return err } if olData.ID != "" { var newData domain.CostComponent db.Model(&newData).Where("merchant_id=?", u.AuthUser.MerchantID).Where("inc?", olData.Inc).Order("inc ASC").Limit(1).First(&newData) if newData.ID != "" { err := db.Transaction(func(tx *gorm.DB) error { err := tx.Model(&olData).Where("id=?", olData.ID).UpdateColumn("inc", newData.Inc).Error if err != nil { return err } err = tx.Model(&newData).Where("id=?", newData.ID).UpdateColumn("inc", olData.Inc).Error if err != nil { return err } return nil }) return err } } } else { var olData domain.CostComponent err := db.Model(&olData).Where("id=?", id).First(&olData).Error if err != nil { return err } if olData.ID != "" { merchant_id := olData.MerchantID var newData domain.CostComponent db.Model(&newData).Where("merchant_id=?", merchant_id).Where("inc>?", olData.Inc).Order("inc ASC").Limit(1).First(&newData) if newData.ID != "" { err := db.Transaction(func(tx *gorm.DB) error { err := tx.Model(&olData).Where("id=?", olData.ID).UpdateColumn("inc", newData.Inc).Error if err != nil { return err } err = tx.Model(&newData).Where("id=?", newData.ID).UpdateColumn("inc", olData.Inc).Error if err != nil { return err } return nil }) return err } } } return nil }