package data import ( "fmt" "log" "recipe-manager/helpers" "recipe-manager/models" "recipe-manager/services/logger" "time" "go.uber.org/zap" ) type RecipeWithTimeStamps struct { Recipe models.Recipe TimeStamps int64 } type Data struct { CurrentFile string CurrentCountryID string AllRecipeFiles map[string][]helpers.RecipePath currentRecipe *models.Recipe recipeMap map[string]RecipeWithTimeStamps Countries []helpers.CountryName taoLogger *logger.TaoLogger } func NewData(taoLogger *logger.TaoLogger) *Data { countries := []helpers.CountryName{{ CountryID: "tha", CountryName: "Thailand", }, { CountryID: "mys", CountryName: "Malaysia", }, { CountryID: "aus", CountryName: "Australia", }, } allRecipeFiles := helpers.ScanRecipeFiles(countries) defaultFile := "coffeethai02_600.json" defaultCountry := "tha" defaultRecipe, err := helpers.ReadRecipeFile(defaultCountry, defaultFile) if err != nil { log.Panic("Error when read default recipe file:", err) } return &Data{ CurrentFile: defaultFile, CurrentCountryID: defaultCountry, AllRecipeFiles: allRecipeFiles, currentRecipe: defaultRecipe, recipeMap: map[string]RecipeWithTimeStamps{ defaultFile: { Recipe: *defaultRecipe, TimeStamps: time.Now().Unix(), }, }, Countries: countries, taoLogger: taoLogger, } } func (d *Data) GetRecipe(countryID, filename string) *models.Recipe { if countryID == "" { return d.currentRecipe } if filename == "" || filename == d.CurrentFile { return d.currentRecipe } if recipe, ok := d.recipeMap[filename]; ok { d.CurrentFile = filename d.CurrentCountryID = countryID return &recipe.Recipe } // change current version and read new recipe d.CurrentFile = filename d.CurrentCountryID = countryID recipe, err := helpers.ReadRecipeFile(countryID, filename) if err != nil { d.taoLogger.Log.Error("Error when read recipe file, Return default recipe", zap.Error(err)) return d.currentRecipe } d.currentRecipe = recipe // save to map if len(d.recipeMap) > 5 { // limit keep in memory 5 version // remove oldest version var oldestVersion string var oldestTime int64 for k, v := range d.recipeMap { if oldestTime == 0 || v.TimeStamps < oldestTime { oldestTime = v.TimeStamps oldestVersion = k } } delete(d.recipeMap, oldestVersion) } d.recipeMap[filename] = RecipeWithTimeStamps{ Recipe: *d.currentRecipe, TimeStamps: time.Now().Unix(), } return d.currentRecipe } func (d *Data) GetRecipe01() []models.Recipe01 { return d.currentRecipe.Recipe01 } func (d *Data) GetCurrentRecipe() *models.Recipe { return d.currentRecipe } func (d *Data) GetRecipe01ByProductCode(filename, countryID, productCode string) (models.Recipe01, error) { if filename == "" || filename == d.CurrentFile { for _, v := range d.currentRecipe.Recipe01 { if v.ProductCode == productCode { return v, nil } } } else if recipe, ok := d.recipeMap[filename]; ok { for _, v := range recipe.Recipe.Recipe01 { if v.ProductCode == productCode { return v, nil } } } d.CurrentFile = filename d.CurrentCountryID = countryID recipe, err := helpers.ReadRecipeFile(countryID, filename) if err != nil { d.taoLogger.Log.Error("Error when read recipe file, Return default recipe", zap.Error(err)) for _, v := range d.currentRecipe.Recipe01 { if v.ProductCode == productCode { return v, nil } } } d.currentRecipe = recipe // save to map if len(d.recipeMap) > 5 { // limit keep in memory 5 version // remove oldest version var oldestVersion string var oldestTime int64 for k, v := range d.recipeMap { if oldestTime == 0 || v.TimeStamps < oldestTime { oldestTime = v.TimeStamps oldestVersion = k } } delete(d.recipeMap, oldestVersion) } d.recipeMap[filename] = RecipeWithTimeStamps{ Recipe: *d.currentRecipe, TimeStamps: time.Now().Unix(), } for _, v := range d.currentRecipe.Recipe01 { if v.ProductCode == productCode { return v, nil } } return models.Recipe01{}, fmt.Errorf("product code: %s not found", productCode) } func (d *Data) SetValuesToRecipe(recipe models.Recipe01) { for index, v := range d.currentRecipe.Recipe01 { if v.ProductCode == recipe.ProductCode { // Log.Debug("SetValuesToRecipe", zap.Any("old", v), zap.Any("new", recipe)) // v = recipe d.currentRecipe.Recipe01[index] = recipe break } } } func (d *Data) GetMaterialSetting(countryID, filename string) []models.MaterialSetting { result := make([]models.MaterialSetting, 0) if countryID == "" { copy(result, d.currentRecipe.MaterialSetting) return result } if filename == "" || filename == d.CurrentFile { copy(result, d.currentRecipe.MaterialSetting) return result } if recipe, ok := d.recipeMap[filename]; ok { copy(result, recipe.Recipe.MaterialSetting) d.CurrentFile = filename d.CurrentCountryID = countryID return result } d.CurrentFile = filename d.CurrentCountryID = countryID recipe, err := helpers.ReadRecipeFile(countryID, filename) if err != nil { d.taoLogger.Log.Error("Error when read recipe file, Return default recipe", zap.Error(err)) copy(result, d.currentRecipe.MaterialSetting) return result } d.currentRecipe = recipe // save to map if len(d.recipeMap) > 5 { // limit keep in memory 5 version // remove oldest version var oldestVersion string var oldestTime int64 for k, v := range d.recipeMap { if oldestTime == 0 || v.TimeStamps < oldestTime { oldestTime = v.TimeStamps oldestVersion = k } } delete(d.recipeMap, oldestVersion) } d.recipeMap[filename] = RecipeWithTimeStamps{ Recipe: *d.currentRecipe, TimeStamps: time.Now().Unix(), } copy(result, d.currentRecipe.MaterialSetting) return result } func (d *Data) GetMaterialCode(ids []uint64, countryID, filename string) []models.MaterialCode { var result []models.MaterialCode if filename == "" || filename == d.CurrentFile { result = d.currentRecipe.MaterialCode } else if recipe, ok := d.recipeMap[filename]; ok { d.CurrentFile = filename return recipe.Recipe.MaterialCode } else { d.CurrentFile = filename d.CurrentCountryID = countryID recipe, err := helpers.ReadRecipeFile(countryID, filename) if err != nil { d.taoLogger.Log.Error("Error when read recipe file, Return default recipe", zap.Error(err)) return d.currentRecipe.MaterialCode } d.currentRecipe = recipe // save to map if len(d.recipeMap) > 5 { // limit keep in memory 5 version // remove oldest version var oldestVersion string var oldestTime int64 for k, v := range d.recipeMap { if oldestTime == 0 || v.TimeStamps < oldestTime { oldestTime = v.TimeStamps oldestVersion = k } } delete(d.recipeMap, oldestVersion) } d.recipeMap[filename] = RecipeWithTimeStamps{ Recipe: *d.currentRecipe, TimeStamps: time.Now().Unix(), } result = d.currentRecipe.MaterialCode } if len(ids) == 0 { return result } resultFilter := make([]models.MaterialCode, len(ids)) for _, id := range ids { if id == 0 { continue } for _, m := range result { if m.MaterialID == id { resultFilter = append(resultFilter, m) break } } } return resultFilter } func (d *Data) GetCountryNameByID(countryID string) (string, error) { for _, country := range d.Countries { if country.CountryID == countryID { return country.CountryName, nil } } return "", fmt.Errorf("country ID: %s not found", countryID) } func (d *Data) GetCountryIDByName(countryName string) (string, error) { for _, country := range d.Countries { if country.CountryName == countryName { return country.CountryID, nil } } return "", fmt.Errorf("country name: %s not found", countryName) }