package services import ( "fmt" "time" "rijig/dto" "rijig/internal/repositories" "rijig/model" "rijig/utils" ) type InitialCointService interface { CreateInitialCoint(request dto.RequestInitialCointDTO) (*dto.ReponseInitialCointDTO, error) GetAllInitialCoints() ([]dto.ReponseInitialCointDTO, error) GetInitialCointByID(id string) (*dto.ReponseInitialCointDTO, error) UpdateInitialCoint(id string, request dto.RequestInitialCointDTO) (*dto.ReponseInitialCointDTO, error) DeleteInitialCoint(id string) error } type initialCointService struct { InitialCointRepo repositories.InitialCointRepository } func NewInitialCointService(repo repositories.InitialCointRepository) InitialCointService { return &initialCointService{InitialCointRepo: repo} } func (s *initialCointService) CreateInitialCoint(request dto.RequestInitialCointDTO) (*dto.ReponseInitialCointDTO, error) { errors, valid := request.ValidateCointInput() if !valid { return nil, fmt.Errorf("validation error: %v", errors) } coint := model.InitialCoint{ CoinName: request.CoinName, ValuePerUnit: request.ValuePerUnit, } if err := s.InitialCointRepo.CreateInitialCoint(&coint); err != nil { return nil, fmt.Errorf("failed to create initial coint: %v", err) } createdAt, _ := utils.FormatDateToIndonesianFormat(coint.CreatedAt) updatedAt, _ := utils.FormatDateToIndonesianFormat(coint.UpdatedAt) responseDTO := &dto.ReponseInitialCointDTO{ ID: coint.ID, CoinName: coint.CoinName, ValuePerUnit: coint.ValuePerUnit, CreatedAt: createdAt, UpdatedAt: updatedAt, } cacheKey := fmt.Sprintf("initialcoint:%s", coint.ID) cacheData := map[string]interface{}{ "data": responseDTO, } if err := utils.SetJSONData(cacheKey, cacheData, time.Hour*24); err != nil { fmt.Printf("Error caching new initial coint: %v\n", err) } err := s.updateAllCointCache() if err != nil { return nil, fmt.Errorf("error updating all initial coint cache: %v", err) } return responseDTO, nil } func (s *initialCointService) GetAllInitialCoints() ([]dto.ReponseInitialCointDTO, error) { var cointsDTO []dto.ReponseInitialCointDTO cacheKey := "initialcoints:all" cachedData, err := utils.GetJSONData(cacheKey) if err != nil { fmt.Printf("Error fetching cache for initialcoints: %v\n", err) } if cachedData != nil { if data, ok := cachedData["data"].([]interface{}); ok { for _, item := range data { if cointData, ok := item.(map[string]interface{}); ok { if coinID, ok := cointData["coin_id"].(string); ok { if coinName, ok := cointData["coin_name"].(string); ok { if valuePerUnit, ok := cointData["value_perunit"].(float64); ok { if createdAt, ok := cointData["createdAt"].(string); ok { if updatedAt, ok := cointData["updatedAt"].(string); ok { cointsDTO = append(cointsDTO, dto.ReponseInitialCointDTO{ ID: coinID, CoinName: coinName, ValuePerUnit: valuePerUnit, CreatedAt: createdAt, UpdatedAt: updatedAt, }) } } } } } } } return cointsDTO, nil } } records, err := s.InitialCointRepo.FindAllInitialCoints() if err != nil { return nil, fmt.Errorf("failed to fetch initial coints from database: %v", err) } if len(records) == 0 { return cointsDTO, nil } for _, record := range records { createdAt, _ := utils.FormatDateToIndonesianFormat(record.CreatedAt) updatedAt, _ := utils.FormatDateToIndonesianFormat(record.UpdatedAt) cointsDTO = append(cointsDTO, dto.ReponseInitialCointDTO{ ID: record.ID, CoinName: record.CoinName, ValuePerUnit: record.ValuePerUnit, CreatedAt: createdAt, UpdatedAt: updatedAt, }) } cacheData := map[string]interface{}{ "data": cointsDTO, } if err := utils.SetJSONData(cacheKey, cacheData, time.Hour*24); err != nil { fmt.Printf("Error caching all initial coints: %v\n", err) } return cointsDTO, nil } func (s *initialCointService) GetInitialCointByID(id string) (*dto.ReponseInitialCointDTO, error) { cacheKey := fmt.Sprintf("initialcoint:%s", id) cachedData, err := utils.GetJSONData(cacheKey) if err == nil && cachedData != nil { if data, ok := cachedData["data"].(map[string]interface{}); ok { return &dto.ReponseInitialCointDTO{ ID: data["coin_id"].(string), CoinName: data["coin_name"].(string), ValuePerUnit: data["value_perunit"].(float64), CreatedAt: data["createdAt"].(string), UpdatedAt: data["updatedAt"].(string), }, nil } else { return nil, fmt.Errorf("error: cache data is not in the expected format for coin ID %s", id) } } coint, err := s.InitialCointRepo.FindInitialCointByID(id) if err != nil { return nil, fmt.Errorf("failed to fetch initial coint by ID %s: %v", id, err) } createdAt, _ := utils.FormatDateToIndonesianFormat(coint.CreatedAt) updatedAt, _ := utils.FormatDateToIndonesianFormat(coint.UpdatedAt) cointDTO := &dto.ReponseInitialCointDTO{ ID: coint.ID, CoinName: coint.CoinName, ValuePerUnit: coint.ValuePerUnit, CreatedAt: createdAt, UpdatedAt: updatedAt, } cacheData := map[string]interface{}{ "data": cointDTO, } if err := utils.SetJSONData(cacheKey, cacheData, time.Hour*24); err != nil { fmt.Printf("Error caching initial coint by ID: %v\n", err) } return cointDTO, nil } func (s *initialCointService) UpdateInitialCoint(id string, request dto.RequestInitialCointDTO) (*dto.ReponseInitialCointDTO, error) { coint, err := s.InitialCointRepo.FindInitialCointByID(id) if err != nil { return nil, fmt.Errorf("initial coint with ID %s not found", id) } coint.CoinName = request.CoinName coint.ValuePerUnit = request.ValuePerUnit if err := s.InitialCointRepo.UpdateInitialCoint(id, coint); err != nil { return nil, fmt.Errorf("failed to update initial coint: %v", err) } createdAt, _ := utils.FormatDateToIndonesianFormat(coint.CreatedAt) updatedAt, _ := utils.FormatDateToIndonesianFormat(coint.UpdatedAt) cointDTO := &dto.ReponseInitialCointDTO{ ID: coint.ID, CoinName: coint.CoinName, ValuePerUnit: coint.ValuePerUnit, CreatedAt: createdAt, UpdatedAt: updatedAt, } cacheKey := fmt.Sprintf("initialcoint:%s", id) cacheData := map[string]interface{}{ "data": cointDTO, } if err := utils.SetJSONData(cacheKey, cacheData, time.Hour*24); err != nil { fmt.Printf("Error caching updated initial coint: %v\n", err) } allCoints, err := s.InitialCointRepo.FindAllInitialCoints() if err != nil { return nil, fmt.Errorf("failed to fetch all initial coints from database: %v", err) } var cointsDTO []dto.ReponseInitialCointDTO for _, record := range allCoints { createdAt, _ := utils.FormatDateToIndonesianFormat(record.CreatedAt) updatedAt, _ := utils.FormatDateToIndonesianFormat(record.UpdatedAt) cointsDTO = append(cointsDTO, dto.ReponseInitialCointDTO{ ID: record.ID, CoinName: record.CoinName, ValuePerUnit: record.ValuePerUnit, CreatedAt: createdAt, UpdatedAt: updatedAt, }) } cacheAllKey := "initialcoints:all" cacheAllData := map[string]interface{}{ "data": cointsDTO, } if err := utils.SetJSONData(cacheAllKey, cacheAllData, time.Hour*24); err != nil { fmt.Printf("Error caching all initial coints: %v\n", err) } return cointDTO, nil } func (s *initialCointService) DeleteInitialCoint(id string) error { coint, err := s.InitialCointRepo.FindInitialCointByID(id) if err != nil { return fmt.Errorf("initial coint with ID %s not found", id) } if err := s.InitialCointRepo.DeleteInitialCoint(id); err != nil { return fmt.Errorf("failed to delete initial coint: %v", err) } cacheKey := fmt.Sprintf("initialcoint:%s", coint.ID) if err := utils.DeleteData(cacheKey); err != nil { fmt.Printf("Error deleting cache for initial coint: %v\n", err) } return s.updateAllCointCache() } func (s *initialCointService) updateAllCointCache() error { records, err := s.InitialCointRepo.FindAllInitialCoints() if err != nil { return fmt.Errorf("failed to fetch all initial coints from database: %v", err) } var cointsDTO []dto.ReponseInitialCointDTO for _, record := range records { createdAt, _ := utils.FormatDateToIndonesianFormat(record.CreatedAt) updatedAt, _ := utils.FormatDateToIndonesianFormat(record.UpdatedAt) cointsDTO = append(cointsDTO, dto.ReponseInitialCointDTO{ ID: record.ID, CoinName: record.CoinName, ValuePerUnit: record.ValuePerUnit, CreatedAt: createdAt, UpdatedAt: updatedAt, }) } cacheAllKey := "initialcoints:all" cacheAllData := map[string]interface{}{ "data": cointsDTO, } if err := utils.SetJSONData(cacheAllKey, cacheAllData, time.Hour*24); err != nil { fmt.Printf("Error caching all initial coints: %v\n", err) return err } return nil }